diff --git a/.github/ISSUE_TEMPLATE/issue-template.md b/.github/ISSUE_TEMPLATE/issue-template.md new file mode 100644 index 00000000000..dd4f1455032 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue-template.md @@ -0,0 +1,18 @@ +--- +name: Issue +about: Reporting bugs and problems in Eclipse Jetty +title: '' +assignees: '' + +--- + +**Jetty version** + +**Java version** + +**OS type/version** + +**Description** + + + diff --git a/.github/ISSUE_TEMPLATE/question-template.md b/.github/ISSUE_TEMPLATE/question-template.md new file mode 100644 index 00000000000..d9cb028ca8b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question-template.md @@ -0,0 +1,16 @@ +--- +name: Question +about: Asking questions about Eclipse Jetty +title: '' +labels: Question +assignees: '' + +--- + +**Jetty version** + +**Java version** + +**Question** + + diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..8abd90936b2 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,20 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 365 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 30 +# Issues with these labels will never be considered stale +exemptLabels: + - Pinned + - Security + - Specification + - TCK +# Label to use when marking an issue as stale +staleLabel: Stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has been a + full year without activity. It will be closed if no further activity occurs. + Thank you for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: > + This issue has been closed due to it having no activity. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9391cc18ab2..ef6433b76c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,10 +53,10 @@ Be sure to search for existing bugs before you create another one. Remember that Reporting Security Issues ----------------- -There are a number of avenues for reporting security issues to the Jetty project available. -If the issue is directly related to Jetty itself then reporting to the Jetty developers is encouraged. -The most direct method is to mail [security@webtide.com](mailto:security@webtide.com). -Webtide is comprised of the active committers of the Jetty project is our preferred reporting method. +There are a number of avenues for reporting security issues to the Jetty project available. +If the issue is directly related to Jetty itself then reporting to the Jetty developers is encouraged. +The most direct method is to mail [security@webtide.com](mailto:security@webtide.com). +Webtide is comprised of the active committers of the Jetty project is our preferred reporting method. We are flexible in how we work with reporters of security issues but we reserve the right to act in the interests of the Jetty project in all circumstances. If the issue is related to Eclipse or its Jetty integration then we encourage you to reach out to [security@eclipse.org](mailto:security@eclipse.org). diff --git a/Jenkinsfile b/Jenkinsfile index 0d9b2c54a3d..4477293c51e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,65 +11,53 @@ pipeline { agent { node { label 'linux' } } options { timeout(time: 120, unit: 'MINUTES') } steps { - mavenBuild("jdk11", "-Pmongodb install", "maven3", true) // -Pautobahn + mavenBuild("jdk11", "-T3 -Pmongodb clean install", "maven3", true) // -Pautobahn // Collect up the jacoco execution results (only on main build) jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class', - exclusionPattern: '' + - // build tools - '**/org/eclipse/jetty/ant/**' + - ',**/org/eclipse/jetty/maven/**' + - ',**/org/eclipse/jetty/jspc/**' + - // example code / documentation - ',**/org/eclipse/jetty/embedded/**' + - ',**/org/eclipse/jetty/asyncrest/**' + - ',**/org/eclipse/jetty/demo/**' + - // special environments / late integrations - ',**/org/eclipse/jetty/gcloud/**' + - ',**/org/eclipse/jetty/infinispan/**' + - ',**/org/eclipse/jetty/osgi/**' + - ',**/org/eclipse/jetty/spring/**' + - ',**/org/eclipse/jetty/http/spi/**' + - // test classes - ',**/org/eclipse/jetty/tests/**' + - ',**/org/eclipse/jetty/test/**', - execPattern: '**/target/jacoco.exec', - classPattern: '**/target/classes', - sourcePattern: '**/src/main/java' + exclusionPattern: '' + + // build tools + '**/org/eclipse/jetty/ant/**' + + ',**/org/eclipse/jetty/maven/**' + + ',**/org/eclipse/jetty/jspc/**' + + // example code / documentation + ',**/org/eclipse/jetty/embedded/**' + + ',**/org/eclipse/jetty/asyncrest/**' + + ',**/org/eclipse/jetty/demo/**' + + // special environments / late integrations + ',**/org/eclipse/jetty/gcloud/**' + + ',**/org/eclipse/jetty/infinispan/**' + + ',**/org/eclipse/jetty/osgi/**' + + ',**/org/eclipse/jetty/spring/**' + + ',**/org/eclipse/jetty/http/spi/**' + + // test classes + ',**/org/eclipse/jetty/tests/**' + + ',**/org/eclipse/jetty/test/**', + execPattern: '**/target/jacoco.exec', + classPattern: '**/target/classes', + sourcePattern: '**/src/main/java' warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']] junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml,**/target/autobahntestsuite-reports/*.xml' } } - - stage("Build / Test - JDK12") { + + stage("Build / Test - JDK13") { agent { node { label 'linux' } } - options { timeout(time: 120, unit: 'MINUTES') } steps { - mavenBuild("jdk12", "-Pmongodb install", "maven3", true) - warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']] - junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml' + timeout(time: 120, unit: 'MINUTES') { + mavenBuild("jdk13", "-T3 -Pmongodb clean install", "maven3", true) + warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']] + junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml' + } } } stage("Build Javadoc") { agent { node { label 'linux' } } - options { timeout(time: 30, unit: 'MINUTES') } steps { - mavenBuild("jdk11", "install javadoc:javadoc -DskipTests", "maven3", true) - warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'JavaDoc'], [parserName: 'Java']] - } - } - - stage("Checkstyle ") { - agent { node { label 'linux' } } - options { timeout(time: 30, unit: 'MINUTES') } - steps { - mavenBuild("jdk11", "install -DskipTests", "maven3", true) - mavenBuild("jdk11", "install -f build-resources", "maven3", true) - mavenBuild("jdk11", "install checkstyle:check -DskipTests", "maven3", true) - recordIssues( - enabledForFailure: true, aggregatingResults: true, - tools: [java(), checkStyle(pattern: '**/target/checkstyle-result.xml', reportEncoding: 'UTF-8')] - ) + timeout(time: 30, unit: 'MINUTES') { + mavenBuild("jdk11", "package source:jar javadoc:jar javadoc:aggregate-jar -Peclipse-release -DskipTests -Dpmd.skip=true -Dcheckstyle.skip=true", "maven3", true) + warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'JavaDoc'], [parserName: 'Java']] + } } } } @@ -88,28 +76,24 @@ pipeline { } } - def slackNotif() { - script { - try - { - if ( env.BRANCH_NAME == 'jetty-10.0.x' || env.BRANCH_NAME == 'jetty-9.4.x' ) - { - //BUILD_USER = currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId() - // by ${BUILD_USER} - COLOR_MAP = ['SUCCESS': 'good', 'FAILURE': 'danger', 'UNSTABLE': 'danger', 'ABORTED': 'danger'] - slackSend channel: '#jenkins', - color: COLOR_MAP[currentBuild.currentResult], - message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} build ${env.BUILD_NUMBER} - ${env.BUILD_URL}" - } - } catch (Exception e) { - e.printStackTrace() - echo "skip failure slack notification: " + e.getMessage() + script { + try { + if (env.BRANCH_NAME == 'jetty-10.0.x' || env.BRANCH_NAME == 'jetty-9.4.x') { + //BUILD_USER = currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId() + // by ${BUILD_USER} + COLOR_MAP = ['SUCCESS': 'good', 'FAILURE': 'danger', 'UNSTABLE': 'danger', 'ABORTED': 'danger'] + slackSend channel: '#jenkins', + color: COLOR_MAP[currentBuild.currentResult], + message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} build ${env.BUILD_NUMBER} - ${env.BUILD_URL}" } + } catch (Exception e) { + e.printStackTrace() + echo "skip failure slack notification: " + e.getMessage() } + } } - /** * To other developers, if you are using this method above, please use the following syntax. * @@ -125,15 +109,16 @@ def mavenBuild(jdk, cmdline, mvnName, junitPublishDisabled) { def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true' withMaven( - maven: mvnName, - jdk: "$jdk", - publisherStrategy: 'EXPLICIT', - options: [junitPublisher(disabled: junitPublishDisabled),mavenLinkerPublisher(disabled: false),pipelineGraphPublisher(disabled: false)], - mavenOpts: mavenOpts, - mavenLocalRepo: localRepo) { + maven: mvnName, + jdk: "$jdk", + publisherStrategy: 'EXPLICIT', + options: [junitPublisher(disabled: junitPublishDisabled), mavenLinkerPublisher(disabled: false), pipelineGraphPublisher(disabled: false)], + mavenOpts: mavenOpts, + mavenLocalRepo: localRepo) { // Some common Maven command line + provided command line - sh "mvn -Pci -V -B -T3 -e -fae -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + env.JENKINS_HOME + sh "mvn -Pci -V -B -e -fae -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + env.JENKINS_HOME } } + // vim: et:ts=2:sw=2:ft=groovy diff --git a/KEYS.txt b/KEYS.txt index acf04a8cc33..73b9fb49a4e 100644 --- a/KEYS.txt +++ b/KEYS.txt @@ -2,6 +2,6 @@ Jan Bartel AED5 EE6C 45D0 FE8D 5D1B 164F 27DE D4BF 6216 DB8F Jesse McConnell 2A68 4B57 436A 81FA 8706 B53C 61C3 351A 438A 3B7D Joakim Erdfelt 5989 BAF7 6217 B843 D66B E55B 2D0E 1FB8 FE4B 68B4 -Joakim Erdfelt B59B 67FD 7904 9843 67F9 3180 0818 D9D6 8FB6 7BAC +Joakim Erdfelt B59B 67FD 7904 9843 67F9 3180 0818 D9D6 8FB6 7BAC Joakim Erdfelt BFBB 21C2 46D7 7768 3628 7A48 A04E 0C74 ABB3 5FEA Simone Bordet 8B09 6546 B1A8 F026 56B1 5D3B 1677 D141 BCF3 584D diff --git a/LICENSE b/LICENSE index 6acfaf43962..c2d40c35af1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,215 +1,290 @@ -This program and the accompanying materials are made available under the -terms of the Eclipse Public License 1.0 which is available at -https://www.eclipse.org/org/documents/epl-1.0/EPL-1.0.txt -or the Apache Software License 2.0 which is available at +This program and the accompanying materials are made available under +the terms of the Eclipse Public License 2.0 which is available at +https://www.eclipse.org/legal/epl-2.0 +This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set +forth in the Eclipse Public License, v. 2.0 are satisfied: +the Apache License v2.0 which is available at https://www.apache.org/licenses/LICENSE-2.0 +Eclipse Public License - v 2.0 -Eclipse Public License - v 1.0 - -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC -LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM -CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: -a) in the case of the initial Contributor, the initial code and documentation - distributed under this Agreement, and -b) in the case of each subsequent Contributor: - i) changes to the Program, and - ii) additions to the Program; + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and - where such changes and/or additions to the Program originate from and are - distributed by that particular Contributor. A Contribution 'originates' - from a Contributor if it was added to the Program by such Contributor - itself or anyone acting on such Contributor's behalf. Contributions do not - include additions to the Program which: (i) are separate modules of - software distributed in conjunction with the Program under their own - license agreement, and (ii) are not derivative works of the Program. + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. -"Contributor" means any person or entity that distributes the Program. +"Contributor" means any person or entity that Distributes the Program. -"Licensed Patents" mean patent claims licensable by a Contributor which are -necessarily infringed by the use or sale of its Contribution alone or when -combined with the Program. +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. -"Program" means the Contributions distributed in accordance with this +"Program" means the Contributions Distributed in accordance with this Agreement. -"Recipient" means anyone who receives the Program under this Agreement, -including all Contributors. +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. 2. GRANT OF RIGHTS - a) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free copyright license to - reproduce, prepare derivative works of, publicly display, publicly - perform, distribute and sublicense the Contribution of such Contributor, - if any, and such derivative works, in source code and object code form. - b) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free patent license under - Licensed Patents to make, use, sell, offer to sell, import and otherwise - transfer the Contribution of such Contributor, if any, in source code and - object code form. This patent license shall apply to the combination of - the Contribution and the Program if, at the time the Contribution is - added by the Contributor, such addition of the Contribution causes such - combination to be covered by the Licensed Patents. The patent license - shall not apply to any other combinations which include the Contribution. - No hardware per se is licensed hereunder. - c) Recipient understands that although each Contributor grants the licenses - to its Contributions set forth herein, no assurances are provided by any - Contributor that the Program does not infringe the patent or other - intellectual property rights of any other entity. Each Contributor - disclaims any liability to Recipient for claims brought by any other - entity based on infringement of intellectual property rights or - otherwise. As a condition to exercising the rights and licenses granted - hereunder, each Recipient hereby assumes sole responsibility to secure - any other intellectual property rights needed, if any. For example, if a - third party patent license is required to allow Recipient to distribute - the Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - d) Each Contributor represents that to its knowledge it has sufficient - copyright rights in its Contribution, if any, to grant the copyright - license set forth in this Agreement. + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). 3. REQUIREMENTS -A Contributor may choose to distribute the Program in object code form under -its own license agreement, provided that: +3.1 If a Contributor Distributes the Program in any form, then: - a) it complies with the terms and conditions of this Agreement; and - b) its license agreement: - i) effectively disclaims on behalf of all Contributors all warranties - and conditions, express and implied, including warranties or - conditions of title and non-infringement, and implied warranties or - conditions of merchantability and fitness for a particular purpose; - ii) effectively excludes on behalf of all Contributors all liability for - damages, including direct, indirect, special, incidental and - consequential damages, such as lost profits; - iii) states that any provisions which differ from this Agreement are - offered by that Contributor alone and not by any other party; and - iv) states that source code for the Program is available from such - Contributor, and informs licensees how to obtain it in a reasonable - manner on or through a medium customarily used for software exchange. + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and -When the Program is made available in source code form: + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; - a) it must be made available under this Agreement; and - b) a copy of this Agreement must be included with each copy of the Program. - Contributors may not remove or alter any copyright notices contained - within the Program. + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; -Each Contributor must identify itself as the originator of its Contribution, -if -any, in a manner that reasonably allows subsequent Recipients to identify the -originator of the Contribution. + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. 4. COMMERCIAL DISTRIBUTION -Commercial distributors of software may accept certain responsibilities with -respect to end users, business partners and the like. While this license is -intended to facilitate the commercial use of the Program, the Contributor who -includes the Program in a commercial product offering should do so in a manner -which does not create potential liability for other Contributors. Therefore, -if a Contributor includes the Program in a commercial product offering, such -Contributor ("Commercial Contributor") hereby agrees to defend and indemnify -every other Contributor ("Indemnified Contributor") against any losses, -damages and costs (collectively "Losses") arising from claims, lawsuits and -other legal actions brought by a third party against the Indemnified -Contributor to the extent caused by the acts or omissions of such Commercial -Contributor in connection with its distribution of the Program in a commercial -product offering. The obligations in this section do not apply to any claims -or Losses relating to any actual or alleged intellectual property -infringement. In order to qualify, an Indemnified Contributor must: -a) promptly notify the Commercial Contributor in writing of such claim, and -b) allow the Commercial Contributor to control, and cooperate with the -Commercial Contributor in, the defense and any related settlement -negotiations. The Indemnified Contributor may participate in any such claim at -its own expense. +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. -For example, a Contributor might include the Program in a commercial product -offering, Product X. That Contributor is then a Commercial Contributor. If -that Commercial Contributor then makes performance claims, or offers -warranties related to Product X, those performance claims and warranties are -such Commercial Contributor's responsibility alone. Under this section, the -Commercial Contributor would have to defend claims against the other -Contributors related to those performance claims and warranties, and if a -court requires any other Contributor to pay any damages as a result, the -Commercial Contributor must pay those damages. +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. 5. NO WARRANTY -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, -NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each -Recipient is solely responsible for determining the appropriateness of using -and distributing the Program and assumes all risks associated with its -exercise of rights under this Agreement , including but not limited to the -risks and costs of program errors, compliance with applicable laws, damage to -or loss of data, programs or equipment, and unavailability or interruption of -operations. +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY -CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION -LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE -EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGES. +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of the -remainder of the terms of this Agreement, and without further action by the -parties hereto, such provision shall be reformed to the minimum extent -necessary to make such provision valid and enforceable. +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. -If Recipient institutes patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Program itself -(excluding combinations of the Program with other software or hardware) -infringes such Recipient's patent(s), then such Recipient's rights granted -under Section 2(b) shall terminate as of the date such litigation is filed. +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. -All Recipient's rights under this Agreement shall terminate if it fails to -comply with any of the material terms or conditions of this Agreement and does -not cure such failure in a reasonable period of time after becoming aware of -such noncompliance. If all Recipient's rights under this Agreement terminate, -Recipient agrees to cease use and distribution of the Program as soon as -reasonably practicable. However, Recipient's obligations under this Agreement -and any licenses granted by Recipient relating to the Program shall continue -and survive. +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. -Everyone is permitted to copy and distribute copies of this Agreement, but in -order to avoid inconsistency the Agreement is copyrighted and may only be -modified in the following manner. The Agreement Steward reserves the right to -publish new versions (including revisions) of this Agreement from time to -time. No one other than the Agreement Steward has the right to modify this -Agreement. The Eclipse Foundation is the initial Agreement Steward. The -Eclipse Foundation may assign the responsibility to serve as the Agreement -Steward to a suitable separate entity. Each new version of the Agreement will -be given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the -Agreement under which it was received. In addition, after a new version of the -Agreement is published, Contributor may elect to distribute the Program -(including its Contributions) under the new version. Except as expressly -stated in Sections 2(a) and 2(b) above, Recipient receives no rights or -licenses to the intellectual property of any Contributor under this Agreement, -whether expressly, by implication, estoppel or otherwise. All rights in the -Program not expressly granted under this Agreement are reserved. +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. -This Agreement is governed by the laws of the State of New York and the -intellectual property laws of the United States of America. No party to this -Agreement will bring a legal action under this Agreement more than one year -after the cause of action arose. Each party waives its rights to a jury trial in -any resulting litigation. +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. Apache License @@ -413,3 +488,7 @@ any resulting litigation. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + +SPDX-License-Identifier: EPL-2.0 +SPDX-License-Identifier: Apache-2.0 diff --git a/NOTICE.txt b/NOTICE.txt index 219db707b5f..0d3e49d75d4 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,41 +1,42 @@ -============================================================== - Jetty Web Container - Copyright 1995-2019 Mort Bay Consulting Pty Ltd. -============================================================== +Notices for Eclipse Jetty +========================= +This content is produced and maintained by the Eclipse Jetty project. -The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd -unless otherwise noted. +Project home: https://www.eclipse.org/jetty/ -Jetty is dual licensed under both +Trademarks +---------- +Eclipse Jetty, and Jetty are trademarks of the Eclipse Foundation. - * The Apache 2.0 License - http://www.apache.org/licenses/LICENSE-2.0.html +Copyright +--------- +All contributions are the property of the respective authors or of +entities to which copyright has been assigned by the authors (eg. employer). - and +Declared Project Licenses +------------------------- +This artifacts of this project are made available under the terms of: - * The Eclipse Public 1.0 License - http://www.eclipse.org/legal/epl-v10.html + * the Eclipse Public License v2.0 + https://www.eclipse.org/legal/epl-2.0 + SPDX-License-Identifier: EPL-2.0 -Jetty may be distributed under either license. + or ------- -Eclipse + * the Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + SPDX-License-Identifier: Apache-2.0 -The following artifacts are EPL. +The following dependencies are EPL. * org.eclipse.jetty.orbit:org.eclipse.jdt.core -The following artifacts are EPL and ASL2. +The following dependencies are EPL and ASL2. * org.eclipse.jetty.orbit:javax.security.auth.message - -The following artifacts are EPL and CDDL 1.0. +The following dependencies are EPL and CDDL 1.0. * org.eclipse.jetty.orbit:javax.mail.glassfish - ------- -Oracle - -The following artifacts are CDDL + GPLv2 with classpath exception. +The following dependencies are CDDL + GPLv2 with classpath exception. https://glassfish.dev.java.net/nonav/public/CDDL+GPL.html * javax.servlet:javax.servlet-api @@ -43,72 +44,46 @@ https://glassfish.dev.java.net/nonav/public/CDDL+GPL.html * javax.transaction:javax.transaction-api * javax.websocket:javax.websocket-api ------- -Oracle OpenJDK - -If ALPN is used to negotiate HTTP/2 connections, then the following -artifacts may be included in the distribution or downloaded when ALPN -module is selected. - - * java.sun.security.ssl - -These artifacts replace/modify OpenJDK classes. The modififications -are hosted at github and both modified and original are under GPL v2 with -classpath exceptions. -http://openjdk.java.net/legal/gplv2+ce.html - - ------- -OW2 - -The following artifacts are licensed by the OW2 Foundation according to the +The following dependencies are licensed by the OW2 Foundation according to the terms of http://asm.ow2.org/license.html -org.ow2.asm:asm-commons -org.ow2.asm:asm + * org.ow2.asm:asm-commons + * org.ow2.asm:asm +The following dependencies are ASL2 licensed. ------- -Apache + * org.apache.taglibs:taglibs-standard-spec + * org.apache.taglibs:taglibs-standard-impl -The following artifacts are ASL2 licensed. - -org.apache.taglibs:taglibs-standard-spec -org.apache.taglibs:taglibs-standard-impl - - ------- -MortBay - -The following artifacts are ASL2 licensed. Based on selected classes from +The following dependencies are ASL2 licensed. Based on selected classes from following Apache Tomcat jars, all ASL2 licensed. -org.mortbay.jasper:apache-jsp - org.apache.tomcat:tomcat-jasper - org.apache.tomcat:tomcat-juli - org.apache.tomcat:tomcat-jsp-api - org.apache.tomcat:tomcat-el-api - org.apache.tomcat:tomcat-jasper-el - org.apache.tomcat:tomcat-api - org.apache.tomcat:tomcat-util-scan - org.apache.tomcat:tomcat-util - -org.mortbay.jasper:apache-el - org.apache.tomcat:tomcat-jasper-el - org.apache.tomcat:tomcat-el-api - - ------- -Mortbay + * org.mortbay.jasper:apache-jsp + * org.apache.tomcat:tomcat-jasper + * org.apache.tomcat:tomcat-juli + * org.apache.tomcat:tomcat-jsp-api + * org.apache.tomcat:tomcat-el-api + * org.apache.tomcat:tomcat-jasper-el + * org.apache.tomcat:tomcat-api + * org.apache.tomcat:tomcat-util-scan + * org.apache.tomcat:tomcat-util + * org.mortbay.jasper:apache-el + * org.apache.tomcat:tomcat-jasper-el + * org.apache.tomcat:tomcat-el-api The following artifacts are CDDL + GPLv2 with classpath exception. - https://glassfish.dev.java.net/nonav/public/CDDL+GPL.html -org.eclipse.jetty.toolchain:jetty-servlet-api + * org.eclipse.jetty.toolchain:jetty-schemas ------- -Assorted +Cryptography +------------ +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted. The UnixCrypt.java code implements the one way cryptography used by Unix systems for simple password protection. Copyright 1996 Aki Yoshida, diff --git a/README.md b/README.md index 2793de75d63..969435deb35 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Documentation Project documentation is available on the Jetty Eclipse website. -- [http://www.eclipse.org/jetty/documentation](http://www.eclipse.org/jetty/documentation) +- [https://www.eclipse.org/jetty/documentation](https://www.eclipse.org/jetty/documentation) Building ======== @@ -40,9 +40,9 @@ The first build may take a longer than expected as Maven downloads all the depen The build tests do a lot of stress testing, and on some machines it is necessary to set the file descriptor limit to greater than 2048 for the tests to all pass successfully. -It is possible to bypass tests by building with `mvn -Dmaven.test.skip=true install` but note that this will not produce some of the test jars that are leveraged in other places in the build. +It is possible to bypass tests by building with `mvn clean install -DskipTests`. Professional Services --------------------- -Expert advice and production support are available through [Webtide.com](http://webtide.com). +Expert advice and production support are available through [Webtide.com](https://webtide.com). diff --git a/VERSION.txt b/VERSION.txt index 8f50d35d1be..3779571a9a4 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,5 +1,168 @@ jetty-10.0.0-SNAPSHOT +jetty-10.0.0.alpha1 - 26 November 2019 + + 97 Permanent UnavailableException thrown during servlet request handling + should cause servlet destroy + + 137 Support OAuth + + 155 No way to set keystore for JSR 356 websocket clients, needed for SSL + client authentication + + 250 Implement HTTP CONNECT for HTTP/2 + + 995 UrlEncoded.encodeString should skip more characters + + 1036 Allow easy configuration of Scheduler-Threads and name them more + appropriate + + 1485 Add systemd service file + + 1743 Refactor jetty maven plugin goals to be more orthogonal + + 2266 Jetty maven plugin reload is triggered each time the + `scanIntervalSeconds` pass + + 2340 Remove raw ServletHandler usage examples from documentation + + 2429 Review HttpClient backpressure semantic + + 2578 Use addEventListener(EventListener listener) + + 2709 current default for headerCacheSize is not large enough for many + requests + + 2815 hpack fields are opaque octets + + 3040 Allow RFC6265 Cookies to include optional SameSite attribute. + + 3083 The ini-template for jetty.console-capture.dir does not match the + default value + + 3106 Websocket connection stats and request stats + + 3558 Error notifications can be received after a successful websocket close + + 3601 HTTP2 stall on reset streams + + 3705 Review ClientUpgradeRequest exception handling + + 3734 websocket suspend when input closed + + 3747 Make Jetty Demo work with JPMS + + 3787 Jetty client sometimes returns EOFException instead of + SSLHandshakeException on certificate errors. + + 3804 Weld/CDI XML backwards compat? + + 3806 Error Page handling Async race with ProxyServlet + + 3822 trustAll will not work on some servers + + 3829 Avoid sending empty trailer frames for http/2 responses + + 3840 Byte-range request performance problems with large files + + 3856 Different behaviour with maxFormContentSize=0 if Content-Length header + is present/missing + + 3863 Enforce use of SNI + + 3869 Update to ASM 7.2 for jdk 13 + + 3872 Review exposure of JavaxWebSocketServletContainerInitializer + + 3876 WebSocketPartialListener is only called for initial frames, not for + continuation frames + + 3884 @WebSocket without @OnWebSocketMessage handler fails when receiving a + continuation frame + + 3888 BufferUtil.toBuffer(Resource resource,boolean direct) does not like + large (4G+) Resources + + 3906 Fix for #3840 breaks Path encapsulation in PathResource + + 3913 Clustered HttpSession IllegalStateException: Invalid for read + + 3929 Deadlock between new HTTP2Connection() and Server.stop() + + 3936 Race condition when modifying session + sendRedirect() + + 3940 Double initialization of Log + + 3951 Consider adding demand API to HTTP/2 + + 3952 Server configuration for direct/heap ByteBuffers + + 3956 Remove and warn on use of illegal HTTP/2 response headers + + 3957 CustomRequestLog bad usage of MethodHandles.lookup() + + 3960 Fix HttpConfiguration copy constructor + + 3964 Improve efficiency of listeners + + 3968 WebSocket sporadic ReadPendingException using suspend/resume + + 3969 X-Forwarded-Port header customization isn't possible + + 3978 HTTP/2 fixes for robustly handling abnormal traffic and resource + exhaustion + + 3983 JarFileResource incorrectly lists the contents of directories with + spaces + + 3985 Improve lenient Cookie parsing + + 3989 Inform custom ManagedSelector of dead selector via optional + onFailedSelect() + + 4000 Add SameFileAliasChecker to help with FileSystem static file access + normalization on Mac and Windows + + 4003 Quickstart broken in jetty-10 + + 4007 Getting NullPointerException while trying to run jetty start.run on + Windows + + 4009 ServletContextHandler setSecurityHandler broke handler chain + + 4020 Revert WebSocket ExtensionFactory change to interface + + 4022 Servlet which is added by ServletRegistration can't be started + + 4025 Provide more write-through behaviours for DefaultSessionCache + + 4027 Ensure AbstractSessionDataStore cannot be used unless it is started + + 4033 Ignore bad percent encodings in paths during + URIUtil.equalsIgnoreEncodings() + + 4047 Gracefully stopped Jetty not flushing all response data + + 4048 Multiple values in X-Forwarded-Port throw NumberFormatException + + 4057 NullPointerException in o.e.j.h.HttpFields + + 4058 Review Locker + + 4064 java.lang.NullPointerException initializing embedded servlet + + 4075 Do not fail on servlet-mapping with url-pattern /On* + + 4076 Restarting quickstarted webapp throws IllegalStateException: + ServletContainerInitializersStarter already exists + + 4082 Debug logging causes NullPointerException in client + + 4084 Use of HttpConfiguration.setBlockingTimeout(long) in jetty.xml produces + warning on jetty-home startup + + 4096 Thread in ReservedThreadExecutor does not exit when stopped + + 4104 Frames are sent through ExtensionStack even if WebSocket Session is + closed + + 4105 QueuedThreadPool increased thread usage and no idle thread decay + + 4113 HttpClient fails with JDK 13 and TLS 1.3 + + 4115 Drop HTTP/2 pseudo headers + + 4121 QueuedThreadPool should support ThreadFactory behaviors + + 4122 QueuedThreadPool should reset thread interrupted on failed run + + 4124 Run websocket autobahn tests with jetty and javax apis instead of just + with core. + + 4128 OpenIdCredentials can't decode JWT ID token + + 4132 Should be possible to use OIDC without metadata + + 4138 OpenID module should use HttpClient instead of HttpURLConnection + + 4141 ClassCastException with non-async Servlet + async Filter + + HttpServletRequestWrapper + + 4142 Configurable HTTP/2 RateControl + + 4144 Naked cast to Request should be avoided + + 4150 Module org.eclipse.jetty.alpn.client not found, required by + org.eclipse.jetty.proxy + + 4152 WebSocket autoFragment does not fragment based on maxFrameSize + + 4156 IllegalStateException when forwarding to jsp with new session + + 4161 Regression: EofException: request lifecycle violation + + 4170 Client-side alias selection based on SSLEngine + + 4173 NullPointerException warning in log from WebInfConfiguration after + upgrade + + 4174 ConcurrentModificationException when stopping jetty:run-war + + 4176 Should not set header if sendError has been called + + 4177 Configure HTTP proxy with SslContextFactory + + 4179 Improve HttpChannel$SendCallback references for GC + + 4183 Jetty considers bootstrap injected class to be a "server class" + + 4188 Spin in HttpOutput.close + + 4190 Jetty hangs after thread blocked in SharedBlockingCallback.block() + called by HttpOutput.close + + 4191 Increase GzipHandler minGzipSize default value + + 4193 InetAccessHandler - new includeConnectors/excludeConnectors not quite + correct anymore + + 4201 Throw SSLHandshakeException in case of TLS handshake failures + + 4203 Some Transfer-Encoding and Content-Length combinations do not result in + expected 400 Bad Request + + 4204 Transfer-Encoding behavior does not follow RFC7230 + + 4208 304 response with Content-Length fails, not conform to RFC7230 + + 4209 Unused TLS connection is not closed in Java 11 + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + + 4222 Major/Minor Version wrong (jetty 10 is servlet 4) + + 4227 First authorization request produced by OIDC module fails due to + inclusion of sessionid + + 4236 clean up redirect code calculation for OpenIdAuthenticator + + 4237 simplify openid module configuration + + 4240 CGI form post results in 500 response if no character encoding + + 4243 ErrorHandler produces invalid json error response + + 4247 Cookie security attributes are going to mandated by Google Chrome + + 4248 Websocket client UpgradeListener never reports success + + 4251 Http 2.0 clients cannot upgrade protocol + + 4258 RateControl should be per-connection + + 4264 Spring Boot BasicErrorController no longer invoked + + 4265 HttpChannel SEND_ERROR should use ErrorHandler.doError() + + 4277 Reading streamed gzipped body never terminates + + 4279 Regression: ResponseWriter#close blocks indefinitely + + 4282 Review HttpParser handling in case of no content + + 4283 Wrong package for OpenJDK8ClientALPNProcessor + + 4284 Possible NullPointerException in Main.java when stopped from command + line + + 4287 Move getUriLastPathSegment(URI uri) to URIUtil + + 4296 Unable to create WebSocket connect if the query string of the URL has % + symbol. + + 4301 Demand beforeContent is not forwarded + + 4305 Jetty server ALPN shall alert fatal no_application_protocol if no + client application protocol is supported + + 4325 Deprecate SniX509ExtendedKeyManager constructor without + SslContextFactory$Server + + 4334 Better test ErrorHandler changes + + 4342 OpenID module cannot create HttpClient in Jetty 10 + jetty-10.0.0-alpha0 - 11 July 2019 + 113 Add support for NCSA Extended Log File Format + 114 Bring back overlay deployer @@ -7,7 +170,7 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 207 Support javax.websocket version 1.1 + 215 Add Conscrypt for native ALPN/TLS/SSL + 300 Implement Deflater / Inflater Object Pool - + 482 [jetty-osgi] The CCL while parsing the xml files should be set to a + + 482 jetty-osgi] The CCL while parsing the xml files should be set to a combination of Jetty and Bundle-Classloader + 592 Support no-value Host header in HttpParser + 632 JMX tests rely on fixed port @@ -77,8 +240,9 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 2061 WebSocket hangs in blockingWrite + 2075 Deprecating MultiException + 2095 Remove FastCGI multiplexing - + 2103 Server should open connectors early in start sequence + + 2103 Server should open connectors early in start sequence + 2108 Update licence headers and plugin for 2018 + + 2140 Infinispan and hazelcast changes to scavenge zombie expired sessions + 2172 Support javax.websocket 1.1 + 2175 Refactor WebSocket close handling + 2191 JPMS Support @@ -91,13 +255,12 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 2978 Add module-info.java to relevant Jetty modules + 2983 Jetty 10 Configuration abstraction + 2985 Jetty 10 Configuration replacement algorithm incorrect - + 2996 ContextHandler.setDefaultContextPath() not implemented for quickstart. + + 2996 ContextHandler.setDefaultContextPath() not implemented for quickstart + 3009 Update Jetty 10 to use non-LEGACY Compliance Modes + 3010 Move old MultiPart parsing implementation to jetty-http + 3011 Move HttpCompliance to HttpConfiguration + 3012 Refactor HttpCompliance and HttpComplianceSection to be friendlier to customization - + 3106 Websocket connection stats and request stats + 3129 javax-websocket-common pom.xml is wrong + 3139 NPE on WebSocketServerContainerInitializer.configureContext(ServletContextHandler) @@ -114,7 +277,7 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 3197 Use jetty specific websocket API jar + 3213 MetaInfConfigurationTest tests disabled in jetty-10.0.x + 3216 Autobahn WebSocketServer failures in jetty 10 - + 3225 Response.sendError should not set reason. + + 3225 Response.sendError should not set reason + 3246 javax-websocket-tests exception stacktraces + 3249 Update to apache jasper 9.0.14 for jetty-10 + 3274 OSGi versions of java.base classes in @@ -122,7 +285,7 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 3279 WebSocket write may hang forever + 3288 Correct websocket artifactIds on jetty-10.0.x + 3290 async websocket onOpen, onError and onClose in 10.0.x - + 3298 Review jetty-10 websocket CompletableFuture usage. + + 3298 Review jetty-10 websocket CompletableFuture usage + 3303 Update to jakarta ee javax artifacts for jetty-10 + 3308 Remove deprecated methods from sessions + 3320 Review Jetty 10 module-info.java @@ -156,7 +319,7 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 3648 javax.websocket client container incorrectly creates Server SslContextFactory + 3661 JettyWebSocketServerContainer exposes websocket common classes - + 3666 WebSocket - Handling sent 1009 close frame. + + 3666 WebSocket - Handling sent 1009 close frame + 3696 Unwrap JavaxWebSocketClientContainer.connectToServer() exceptions + 3698 Missing WebSocket ServerContainer after server restart + 3700 stackoverflow in WebAppClassLoaderUrlStreamTest @@ -191,8 +354,256 @@ jetty-10.0.0-alpha0 - 11 July 2019 + 3840 Byte-range request performance problems with large files + 3849 ClosedChannelException from jetty-test-webapp javax websocket chat example - + 467246 null - + jetty-10 null + +jetty-9.4.27.v20200227 - 27 February 2020 + + 3247 Generate jetty-maven-plugin website + + 4247 Cookie security attributes are going to mandated by Google Chrome + + 4360 Upgrade to Apache Jasper 8.5.49 + + 4475 WebSocket JSR356 implementation not honoring javadoc of MessageHandler + on Whole + + 4495 Review ReservedThreadExecutor's concurrency model + + 4504 X-Forwarded-Server header overwrites X-Forwarded-Host + + 4520 Jetty jdbc session manager causing exceptions for violating primary key + in inserting session in the table + + 4529 ErrorHandler showing servlet info, can not be disabled unless + overriding most of its functionality + + 4533 Reinstate hard close in dispatcher + + 4537 High CPU on Jetty Websocket thread + + 4541 Jetty server always allocates maximum response header size + + 4550 XmlConfiguration constructor selection based on number of arguments + + 4567 Jetty logging supporting Throwable as last argument + + 4573 Order dependency of X-Forwarded-Host and X-Forwarded-Port + + 4575 Stopping ReservedThreadExecutor may hang + + 4577 request getPathInfo returns null + + 4594 ServletContextListeners added to destroyServletContextListeners in + ContextHandler::startContext() are not removed by + ContextHandler::removeEventListener() + + 4606 DateCache.formatNow(long now) does not honor the passed in long + + 4612 ReservedThreadExecutor hangs when the last reserved thread idles out + +jetty-9.4.26.v20200117 - 17 January 2020 + + 2620 Exception from user endpoint onClose results in unclosed + WebSocketSession + + 4383 Errors deleting multipart tmp files java.lang.NullPointerException + under heavy load + + 4444 TLS Connection Timeout Intermittently + + 4461 IllegalStateException in HttpOutput with Jersey + +jetty-9.4.25.v20191220 - 20 December 2019 + + 995 UrlEncoded.encodeString should skip more characters + + 2195 Add parameter expansion to start.jar --exec parameters + + 3512 File descriptor is not released after zip file uploaded via + jetty-client + + 3730 WebSocketClient constructor cleanup (and deprecations) + + 4269 ResponseWriter should not throw RuntimeIOExceptions + + 4323 QOS Filter does not handle IllegalStateException and never releases + passes + + 4329 rewrite prevents URL session tracking. + + 4331 Improve handling of HttpOutput.close() for pending writes + + 4350 Deprecated MultiPartInputStreamParser still used in jetty-server + (MultiPartsUtilParser) but OSGi ExportPackage suppressed + + 4351 Servlet.service called before Servlet.init is finished when servlet is + lazily initialized + + 4363 jetty-maven-plugin no longer processes supplied context.xml-file. + + 4366 HTTP client uses SOCKS4 proxy hostname for SSL hostname verification + + 4374 Jetty client: Response.AsyncContentListener.onContent is not called + + 4376 Async Content Complete bug results in + org.eclipse.jetty.io.EofException: Async closed + + 4385 Limit new UnsupportedOperationException to direct base class + SslContextFactory usage + + 4392 Suppress logging of QuietException in HttpChannelState.asyncError() + + 4402 NPE in JettyRunWarExplodedMojo + + 4411 Jetty server spins on incomplete request due to delayed dispatch + until content + + 4415 GzipHandler invalid input zip size on large + (over 2,147,483,647 bytes) request body content + + 4421 HttpClient support for PROXY protocol + + 4427 Retried HttpClient Requests can result in duplicates cookies + +jetty-9.4.24.v20191120 - 20 November 2019 + + 3083 The ini-template for jetty.console-capture.dir does not match the + default value + + 4128 OpenIdCredetials can't decode JWT ID token + + 4334 Better test ErrorHandler changes + +jetty-9.4.23.v20191118 - 18 November 2019 + + 1485 Add systemd service file + + 2266 Jetty maven plugin reload is triggered each time the + `scanIntervalSeconds` pass + + 2340 Remove raw ServletHandler usage examples from documentation + + 2709 current default for headerCacheSize is not large enough for many + requests + + 3863 Enforce use of SNI + + 3869 Update to ASM 7.2 for jdk 13 + + 4033 Ignore bad percent encodings in paths during + URIUtil.equalsIgnoreEncodings() + + 4138 OpenID module should use HttpClient instead of HttpURLConnection + + 4156 IllegalStateException when forwarding to jsp with new session + + 4161 Regression: EofException: request lifecycle violation + + 4173 NullPointerException warning in log from WebInfConfiguration after + upgrade + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + + 4236 clean up redirect code calculation for OpenIdAuthenticator + + 4237 simplify openid module configuration + + 4240 CGI form post results in 500 response if no character encoding + + 4243 ErrorHandler produces invalid json error response + + 4247 Cookie security attributes are going to mandated by Google Chrome + + 4248 Websocket client UpgradeListener never reports success + + 4251 Http 2.0 clients cannot upgrade protocol + + 4258 RateControl should be per-connection + + 4264 Spring Boot BasicErrorController no longer invoked + + 4265 HttpChannel SEND_ERROR should use ErrorHandler.doError() + + 4277 Reading streamed gzipped body never terminates + + 4279 Regression: ResponseWriter#close blocks indefinitely + + 4282 Review HttpParser handling in case of no content + + 4283 Wrong package for OpenJDK8ClientALPNProcessor + + 4284 Possible NullPointerException in Main.java when stopped from command + line + + 4287 Move getUriLastPathSegment(URI uri) to URIUtil + + 4296 Unable to create WebSocket connect if the query string of the URL has % + symbol. + + 4301 Demand beforeContent is not forwarded + + 4305 Jetty server ALPN shall alert fatal no_application_protocol if no + client application protocol is supported + + 4325 Deprecate SniX509ExtendedKeyManager constructor without + SslContextFactory$Server + +jetty-9.4.22.v20191022 - 22 October 2019 + + 2429 HttpClient backpressure improved + + 3558 Error notifications can be received after a successful websocket + + 3787 Jetty client sometimes returns EOFException instead of + SSLHandshakeException on certificate errors. + + 3913 Clustered HttpSession IllegalStateException: Invalid for read + + 3989 Inform custom ManagedSelector of dead selector via optional + onFailedSelect() + + 4096 Thread in ReservedThreadExecutor does not exit when stopped + + 4104 Frames are sent through ExtensionStack even if WebSocket Session is + closed + + 4105 QueuedThreadPool increased thread usage and no idle thread decay + + 4115 Drop HTTP/2 pseudo headers + + 4121 QueuedThreadPool should support ThreadFactory behaviors + + 4122 QueuedThreadPool should reset thread interrupted on failed run + + 4128 OpenIdCredetials can't decode JWT ID token + + 4132 Should be possible to use OIDC without metadata + + 4141 ClassCastException with non-async Servlet + async Filter + + HttpServletRequestWrapper + + 4142 Configurable HTTP/2 RateControl + + 4144 Naked cast to Request should be avoided + + 4156 IllegalStateException when forwarding to jsp with new session + + 4158 Behaviour change in session handling in 9.4.21.v20190926 + + 4170 Client-side alias selection based on SSLEngine + + 4174 ConcurrentModificationException when stopping jetty:run-war + + 4176 Should not set header if sendError has been called + + 4177 Configure HTTP proxy with SslContextFactory + + 4179 Improve HttpChannel$SendCallback references for GC + + 4183 Jetty considers bootstrap injected class to be a "server class" + + 4188 Spin in HttpOutput.close + + 4190 Jetty hangs after thread blocked in SharedBlockingCallback.block() + called by HttpOutput.close + + 4191 Increase GzipHandler minGzipSize default size + + 4193 InetAccessHandler - new includeConnectors/excludeConnectors not quite + correct anymore + + 4201 Throw SSLHandshakeException in case of TLS handshake failures + + 4203 Some Transfer-Encoding and Content-Length combinations do not result in + expected 400 Bad Request + + 4204 Transfer-Encoding behavior does not follow RFC7230 + + 4208 Regression in Jetty 9.4.21: 304 response with Content-Length fails + + 4209 Unused TLS connection is not closed in Java 11 + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + + 4227 First authorization request produced by OIDC module fails due to + inclusion of sessionid + +jetty-9.4.21.v20190926 - 26 September 2019 + + 97 Permanent UnavailableException thrown during servlet request handling + should cause servlet destroy + + 137 Support OAuth + + 155 No way to set keystore for JSR 356 websocket clients, needed for SSL + client authentication + + 1036 Allow easy configuration of Scheduler-Threads and name them more + appropriate + + 2815 HPack fields are opaque octets + + 3040 Allow RFC6265 Cookies to include optional SameSite attribute + + 3106 WebSocket connection stats and request stats + + 3734 WebSocket suspend when input closed + + 3747 Make Jetty Demo work with JPMS + + 3806 Error Page handling Async race with ProxyServlet + + 3913 Clustered HttpSession IllegalStateException: Invalid for read + + 3936 Race condition when modifying session + sendRedirect() + + 3956 Remove and warn on use of illegal HTTP/2 response headers + + 3964 Improve efficiency of listeners + + 3968 WebSocket sporadic ReadPendingException using suspend/resume + + 3978 HTTP/2 fixes for robustly handling abnormal traffic and resource + exhaustion + + 3983 JarFileResource incorrectly lists the contents of directories with + spaces + + 3985 Improve lenient Cookie parsing + + 3989 Inform custom ManagedSelector of dead selector via optional + onFailedSelect() + + 4000 Add SameFileAliasChecker to help with FileSystem static file access + normalization on Mac and Windows + + 4007 NullPointerException while trying to run jetty start.run on Windows + + 4009 ServletContextHandler setSecurityHandler broke handler chain + + 4020 Revert WebSocket ExtensionFactory change to interface + + 4022 Servlet which is added by ServletRegistration can't be started + + 4025 Provide more write-through behaviours for DefaultSessionCache + + 4027 Ensure AbstractSessionDataStore cannot be used unless it is started + + 4033 Ignore bad percent encodings in paths during + URIUtil.equalsIgnoreEncodings() + + 4047 Gracefully stopped Jetty not flushing all response data + + 4048 Multiple values in X-Forwarded-Port throw NumberFormatException + + 4057 NullPointerException in o.e.j.h.HttpFields + + 4064 NullPointerException initializing embedded servlet + + 4075 Do not fail on servlet-mapping with url-pattern /On* + + 4082 NullPointerExceptoin while Debug logging in client + + 4084 Use of HttpConfiguration.setBlockingTimeout(long) in jetty.xml produces + warning on jetty-home startup + + 4105 Cleanup of Idle thread count in QueuedThreadPool + + 4113 HttpClient fails with JDK 13 and TLS 1.3 + +jetty-9.4.20.v20190813 - 13 August 2019 + + 300 Implement Deflater / Inflater Object Pool + + 2061 WebSocket hangs in blockingWrite + + 3601 HTTP2 stall on reset streams + + 3648 javax.websocket client container incorrectly creates Server + SslContextFactory + + 3698 Missing WebSocket ServerContainer after server restart + + 3700 stackoverflow in WebAppClassLoaderUrlStreamTest + + 3708 Swap various java.lang.String replace() methods for better performant + ones + + 3731 Add testing of CDI behaviors + + 3736 NPE from WebAppClassLoader during CDI + + 3746 ClassCastException in WriteFlusher.java - IdleState cannot be cast to + FailedState + + 3749 Memory leak while processing AsyncListener annotations + + 3755 ServerWithAnnotations doesn't do anything + + 3758 Avoid sending empty trailer frames for http/2 requests + + 3782 X-Forwarded-Port overrides X-Forwarded-For + + 3786 ALPN support for Java 14 + + 3798 ClasspathPattern match method throws NPE. URI can be null + + 3799 Programmatically added listeners from + ServletContextListener.contextInitialzed() are not called + + 3804 Weld/CDI XML backwards compat + + 3805 XmlConfiguration odd behavior for numbers + + 3806 The error page handler didn't process correctly in proxy + + 3815 PropertyFileLoginModule adds user principle as a role + + 3822 trustAll will not work on some servers + + 3829 Avoid sending empty trailer frames for http/2 responses + + 3835 WebSocketSession are not being stopped properly + + 3840 Byte-range request performance problems with large files + + 3856 Different behaviour with maxFormContentSize=0 if Content-Length header + is present/missing + + 3876 WebSocketPartialListener is only called for initial frames, not for + continuation frames + + 3884 @WebSocket without @OnWebSocketMessage handler fails when receiving a + continuation frame + + 3888 BufferUtil.toBuffer(Resource resource,boolean direct) does not like + large (4G+) Resources + + 3906 Fix for #3840 breaks Path encapsulation in PathResource + + 3929 Deadlock between new HTTP2Connection() and Server.stop() + + 3940 Double initialization of Log + + 3957 CustomRequestLog bad usage of MethodHandles.lookup() + + 3960 Fix HttpConfiguration copy constructor + + 3969 X-Forwarded-Port header customization isn't possible jetty-9.4.19.v20190610 - 10 June 2019 + 2909 Remove B64Code @@ -246,6 +657,7 @@ jetty-9.4.18.v20190429 - 29 April 2019 + 3609 Fix infinispan start module dependencies jetty-9.4.17.v20190418 - 18 April 2019 + + 2140 Infinispan and hazelcast changes to scavenge zombie expired sessions + 3464 Split SslContextFactory into Client and Server + 3549 Directory Listing on Windows reveals Resource Base path + 3555 DefaultHandler Reveals Base Resource Path of each Context @@ -323,6 +735,11 @@ jetty-9.4.15.v20190215 - 15 February 2019 + 3350 Do not expect to be able to connect to https URLs with the HttpClient created from a parameterless constructor +jetty-9.3.28.v20191105 - 05 November 2019 + + 3989 Inform custom ManagedSelector of dead selector via optional + onFailedSelect() + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + jetty-9.3.27.v20190418 - 18 April 2019 + 3549 Directory Listing on Windows reveals Resource Base path + 3555 DefaultHandler Reveals Base Resource Path of each Context @@ -335,6 +752,9 @@ jetty-9.3.26.v20190403 - 03 April 2019 ForwardedRequestCustomizer + 3319 Allow reverse sort for directory listed files +jetty-9.2.29.v20191105 - 05 November 2019 + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + jetty-9.2.28.v20190418 - 18 April 2019 + 3549 Directory Listing on Windows reveals Resource Base path + 3555 DefaultHandler Reveals Base Resource Path of each Context diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index dd6db29871e..6e60cc36d63 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -183,12 +183,12 @@ org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} org.eclipse.jetty.websocket - jetty-websocket-client + websocket-jetty-client ${project.version} diff --git a/aggregates/jetty-websocket-all/pom.xml b/aggregates/jetty-websocket-all/pom.xml index df9eb5f59b5..fec0ba1be95 100644 --- a/aggregates/jetty-websocket-all/pom.xml +++ b/aggregates/jetty-websocket-all/pom.xml @@ -113,7 +113,7 @@ org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} provided diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index 4220f823685..165dbb9c747 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -63,6 +63,10 @@ + + org.slf4j + slf4j-api + org.eclipse.jetty jetty-util @@ -101,6 +105,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/apache-jsp/src/main/java/module-info.java b/apache-jsp/src/main/java/module-info.java index 99b8a2737e7..20f6efc0d1e 100644 --- a/apache-jsp/src/main/java/module-info.java +++ b/apache-jsp/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import javax.servlet.ServletContainerInitializer; @@ -31,6 +31,7 @@ module org.eclipse.jetty.apache.jsp requires jetty.servlet.api; requires org.eclipse.jetty.util; requires org.mortbay.apache.jasper; + requires org.slf4j; provides Log with JuliLog; provides ServletContainerInitializer with JettyJasperInitializer; diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java index 9538da980c2..9ab013880f5 100644 --- a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java +++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.apache.jsp; @@ -54,27 +54,18 @@ public class JettyJasperInitializer extends JasperInitializer super(context, namespaceAware, validation, blockExternal); } - /** - * @see org.apache.jasper.servlet.TldScanner#scan() - */ @Override public void scan() throws IOException, SAXException { return; //do nothing } - /** - * @see org.apache.jasper.servlet.TldScanner#getListeners() - */ @Override public List getListeners() { return Collections.emptyList(); } - /** - * @see org.apache.jasper.servlet.TldScanner#scanJars() - */ @Override public void scanJars() { diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java index f7d8b15f598..1283892c243 100644 --- a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java +++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.apache.jsp; @@ -48,9 +48,6 @@ public class JettyTldPreScanned extends TldPreScanned _jettyPreScannedURLs = preScannedTlds; } - /** - * @see org.apache.jasper.servlet.TldPreScanned#scanJars() - */ @Override public void scanJars() { diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JuliLog.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JuliLog.java index 04218fcc081..b85aecfbabc 100644 --- a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JuliLog.java +++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JuliLog.java @@ -1,23 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.apache.jsp; +import org.slf4j.LoggerFactory; + public class JuliLog implements org.apache.juli.logging.Log { public static org.apache.juli.logging.Log getInstance(String name) @@ -25,19 +27,16 @@ public class JuliLog implements org.apache.juli.logging.Log return new JuliLog(name); } - private final org.eclipse.jetty.util.log.Logger _logger; - private final org.eclipse.jetty.util.log.StdErrLog _stdErrLog; + private final org.slf4j.Logger _logger; public JuliLog() { - _logger = org.eclipse.jetty.util.log.Log.getRootLogger(); - _stdErrLog = (_logger instanceof org.eclipse.jetty.util.log.StdErrLog) ? (org.eclipse.jetty.util.log.StdErrLog)_logger : null; + _logger = LoggerFactory.getLogger(""); } public JuliLog(String name) { - _logger = org.eclipse.jetty.util.log.Log.getLogger(name); - _stdErrLog = (_logger instanceof org.eclipse.jetty.util.log.StdErrLog) ? (org.eclipse.jetty.util.log.StdErrLog)_logger : null; + _logger = LoggerFactory.getLogger(name); } @Override @@ -49,31 +48,31 @@ public class JuliLog implements org.apache.juli.logging.Log @Override public boolean isErrorEnabled() { - return _stdErrLog == null ? true : _stdErrLog.getLevel() <= org.eclipse.jetty.util.log.StdErrLog.LEVEL_WARN; + return _logger.isErrorEnabled(); } @Override public boolean isFatalEnabled() { - return _stdErrLog == null ? true : _stdErrLog.getLevel() <= org.eclipse.jetty.util.log.StdErrLog.LEVEL_WARN; + return _logger.isErrorEnabled(); } @Override public boolean isInfoEnabled() { - return _stdErrLog == null ? true : _stdErrLog.getLevel() <= org.eclipse.jetty.util.log.StdErrLog.LEVEL_INFO; + return _logger.isInfoEnabled(); } @Override public boolean isTraceEnabled() { - return _stdErrLog == null ? true : _stdErrLog.getLevel() <= org.eclipse.jetty.util.log.StdErrLog.LEVEL_DEBUG; + return _logger.isTraceEnabled(); } @Override public boolean isWarnEnabled() { - return _stdErrLog == null ? true : _stdErrLog.getLevel() <= org.eclipse.jetty.util.log.StdErrLog.LEVEL_WARN; + return _logger.isWarnEnabled(); } @Override diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/jsp/JettyJspServlet.java b/apache-jsp/src/main/java/org/eclipse/jetty/jsp/JettyJspServlet.java index 222c4924190..6b045b6c25b 100644 --- a/apache-jsp/src/main/java/org/eclipse/jetty/jsp/JettyJspServlet.java +++ b/apache-jsp/src/main/java/org/eclipse/jetty/jsp/JettyJspServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jsp; diff --git a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyJspServlet.java b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyJspServlet.java index 1963fc1ccf4..e53da63c82c 100644 --- a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyJspServlet.java +++ b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyJspServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jsp; @@ -62,9 +62,6 @@ public class TestJettyJspServlet super(); } - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { diff --git a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java index 6dcc79e267b..a371f64dc22 100644 --- a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java +++ b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jsp; diff --git a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJspFileNameToClass.java b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJspFileNameToClass.java index 4d43f01756c..11dcbde78f5 100644 --- a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJspFileNameToClass.java +++ b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJspFileNameToClass.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jsp; diff --git a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspConfig.java b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspConfig.java index c75507f80dc..5d326522905 100644 --- a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspConfig.java +++ b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jstl; diff --git a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspIncludeTest.java b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspIncludeTest.java index d1785cf0747..917c8c68153 100644 --- a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspIncludeTest.java +++ b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JspIncludeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jstl; diff --git a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java index 8580f2aa867..501de945604 100644 --- a/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java +++ b/apache-jstl/src/test/java/org/eclipse/jetty/jstl/JstlTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jstl; diff --git a/apache-jstl/src/test/resources/jetty-logging.properties b/apache-jstl/src/test/resources/jetty-logging.properties index 08befa5ce97..c1f44baf179 100644 --- a/apache-jstl/src/test/resources/jetty-logging.properties +++ b/apache-jstl/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl # org.eclipse.jetty.LEVEL=INFO # org.eclipse.jetty.util.LEVEL=DEBUG diff --git a/build-resources/jetty-codestyle-eclipse-ide.xml b/build-resources/jetty-codestyle-eclipse-ide.xml index d3960f495f0..be0cefb9e8a 100644 --- a/build-resources/jetty-codestyle-eclipse-ide.xml +++ b/build-resources/jetty-codestyle-eclipse-ide.xml @@ -347,7 +347,7 @@ - + diff --git a/build-resources/jetty-codestyle-intellij.xml b/build-resources/jetty-codestyle-intellij.xml index 1f276e4f415..131dcd75a29 100644 --- a/build-resources/jetty-codestyle-intellij.xml +++ b/build-resources/jetty-codestyle-intellij.xml @@ -1,4 +1,4 @@ - + - + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.http2 http2-server diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/module-info.java b/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/module-info.java index 9a7e82c2dc2..a78a2135e81 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/module-info.java +++ b/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor; @@ -22,9 +22,8 @@ import org.eclipse.jetty.io.ssl.ALPNProcessor; module org.eclipse.jetty.alpn.conscrypt.server { requires org.conscrypt; - requires org.eclipse.jetty.alpn.server; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires org.slf4j; + requires transitive org.eclipse.jetty.alpn.server; provides ALPNProcessor.Server with ConscryptServerALPNProcessor; } diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptServerALPNProcessor.java b/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptServerALPNProcessor.java index 3e5a4ca2598..974029cd8bf 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptServerALPNProcessor.java +++ b/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptServerALPNProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.conscrypt.server; @@ -31,12 +31,12 @@ import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.ssl.ALPNProcessor; import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint; import org.eclipse.jetty.io.ssl.SslHandshakeListener; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ConscryptServerALPNProcessor implements ALPNProcessor.Server { - private static final Logger LOG = Log.getLogger(ConscryptServerALPNProcessor.class); + private static final Logger LOG = LoggerFactory.getLogger(ConscryptServerALPNProcessor.class); @Override public void init() diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java index f17c3283fd8..bce64c886a9 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java +++ b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.conscrypt.server; @@ -79,11 +79,9 @@ public class ConscryptHTTP2ServerTest private void configureSslContextFactory(SslContextFactory sslContextFactory) { Path path = Paths.get("src", "test", "resources"); - File keys = path.resolve("keystore").toFile(); + File keys = path.resolve("keystore.p12").toFile(); sslContextFactory.setKeyStorePath(keys.getAbsolutePath()); - sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - sslContextFactory.setTrustStorePath(keys.getAbsolutePath()); - sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setProvider("Conscrypt"); if (JavaVersion.VERSION.getPlatform() < 9) { diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/jetty-logging.properties b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/jetty-logging.properties index c391f84e35b..2f2fa6d19d9 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/jetty-logging.properties +++ b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.alpn.LEVEL=DEBUG diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/keystore b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/keystore deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/keystore and /dev/null differ diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/keystore.p12 b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..e4b6d7fb090 Binary files /dev/null and b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/resources/keystore.p12 differ diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index fb8b4a1bb2a..5e33ec1daa9 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -40,6 +40,10 @@ jetty-alpn-client ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty.http2 @@ -47,6 +51,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + diff --git a/jetty-alpn/jetty-alpn-java-client/src/main/java/module-info.java b/jetty-alpn/jetty-alpn-java-client/src/main/java/module-info.java index 008bd311206..8496f7fe5e6 100644 --- a/jetty-alpn/jetty-alpn-java-client/src/main/java/module-info.java +++ b/jetty-alpn/jetty-alpn-java-client/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.alpn.java.client.JDK9ClientALPNProcessor; @@ -21,9 +21,8 @@ import org.eclipse.jetty.io.ssl.ALPNProcessor; module org.eclipse.jetty.alpn.java.client { - requires org.eclipse.jetty.alpn.client; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.alpn.client; + requires org.slf4j; provides ALPNProcessor.Client with JDK9ClientALPNProcessor; } diff --git a/jetty-alpn/jetty-alpn-java-client/src/main/java/org/eclipse/jetty/alpn/java/client/JDK9ClientALPNProcessor.java b/jetty-alpn/jetty-alpn-java-client/src/main/java/org/eclipse/jetty/alpn/java/client/JDK9ClientALPNProcessor.java index f8e444b051e..3a455ffb024 100644 --- a/jetty-alpn/jetty-alpn-java-client/src/main/java/org/eclipse/jetty/alpn/java/client/JDK9ClientALPNProcessor.java +++ b/jetty-alpn/jetty-alpn-java-client/src/main/java/org/eclipse/jetty/alpn/java/client/JDK9ClientALPNProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.java.client; @@ -28,12 +28,12 @@ import org.eclipse.jetty.io.ssl.ALPNProcessor; import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint; import org.eclipse.jetty.io.ssl.SslHandshakeListener; import org.eclipse.jetty.util.JavaVersion; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JDK9ClientALPNProcessor implements ALPNProcessor.Client { - private static final Logger LOG = Log.getLogger(JDK9ClientALPNProcessor.class); + private static final Logger LOG = LoggerFactory.getLogger(JDK9ClientALPNProcessor.class); @Override public void init() @@ -55,13 +55,13 @@ public class JDK9ClientALPNProcessor implements ALPNProcessor.Client ALPNClientConnection alpn = (ALPNClientConnection)connection; SSLParameters sslParameters = sslEngine.getSSLParameters(); List protocols = alpn.getProtocols(); - sslParameters.setApplicationProtocols(protocols.toArray(new String[protocols.size()])); + sslParameters.setApplicationProtocols(protocols.toArray(new String[0])); sslEngine.setSSLParameters(sslParameters); ((DecryptedEndPoint)connection.getEndPoint()).getSslConnection() .addHandshakeListener(new ALPNListener(alpn)); } - private final class ALPNListener implements SslHandshakeListener + private static final class ALPNListener implements SslHandshakeListener { private final ALPNClientConnection alpnConnection; diff --git a/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2ClientTest.java b/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2ClientTest.java index 6d6f73f79e8..00a25af7d06 100644 --- a/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2ClientTest.java +++ b/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2ClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.java.client; diff --git a/jetty-alpn/jetty-alpn-java-client/src/test/resources/jetty-logging.properties b/jetty-alpn/jetty-alpn-java-client/src/test/resources/jetty-logging.properties index d96a696f82e..56cc73e5d68 100644 --- a/jetty-alpn/jetty-alpn-java-client/src/test/resources/jetty-logging.properties +++ b/jetty-alpn/jetty-alpn-java-client/src/test/resources/jetty-logging.properties @@ -1,2 +1,2 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index 918725febde..10725f09ccd 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -51,6 +51,15 @@ jetty-alpn-server ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.http2 http2-server diff --git a/jetty-alpn/jetty-alpn-java-server/src/main/java/module-info.java b/jetty-alpn/jetty-alpn-java-server/src/main/java/module-info.java index be977ae30c1..3dc66cb7ad2 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/main/java/module-info.java +++ b/jetty-alpn/jetty-alpn-java-server/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor; @@ -21,9 +21,8 @@ import org.eclipse.jetty.io.ssl.ALPNProcessor; module org.eclipse.jetty.alpn.java.server { - requires org.eclipse.jetty.alpn.server; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires org.slf4j; + requires transitive org.eclipse.jetty.alpn.server; provides ALPNProcessor.Server with JDK9ServerALPNProcessor; } diff --git a/jetty-alpn/jetty-alpn-java-server/src/main/java/org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor.java b/jetty-alpn/jetty-alpn-java-server/src/main/java/org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor.java index ca091a96e15..f5ae6579eba 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/main/java/org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor.java +++ b/jetty-alpn/jetty-alpn-java-server/src/main/java/org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.java.server; @@ -28,12 +28,12 @@ import org.eclipse.jetty.io.ssl.ALPNProcessor; import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslHandshakeListener; import org.eclipse.jetty.util.JavaVersion; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JDK9ServerALPNProcessor implements ALPNProcessor.Server, SslHandshakeListener { - private static final Logger LOG = Log.getLogger(JDK9ServerALPNProcessor.class); + private static final Logger LOG = LoggerFactory.getLogger(JDK9ServerALPNProcessor.class); @Override public void init() @@ -55,7 +55,7 @@ public class JDK9ServerALPNProcessor implements ALPNProcessor.Server, SslHandsha sslEngine.setHandshakeApplicationProtocolSelector(new ALPNCallback((ALPNServerConnection)connection)); } - private final class ALPNCallback implements BiFunction, String>, SslHandshakeListener + private static final class ALPNCallback implements BiFunction, String>, SslHandshakeListener { private final ALPNServerConnection alpnConnection; @@ -68,10 +68,19 @@ public class JDK9ServerALPNProcessor implements ALPNProcessor.Server, SslHandsha @Override public String apply(SSLEngine engine, List protocols) { - if (LOG.isDebugEnabled()) - LOG.debug("apply {} {}", alpnConnection, protocols); - alpnConnection.select(protocols); - return alpnConnection.getProtocol(); + try + { + if (LOG.isDebugEnabled()) + LOG.debug("apply {} {}", alpnConnection, protocols); + alpnConnection.select(protocols); + return alpnConnection.getProtocol(); + } + catch (Throwable x) + { + // Cannot negotiate the protocol, return null to have + // JSSE send Alert.NO_APPLICATION_PROTOCOL to the client. + return null; + } } @Override diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java index ef58bf7ca8f..b524d17fec9 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java +++ b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.java.server; @@ -22,8 +22,13 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; import javax.servlet.http.HttpServletRequest; @@ -38,12 +43,16 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; public class JDK9ALPNTest { @@ -74,9 +83,8 @@ public class JDK9ALPNTest private SslContextFactory.Server newServerSslContextFactory() { SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); - sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); // The mandatory HTTP/2 cipher. sslContextFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); return sslContextFactory; @@ -85,10 +93,10 @@ public class JDK9ALPNTest @Test public void testClientNotSupportingALPNServerSpeaksDefaultProtocol() throws Exception { - startServer(new AbstractHandler.ErrorDispatchHandler() + startServer(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) { baseRequest.setHandled(true); } @@ -127,10 +135,10 @@ public class JDK9ALPNTest @Test public void testClientSupportingALPNServerSpeaksNegotiatedProtocol() throws Exception { - startServer(new AbstractHandler.ErrorDispatchHandler() + startServer(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) { baseRequest.setHandled(true); } @@ -168,4 +176,58 @@ public class JDK9ALPNTest } } } + + @Test + public void testClientSupportingALPNCannotNegotiateProtocol() throws Exception + { + startServer(new AbstractHandler() + { + @Override + public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + jettyRequest.setHandled(true); + } + }); + + SslContextFactory sslContextFactory = new SslContextFactory.Client(true); + sslContextFactory.start(); + String host = "localhost"; + int port = connector.getLocalPort(); + try (SocketChannel client = SocketChannel.open(new InetSocketAddress(host, port))) + { + client.socket().setSoTimeout(5000); + + SSLEngine sslEngine = sslContextFactory.newSSLEngine(host, port); + sslEngine.setUseClientMode(true); + SSLParameters sslParameters = sslEngine.getSSLParameters(); + sslParameters.setApplicationProtocols(new String[]{"unknown/1.0"}); + sslEngine.setSSLParameters(sslParameters); + sslEngine.beginHandshake(); + assertSame(SSLEngineResult.HandshakeStatus.NEED_WRAP, sslEngine.getHandshakeStatus()); + + ByteBuffer sslBuffer = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize()); + + SSLEngineResult result = sslEngine.wrap(BufferUtil.EMPTY_BUFFER, sslBuffer); + assertSame(SSLEngineResult.Status.OK, result.getStatus()); + + sslBuffer.flip(); + client.write(sslBuffer); + + assertSame(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, sslEngine.getHandshakeStatus()); + + sslBuffer.clear(); + int read = client.read(sslBuffer); + assertThat(read, greaterThan(0)); + + sslBuffer.flip(); + // TLS frame layout: record_type, major_version, minor_version, hi_length, lo_length + int recordTypeAlert = 21; + assertEquals(recordTypeAlert, sslBuffer.get(0) & 0xFF); + // Alert record layout: alert_level, alert_code + int alertLevelFatal = 2; + assertEquals(alertLevelFatal, sslBuffer.get(5) & 0xFF); + int alertCodeNoApplicationProtocol = 120; + assertEquals(alertCodeNoApplicationProtocol, sslBuffer.get(6) & 0xFF); + } + } } diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java index 763488f5750..36138a935a2 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java +++ b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.java.server; @@ -46,9 +46,8 @@ public class JDK9HTTP2Server httpsConfig.addCustomizer(new SecureRequestCustomizer()); SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); - sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); HttpConnectionFactory http = new HttpConnectionFactory(httpsConfig); diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/resources/jetty-logging.properties b/jetty-alpn/jetty-alpn-java-server/src/test/resources/jetty-logging.properties index c391f84e35b..2f2fa6d19d9 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/test/resources/jetty-logging.properties +++ b/jetty-alpn/jetty-alpn-java-server/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.alpn.LEVEL=DEBUG diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/resources/keystore.jks b/jetty-alpn/jetty-alpn-java-server/src/test/resources/keystore.jks deleted file mode 100644 index d6592f95ee9..00000000000 Binary files a/jetty-alpn/jetty-alpn-java-server/src/test/resources/keystore.jks and /dev/null differ diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/resources/keystore.p12 b/jetty-alpn/jetty-alpn-java-server/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..a82f9773690 Binary files /dev/null and b/jetty-alpn/jetty-alpn-java-server/src/test/resources/keystore.p12 differ diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 0cf6794b9fa..cd00d31091a 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -44,6 +44,15 @@ jetty-server ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-13.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-13.mod index 689601a4197..eebcdb72615 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-13.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-13.mod @@ -1,4 +1,4 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [depend] -alpn-impl/alpn-9 +alpn-impl/alpn-11 diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-14.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-14.mod index 689601a4197..eebcdb72615 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-14.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-14.mod @@ -1,4 +1,4 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [depend] -alpn-impl/alpn-9 +alpn-impl/alpn-11 diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-15.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-15.mod new file mode 100644 index 00000000000..eebcdb72615 --- /dev/null +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-15.mod @@ -0,0 +1,4 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[depend] +alpn-impl/alpn-11 diff --git a/jetty-alpn/jetty-alpn-server/src/main/java/module-info.java b/jetty-alpn/jetty-alpn-server/src/main/java/module-info.java index 877d4cb91b1..c0e6b7e1452 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/java/module-info.java +++ b/jetty-alpn/jetty-alpn-server/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.io.ssl.ALPNProcessor; @@ -22,9 +22,8 @@ module org.eclipse.jetty.alpn.server { exports org.eclipse.jetty.alpn.server; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.server; + requires org.slf4j; uses ALPNProcessor.Server; } diff --git a/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnection.java b/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnection.java index bdc448be261..8d6e931793d 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnection.java +++ b/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.server; @@ -27,12 +27,12 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NegotiatingServerConnection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ALPNServerConnection extends NegotiatingServerConnection { - private static final Logger LOG = Log.getLogger(ALPNServerConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(ALPNServerConnection.class); public ALPNServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List protocols, String defaultProtocol) { diff --git a/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java b/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java index 452431863e2..601d57dd548 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java +++ b/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java @@ -1,26 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.alpn.server; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; import javax.net.ssl.SSLEngine; @@ -30,13 +29,14 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ssl.ALPNProcessor.Server; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NegotiatingServerConnectionFactory; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ALPNServerConnectionFactory extends NegotiatingServerConnectionFactory { - private static final Logger LOG = Log.getLogger(ALPNServerConnectionFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(ALPNServerConnectionFactory.class); private final List processors = new ArrayList<>(); @@ -51,20 +51,20 @@ public class ALPNServerConnectionFactory extends NegotiatingServerConnectionFact IllegalStateException failure = new IllegalStateException("No Server ALPNProcessors!"); // Use a for loop on iterator so load exceptions can be caught and ignored - for (Iterator i = ServiceLoader.load(Server.class).iterator(); i.hasNext(); ) + TypeUtil.serviceProviderStream(ServiceLoader.load(Server.class)).forEach(provider -> { Server processor; try { - processor = i.next(); + processor = provider.get(); } catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug(x.getMessage(), x); if (x != failure) failure.addSuppressed(x); - continue; + return; } try @@ -75,11 +75,11 @@ public class ALPNServerConnectionFactory extends NegotiatingServerConnectionFact catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug("Could not initialize " + processor, x); + LOG.debug("Could not initialize {}", processor, x); if (x != failure) failure.addSuppressed(x); } - } + }); if (LOG.isDebugEnabled()) { diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 8eadf27f3b3..15e361f4cdb 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -69,6 +69,10 @@ org.ow2.asm asm-commons + + org.slf4j + slf4j-api + jakarta.transaction @@ -86,5 +90,10 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + diff --git a/jetty-annotations/src/main/java/module-info.java b/jetty-annotations/src/main/java/module-info.java index a0e1ec910ef..6575c28d572 100644 --- a/jetty-annotations/src/main/java/module-info.java +++ b/jetty-annotations/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import javax.servlet.ServletContainerInitializer; @@ -27,15 +27,9 @@ module org.eclipse.jetty.annotations requires java.annotation; requires java.naming; - requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.plus; - requires org.eclipse.jetty.security; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.servlet; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.webapp; - requires org.objectweb.asm; + requires transitive org.eclipse.jetty.plus; + requires transitive org.objectweb.asm; + requires org.slf4j; uses ServletContainerInitializer; diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractDiscoverableAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractDiscoverableAnnotationHandler.java index 220f5c8040e..9f338c51ff6 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractDiscoverableAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AbstractDiscoverableAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index f97ee601972..fcc31f19c53 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -27,7 +27,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -39,6 +38,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.servlet.ServletContainerInitializer; import javax.servlet.annotation.HandlesTypes; @@ -50,26 +51,25 @@ import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.FragmentConfiguration; import org.eclipse.jetty.webapp.FragmentDescriptor; import org.eclipse.jetty.webapp.JettyWebXmlConfiguration; -import org.eclipse.jetty.webapp.MetaDataComplete; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebDescriptor; import org.eclipse.jetty.webapp.WebXmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Configuration for Annotations */ public class AnnotationConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(AnnotationConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(AnnotationConfiguration.class); public static final String SERVLET_CONTAINER_INITIALIZER_EXCLUSION_PATTERN = "org.eclipse.jetty.containerInitializerExclusionPattern"; public static final String SERVLET_CONTAINER_INITIALIZER_ORDER = "org.eclipse.jetty.containerInitializerOrder"; @@ -188,11 +188,12 @@ public class AnnotationConfiguration extends AbstractConfiguration /** * ServletContainerInitializerOrdering - * - * A list of classnames of ServletContainerInitializers in the order in which - * they are to be called back. One name only in the list can be "*", which is a + *

Applies an ordering to the {@link ServletContainerInitializer}s for the context, using + * the value of the "org.eclipse.jetty.containerInitializerOrder" context attribute. + * The attribute value is a list of classnames of ServletContainerInitializers in the order in which + * they are to be called. One name only in the list can be "*", which is a * wildcard which matches any other ServletContainerInitializer name not already - * matched. + * matched.

*/ public class ServletContainerInitializerOrdering { @@ -331,17 +332,16 @@ public class AnnotationConfiguration extends AbstractConfiguration _discoverableAnnotationHandlers.add(handler); } - /** - * @see org.eclipse.jetty.webapp.AbstractConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void configure(WebAppContext context) throws Exception { + //handle introspectable annotations (postconstruct,predestroy, multipart etc etc) context.getObjectFactory().addDecorator(new AnnotationDecorator(context)); if (!context.getMetaData().isMetaDataComplete()) { - //If metadata isn't complete, if this is a servlet 3 webapp or isConfigDiscovered is true, we need to search for annotations + //If web.xml not metadata-complete, if this is a servlet 3 webapp or above + //or configDiscovered is true, we need to search for annotations if (context.getServletContext().getEffectiveMajorVersion() >= 3 || context.isConfigurationDiscovered()) { _discoverableAnnotationHandlers.add(new WebServletAnnotationHandler(context)); @@ -370,9 +370,6 @@ public class AnnotationConfiguration extends AbstractConfiguration } } - /** - * @see org.eclipse.jetty.webapp.AbstractConfiguration#postConfigure(org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void postConfigure(WebAppContext context) throws Exception { @@ -413,7 +410,8 @@ public class AnnotationConfiguration extends AbstractConfiguration } /** - * Perform scanning of classes for annotations + * Perform scanning of classes for discoverable + * annotations such as WebServlet/WebFilter/WebListener * * @param context the context for the scan * @throws Exception if unable to scan @@ -436,6 +434,7 @@ public class AnnotationConfiguration extends AbstractConfiguration isUseMultiThreading(context), getMaxScanWait(context)); + //scan selected jars on the container classpath first parseContainerPath(context, parser); //email from Rajiv Mordani jsrs 315 7 April 2010 // If there is a then the ordering should be @@ -443,6 +442,7 @@ public class AnnotationConfiguration extends AbstractConfiguration // In case there is no others then it is // WEB-INF/classes + order of the elements. parseWebInfClasses(context, parser); + //scan non-excluded, non medatadata-complete jars in web-inf lib parseWebInfLib(context, parser); long start = System.nanoTime(); @@ -480,7 +480,7 @@ public class AnnotationConfiguration extends AbstractConfiguration boolean timeout = !latch.await(getMaxScanWait(context), TimeUnit.SECONDS); long elapsedMs = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS); - LOG.info("Scanning elapsed time={}ms", elapsedMs); + LOG.info("Annotation scanning elapsed time={}ms", elapsedMs); if (LOG.isDebugEnabled()) { @@ -562,9 +562,6 @@ public class AnnotationConfiguration extends AbstractConfiguration return Integer.getInteger(MAX_SCAN_WAIT, DEFAULT_MAX_SCAN_WAIT).intValue(); } - /** - * @see org.eclipse.jetty.webapp.AbstractConfiguration#cloneConfigure(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception { @@ -699,14 +696,14 @@ public class AnnotationConfiguration extends AbstractConfiguration } //If no ordering, nothing is excluded - if (context.getMetaData().getOrdering() == null) + if (!context.getMetaData().isOrdered()) { if (LOG.isDebugEnabled()) LOG.debug("!Excluded {} no ordering", sci); return false; } - List orderedJars = context.getMetaData().getOrderedWebInfJars(); + List orderedJars = context.getMetaData().getWebInfResources(true); //there is an ordering, but there are no jars resulting from the ordering, everything excluded if (orderedJars.isEmpty()) @@ -718,17 +715,17 @@ public class AnnotationConfiguration extends AbstractConfiguration //Check if it is excluded by an ordering URI loadingJarURI = sciResource.getURI(); - boolean found = false; - Iterator itor = orderedJars.iterator(); - while (!found && itor.hasNext()) + boolean included = false; + for (Resource r : orderedJars) { - Resource r = itor.next(); - found = r.getURI().equals(loadingJarURI); + included = r.getURI().equals(loadingJarURI); + if (included) + break; } if (LOG.isDebugEnabled()) - LOG.debug("{}Excluded {} found={}", found ? "!" : "", sci, found); - return !found; + LOG.debug("{}Excluded {} found={}", included ? "!" : "", sci, included); + return !included; } /** @@ -793,7 +790,7 @@ public class AnnotationConfiguration extends AbstractConfiguration */ public boolean isFromWebInfClasses(WebAppContext context, Resource sci) { - for (Resource dir : context.getMetaData().getWebInfClassesDirs()) + for (Resource dir : context.getMetaData().getWebInfClassesResources()) { if (dir.equals(sci)) { @@ -819,31 +816,33 @@ public class AnnotationConfiguration extends AbstractConfiguration long start = 0; if (LOG.isDebugEnabled()) start = System.nanoTime(); - ServiceLoader loader = ServiceLoader.load(ServletContainerInitializer.class); - if (LOG.isDebugEnabled()) - LOG.debug("Service loaders found in {}ms", (TimeUnit.MILLISECONDS.convert((System.nanoTime() - start), TimeUnit.NANOSECONDS))); - - Map sciResourceMap = new HashMap(); - ServletContainerInitializerOrdering initializerOrdering = getInitializerOrdering(context); - - //Get initial set of SCIs that aren't from excluded jars or excluded by the containerExclusionPattern, or excluded - //because containerInitializerOrdering omits it - Iterator iter = loader.iterator(); - while (iter.hasNext()) + List scis = TypeUtil.serviceProviderStream(ServiceLoader.load(ServletContainerInitializer.class)).flatMap(provider -> { - ServletContainerInitializer sci; try { - sci = iter.next(); + return Stream.of(provider.get()); } catch (Error e) { // Probably a SCI discovered on the system classpath that is hidden by the context classloader - LOG.info("Error: " + e.getMessage() + " for " + context); - LOG.debug(e); - continue; + if (LOG.isDebugEnabled()) + LOG.debug("Error: {} for {}", e.getMessage(), context, e); + else + LOG.info("Error: {} for {}", e.getMessage(), context); + return Stream.of(); } + }).collect(Collectors.toList()); + if (LOG.isDebugEnabled()) + LOG.debug("Service loaders found in {}ms", (TimeUnit.MILLISECONDS.convert((System.nanoTime() - start), TimeUnit.NANOSECONDS))); + + Map sciResourceMap = new HashMap<>(); + ServletContainerInitializerOrdering initializerOrdering = getInitializerOrdering(context); + + //Get initial set of SCIs that aren't from excluded jars or excluded by the containerExclusionPattern, or excluded + //because containerInitializerOrdering omits it + for (ServletContainerInitializer sci : scis) + { if (matchesExclusionPattern(sci)) { if (LOG.isDebugEnabled()) @@ -875,7 +874,7 @@ public class AnnotationConfiguration extends AbstractConfiguration if (initializerOrdering != null && !initializerOrdering.isDefaultOrder()) { if (LOG.isDebugEnabled()) - LOG.debug("Ordering ServletContainerInitializers with " + initializerOrdering); + LOG.debug("Ordering ServletContainerInitializers with {}", initializerOrdering); //There is an ordering that is not just "*". //Arrange ServletContainerInitializers according to the ordering of classnames given, irrespective of coming from container or webapp classpaths @@ -902,7 +901,7 @@ public class AnnotationConfiguration extends AbstractConfiguration } else { - for (Resource dir : context.getMetaData().getWebInfClassesDirs()) + for (Resource dir : context.getMetaData().getWebInfClassesResources()) { if (dir.equals(entry.getValue()))//from WEB-INF/classes so can't be ordered/excluded { @@ -931,7 +930,7 @@ public class AnnotationConfiguration extends AbstractConfiguration LOG.debug("Ordering ServletContainerInitializers with ordering {}", context.getMetaData().getOrdering()); //add SCIs according to the ordering of its containing jar - for (Resource webInfJar : context.getMetaData().getOrderedWebInfJars()) + for (Resource webInfJar : context.getMetaData().getWebInfResources(true)) { for (Map.Entry entry : sciResourceMap.entrySet()) { @@ -985,7 +984,7 @@ public class AnnotationConfiguration extends AbstractConfiguration return null; String tmp = (String)context.getAttribute(SERVLET_CONTAINER_INITIALIZER_ORDER); - if (tmp == null || "".equals(tmp.trim())) + if (StringUtil.isBlank(tmp)) return null; return new ServletContainerInitializerOrdering(tmp); @@ -1010,9 +1009,10 @@ public class AnnotationConfiguration extends AbstractConfiguration if (LOG.isDebugEnabled()) _containerPathStats = new CounterStatistic(); + //scan the container classpath jars that were selected by + //filtering in MetaInfConfiguration for (Resource r : context.getMetaData().getContainerResources()) { - //queue it up for scanning if using multithreaded mode if (_parserTasks != null) { ParserTask task = new ParserTask(parser, handlers, r); @@ -1027,7 +1027,10 @@ public class AnnotationConfiguration extends AbstractConfiguration } /** - * Scan jars in WEB-INF/lib + * Scan jars in WEB-INF/lib. + * + * Only jars selected by MetaInfConfiguration, and that are not excluded + * by an ordering will be considered. * * @param context the context for the scan * @param parser the annotation parser to use @@ -1035,20 +1038,13 @@ public class AnnotationConfiguration extends AbstractConfiguration */ public void parseWebInfLib(final WebAppContext context, final AnnotationParser parser) throws Exception { - List frags = context.getMetaData().getFragments(); - //email from Rajiv Mordani jsrs 315 7 April 2010 //jars that do not have a web-fragment.xml are still considered fragments //they have to participate in the ordering - ArrayList webInfUris = new ArrayList(); - List jars = null; - - if (context.getMetaData().getOrdering() != null) - jars = context.getMetaData().getOrderedWebInfJars(); - else - //No ordering just use the jars in any order - jars = context.getMetaData().getWebInfJars(); + //if there is an ordering, the ordered jars should be used. + //If there is no ordering, jars will be unordered. + List jars = context.getMetaData().getWebInfResources(context.getMetaData().isOrdered()); if (LOG.isDebugEnabled()) { @@ -1061,13 +1057,13 @@ public class AnnotationConfiguration extends AbstractConfiguration //for each jar, we decide which set of annotations we need to parse for final Set handlers = new HashSet(); - FragmentDescriptor f = getFragmentFromJar(r, frags); + FragmentDescriptor f = context.getMetaData().getFragmentDescriptorForJar(r); //if its from a fragment jar that is metadata complete, we should skip scanning for @webservlet etc // but yet we still need to do the scanning for the classes on behalf of the servletcontainerinitializers //if a jar has no web-fragment.xml we scan it (because it is not excluded by the ordering) //or if it has a fragment we scan it if it is not metadata complete - if (f == null || !isMetaDataComplete(f) || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty()) + if (f == null || !WebDescriptor.isMetaDataComplete(f) || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty()) { //register the classinheritance handler if there is one if (_classInheritanceHandler != null) @@ -1077,7 +1073,7 @@ public class AnnotationConfiguration extends AbstractConfiguration handlers.addAll(_containerInitializerAnnotationHandlers); //only register the discoverable annotation handlers if this fragment is not metadata complete, or has no fragment descriptor - if (f == null || !isMetaDataComplete(f)) + if (f == null || !WebDescriptor.isMetaDataComplete(f)) handlers.addAll(_discoverableAnnotationHandlers); if (_parserTasks != null) @@ -1095,7 +1091,7 @@ public class AnnotationConfiguration extends AbstractConfiguration } /** - * Scan classes in WEB-INF/classes + * Scan classes in WEB-INF/classes. * * @param context the context for the scan * @param parser the annotation parser to use @@ -1113,7 +1109,7 @@ public class AnnotationConfiguration extends AbstractConfiguration if (LOG.isDebugEnabled()) _webInfClassesStats = new CounterStatistic(); - for (Resource dir : context.getMetaData().getWebInfClassesDirs()) + for (Resource dir : context.getMetaData().getWebInfClassesResources()) { if (_parserTasks != null) { @@ -1128,39 +1124,8 @@ public class AnnotationConfiguration extends AbstractConfiguration } } - /** - * Get the web-fragment.xml from a jar - * - * @param jar the jar to look in for a fragment - * @param frags the fragments previously found - * @return true if the fragment if found, or null of not found - * @throws Exception if unable to determine the the fragment contains - */ - public FragmentDescriptor getFragmentFromJar(Resource jar, List frags) - throws Exception - { - //check if the jar has a web-fragment.xml - FragmentDescriptor d = null; - for (FragmentDescriptor frag : frags) - { - Resource fragResource = frag.getResource(); //eg jar:file:///a/b/c/foo.jar!/META-INF/web-fragment.xml - if (Resource.isContainedIn(fragResource, jar)) - { - d = frag; - break; - } - } - return d; - } - - public boolean isMetaDataComplete(WebDescriptor d) - { - return (d != null && d.getMetaDataComplete() == MetaDataComplete.True); - } - public static class ClassInheritanceMap extends ConcurrentHashMap> { - @Override public String toString() { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationDecorator.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationDecorator.java index ed9a16e8bce..fc576c8f8f0 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationDecorator.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationDecorator.java @@ -1,23 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; +import java.util.Objects; + +import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.Decorator; import org.eclipse.jetty.webapp.WebAppContext; @@ -26,23 +29,26 @@ import org.eclipse.jetty.webapp.WebAppContext; */ public class AnnotationDecorator implements Decorator { - protected AnnotationIntrospector _introspector = new AnnotationIntrospector(); + protected AnnotationIntrospector _introspector; + protected WebAppContext _context; public AnnotationDecorator(WebAppContext context) { - registerHandlers(context); + _context = Objects.requireNonNull(context); + _introspector = new AnnotationIntrospector(_context); + registerHandlers(); } - public void registerHandlers(WebAppContext context) + private void registerHandlers() { - _introspector.registerHandler(new ResourceAnnotationHandler(context)); - _introspector.registerHandler(new ResourcesAnnotationHandler(context)); - _introspector.registerHandler(new RunAsAnnotationHandler(context)); - _introspector.registerHandler(new PostConstructAnnotationHandler(context)); - _introspector.registerHandler(new PreDestroyAnnotationHandler(context)); - _introspector.registerHandler(new DeclareRolesAnnotationHandler(context)); - _introspector.registerHandler(new MultiPartConfigAnnotationHandler(context)); - _introspector.registerHandler(new ServletSecurityAnnotationHandler(context)); + _introspector.registerHandler(new ResourceAnnotationHandler(_context)); + _introspector.registerHandler(new ResourcesAnnotationHandler(_context)); + _introspector.registerHandler(new RunAsAnnotationHandler(_context)); + _introspector.registerHandler(new PostConstructAnnotationHandler(_context)); + _introspector.registerHandler(new PreDestroyAnnotationHandler(_context)); + _introspector.registerHandler(new DeclareRolesAnnotationHandler(_context)); + _introspector.registerHandler(new MultiPartConfigAnnotationHandler(_context)); + _introspector.registerHandler(new ServletSecurityAnnotationHandler(_context)); } /** @@ -50,22 +56,28 @@ public class AnnotationDecorator implements Decorator *
    *
  • Resource
  • *
  • Resources
  • + *
  • RunAs
  • *
  • PostConstruct
  • *
  • PreDestroy
  • - *
  • ServletSecurity?
  • + *
  • DeclareRoles
  • + *
  • MultiPart
  • + *
  • ServletSecurity
  • *
* - * @param o the object ot introspect + * @param o the object to introspect + * @param metaInfo information about the object to introspect */ - protected void introspect(Object o) + protected void introspect(Object o, Object metaInfo) { - _introspector.introspect(o.getClass()); + if (o == null) + return; + _introspector.introspect(o, metaInfo); } @Override public Object decorate(Object o) { - introspect(o); + introspect(o, DecoratedObjectFactory.getAssociatedInfo()); return o; } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationIntrospector.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationIntrospector.java index 6b70fada25c..4ffe33c9cc2 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationIntrospector.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationIntrospector.java @@ -1,28 +1,38 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; +import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; +import org.eclipse.jetty.servlet.BaseHolder; +import org.eclipse.jetty.servlet.Source.Origin; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.WebDescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * AnnotationIntrospector * Introspects a class to find various types of @@ -30,8 +40,10 @@ import java.util.Set; */ public class AnnotationIntrospector { + private static final Logger LOG = LoggerFactory.getLogger(AnnotationIntrospector.class); private final Set> _introspectedClasses = new HashSet<>(); private final List _handlers = new ArrayList(); + private final WebAppContext _context; /** * IntrospectableAnnotationHandler @@ -51,12 +63,14 @@ public class AnnotationIntrospector */ public abstract static class AbstractIntrospectableAnnotationHandler implements IntrospectableAnnotationHandler { - private boolean _introspectAncestors; + protected boolean _introspectAncestors; + protected WebAppContext _context; public abstract void doHandle(Class clazz); - public AbstractIntrospectableAnnotationHandler(boolean introspectAncestors) + public AbstractIntrospectableAnnotationHandler(boolean introspectAncestors, WebAppContext context) { + _context = Objects.requireNonNull(context); _introspectAncestors = introspectAncestors; } @@ -75,6 +89,16 @@ public class AnnotationIntrospector c = c.getSuperclass(); } } + + public WebAppContext getContext() + { + return _context; + } + } + + public AnnotationIntrospector(WebAppContext context) + { + _context = Objects.requireNonNull(context); } public void registerHandler(IntrospectableAnnotationHandler handler) @@ -82,13 +106,95 @@ public class AnnotationIntrospector _handlers.add(handler); } - public void introspect(Class clazz) + /** + * Test if an object should be introspected for some specific types of annotations + * like PostConstruct/PreDestroy/MultiPart etc etc. + * + * According to servlet 4.0, these types of annotations should only be evaluated iff any + * of the following are true: + *
    + *
  1. the object was created by the javax.servlet.ServletContext.createServlet/Filter/Listener method
  2. + *
  3. the object comes either from a discovered annotation (WebServlet/Filter/Listener) or a declaration + * in a descriptor AND web.xml is NOT metadata-complete AND any web-fragment.xml associated with the location of + * the class is NOT metadata-complete
  4. + *
+ * + * We also support evaluations of these types of annotations for objects that were created directly + * by the jetty api. + * + * @param o the object to check for its ability to be introspected for annotations + * @param metaInfo meta information about the object to be introspected + * @return true if it can be introspected according to servlet 4.0 rules + */ + public boolean isIntrospectable(Object o, Object metaInfo) { - if (_handlers == null) - return; - if (clazz == null) + if (o == null) + return false; //nothing to introspect + + if (metaInfo == null) + return true; //no information about the object to introspect, assume introspectable + + @SuppressWarnings("rawtypes") + BaseHolder holder = null; + + try + { + holder = (BaseHolder)metaInfo; + } + catch (ClassCastException e) + { + LOG.warn("Not introspectable {}", metaInfo.getClass().getName(), e); + return true; //not the type of information we were expecting, assume introspectable + } + + Origin origin = (holder.getSource() == null ? null : holder.getSource().getOrigin()); + if (origin == null) + return true; //assume introspectable + + switch (origin) + { + case EMBEDDED: + case JAVAX_API: + { + return true; //objects created from the jetty or servlet api are always introspectable + } + case ANNOTATION: + { + return true; //we will have discovered annotations only if metadata-complete==false + } + default: + { + //must be from a descriptor. Only introspect if the descriptor with which it was associated + //is not metadata-complete + if (_context.getMetaData().isMetaDataComplete()) + return false; + + String descriptorLocation = holder.getSource().getResource(); + if (descriptorLocation == null) + return true; //no descriptor, can't be metadata-complete + try + { + return !WebDescriptor.isMetaDataComplete(_context.getMetaData().getFragmentDescriptor(Resource.newResource(descriptorLocation))); + } + catch (IOException e) + { + LOG.warn("Unable to get Resource for descriptor {}", descriptorLocation, e); + return false; //something wrong with the descriptor + } + } + } + } + + /** + * + */ + public void introspect(Object o, Object metaInfo) + { + if (!isIntrospectable(o, metaInfo)) return; + Class clazz = o.getClass(); + synchronized (_introspectedClasses) { //Synchronize on the set of already introspected classes. diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java index cff8252d1df..1e6621ce8ec 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -39,8 +39,6 @@ import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.MultiReleaseJarFile; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; @@ -48,6 +46,8 @@ import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AnnotationParser @@ -69,7 +69,7 @@ import org.objectweb.asm.Opcodes; */ public class AnnotationParser { - private static final Logger LOG = Log.getLogger(AnnotationParser.class); + private static final Logger LOG = LoggerFactory.getLogger(AnnotationParser.class); protected static int ASM_OPCODE_VERSION = Opcodes.ASM7; //compatibility of api protected static String ASM_OPCODE_VERSION_STR = "ASM7"; diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassInheritanceHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassInheritanceHandler.java index a0e9c2bd947..c2532731ae5 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassInheritanceHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ClassInheritanceHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -24,8 +24,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jetty.annotations.AnnotationParser.AbstractHandler; import org.eclipse.jetty.annotations.AnnotationParser.ClassInfo; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ClassInheritanceHandler @@ -34,7 +34,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ClassInheritanceHandler extends AbstractHandler { - private static final Logger LOG = Log.getLogger(ClassInheritanceHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(ClassInheritanceHandler.class); Map> _inheritanceMap; @@ -64,7 +64,7 @@ public class ClassInheritanceHandler extends AbstractHandler } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to handle {}", classInfo, e); } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ContainerInitializerAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ContainerInitializerAnnotationHandler.java index c84910344ad..9206347b659 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ContainerInitializerAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ContainerInitializerAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java index 0c5fc003aba..72604d851ce 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -24,28 +24,22 @@ import javax.servlet.Servlet; import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler; import org.eclipse.jetty.security.ConstraintAware; import org.eclipse.jetty.security.ConstraintSecurityHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DeclaresRolesAnnotationHandler */ public class DeclareRolesAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - private static final Logger LOG = Log.getLogger(DeclareRolesAnnotationHandler.class); - - protected WebAppContext _context; + private static final Logger LOG = LoggerFactory.getLogger(DeclareRolesAnnotationHandler.class); public DeclareRolesAnnotationHandler(WebAppContext context) { - super(false); - _context = context; + super(false, context); } - /** - * @see org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler#doHandle(java.lang.Class) - */ @Override public void doHandle(Class clazz) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java index 920a807c44a..d2035a9419e 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -33,18 +33,12 @@ import org.eclipse.jetty.webapp.WebAppContext; */ public class MultiPartConfigAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - protected WebAppContext _context; - public MultiPartConfigAnnotationHandler(WebAppContext context) { //TODO verify that MultipartConfig is not inheritable - super(false); - _context = context; + super(false, context); } - /** - * @see org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler#doHandle(java.lang.Class) - */ @Override public void doHandle(Class clazz) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java index 36d6e21b7c2..5ed8e24cae1 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PostConstructAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -31,12 +31,9 @@ import org.eclipse.jetty.webapp.WebAppContext; public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - protected WebAppContext _context; - public PostConstructAnnotationHandler(WebAppContext wac) { - super(true); - _context = wac; + super(true, wac); } @Override diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java index 9639cc4e113..2ebe1190d14 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/PreDestroyAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -31,12 +31,9 @@ import org.eclipse.jetty.webapp.WebAppContext; public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - WebAppContext _context; - public PreDestroyAnnotationHandler(WebAppContext wac) { - super(true); - _context = wac; + super(true, wac); } @Override diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java index e0b43bda07c..0a0896fa527 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -32,28 +32,25 @@ import javax.naming.NamingException; import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler; import org.eclipse.jetty.plus.annotation.Injection; import org.eclipse.jetty.plus.annotation.InjectionCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.MetaData; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - private static final Logger LOG = Log.getLogger(ResourceAnnotationHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(ResourceAnnotationHandler.class); protected static final List> ENV_ENTRY_TYPES = Arrays.asList(new Class[] - { - String.class, Character.class, Integer.class, Boolean.class, Double.class, Byte.class, Short.class, Long.class, - Float.class - }); - - protected WebAppContext _context; + { + String.class, Character.class, Integer.class, Boolean.class, Double.class, Byte.class, Short.class, Long.class, + Float.class + }); public ResourceAnnotationHandler(WebAppContext wac) { - super(true); - _context = wac; + super(true, wac); } /** @@ -101,7 +98,7 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH } catch (NamingException e) { - LOG.warn(e); + LOG.warn("Unable to bind name {} to {} from class {}", name, mappedName, clazz, e); } } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourcesAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourcesAnnotationHandler.java index 6428a7dded7..e5bb183e5e9 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourcesAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourcesAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -23,20 +23,17 @@ import javax.annotation.Resources; import javax.naming.NamingException; import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ResourcesAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - private static final Logger LOG = Log.getLogger(ResourcesAnnotationHandler.class); - - protected WebAppContext _wac; + private static final Logger LOG = LoggerFactory.getLogger(ResourcesAnnotationHandler.class); public ResourcesAnnotationHandler(WebAppContext wac) { - super(true); - _wac = wac; + super(true, wac); } @Override @@ -64,13 +61,13 @@ public class ResourcesAnnotationHandler extends AbstractIntrospectableAnnotation { //TODO don't ignore the shareable, auth etc etc - if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name, mappedName)) - if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name, mappedName)) + if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName)) + if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName)) LOG.warn("Skipping Resources(Resource) annotation on " + clazz.getName() + " for name " + name + ": No resource bound at " + (mappedName == null ? name : mappedName)); } catch (NamingException e) { - LOG.warn(e); + LOG.warn("Unable to bind {} to {}", name, mappedName, e); } } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java index 200325d9dbb..0f8be1166a9 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -23,24 +23,21 @@ import javax.servlet.Servlet; import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler; import org.eclipse.jetty.plus.annotation.RunAsCollection; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.Descriptor; import org.eclipse.jetty.webapp.MetaData; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - private static final Logger LOG = Log.getLogger(RunAsAnnotationHandler.class); - - protected WebAppContext _context; + private static final Logger LOG = LoggerFactory.getLogger(RunAsAnnotationHandler.class); public RunAsAnnotationHandler(WebAppContext wac) { //Introspect only the given class for a RunAs annotation, as it is a class level annotation, //and according to Common Annotation Spec p2-6 a class-level annotation is not inheritable. - super(false); - _context = wac; + super(false, wac); } @Override diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java index 315beb45ee3..9a96f0f003f 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -23,9 +23,9 @@ import java.util.List; import org.eclipse.jetty.plus.annotation.ContainerInitializer; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ServletContainerInitializersStarter @@ -35,7 +35,7 @@ import org.eclipse.jetty.webapp.WebAppContext; */ public class ServletContainerInitializersStarter extends AbstractLifeCycle implements ServletContextHandler.ServletContainerInitializerCaller { - private static final Logger LOG = Log.getLogger(ServletContainerInitializersStarter.class); + private static final Logger LOG = LoggerFactory.getLogger(ServletContainerInitializersStarter.class); WebAppContext _context; public ServletContainerInitializersStarter(WebAppContext context) @@ -43,11 +43,6 @@ public class ServletContainerInitializersStarter extends AbstractLifeCycle imple _context = context; } - /** - * Call the doStart method of the ServletContainerInitializers - * - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override public void doStart() { @@ -65,7 +60,7 @@ public class ServletContainerInitializersStarter extends AbstractLifeCycle imple } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to call startup on {}", i, e); throw new RuntimeException(e); } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java index 5d8f739dcc1..328d51d505a 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -31,10 +31,10 @@ import org.eclipse.jetty.security.ConstraintMapping; import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletMapping; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ServletSecurityAnnotationHandler @@ -55,19 +55,13 @@ import org.eclipse.jetty.webapp.WebAppContext; */ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnnotationHandler { - private static final Logger LOG = Log.getLogger(ServletSecurityAnnotationHandler.class); - - private WebAppContext _context; + private static final Logger LOG = LoggerFactory.getLogger(ServletSecurityAnnotationHandler.class); public ServletSecurityAnnotationHandler(WebAppContext wac) { - super(false); - _context = wac; + super(false, wac); } - /** - * @see org.eclipse.jetty.annotations.AnnotationIntrospector.IntrospectableAnnotationHandler#handle(java.lang.Class) - */ @Override public void doHandle(Class clazz) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java index 2813a3aabfc..fbe62081d65 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -29,20 +29,20 @@ import org.eclipse.jetty.http.pathmap.ServletPathSpec; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.servlet.Source; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.DiscoveredAnnotation; import org.eclipse.jetty.webapp.MetaData; import org.eclipse.jetty.webapp.Origin; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * WebFilterAnnotation */ public class WebFilterAnnotation extends DiscoveredAnnotation { - private static final Logger LOG = Log.getLogger(WebFilterAnnotation.class); + private static final Logger LOG = LoggerFactory.getLogger(WebFilterAnnotation.class); public WebFilterAnnotation(WebAppContext context, String className) { @@ -54,9 +54,6 @@ public class WebFilterAnnotation extends DiscoveredAnnotation super(context, className, resource); } - /** - * @see DiscoveredAnnotation#apply() - */ @Override public void apply() { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java index c9b52069c87..3cae920d061 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -21,16 +21,16 @@ package org.eclipse.jetty.annotations; import org.eclipse.jetty.annotations.AnnotationParser.ClassInfo; import org.eclipse.jetty.annotations.AnnotationParser.FieldInfo; import org.eclipse.jetty.annotations.AnnotationParser.MethodInfo; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * WebFilterAnnotationHandler */ public class WebFilterAnnotationHandler extends AbstractDiscoverableAnnotationHandler { - private static final Logger LOG = Log.getLogger(WebFilterAnnotationHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(WebFilterAnnotationHandler.class); public WebFilterAnnotationHandler(WebAppContext context) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java index f00341d0e1b..a3bb6e7a692 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -29,20 +29,20 @@ import javax.servlet.http.HttpSessionListener; import org.eclipse.jetty.servlet.ListenerHolder; import org.eclipse.jetty.servlet.Source; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.DiscoveredAnnotation; import org.eclipse.jetty.webapp.MetaData; import org.eclipse.jetty.webapp.Origin; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * WebListenerAnnotation */ public class WebListenerAnnotation extends DiscoveredAnnotation { - private static final Logger LOG = Log.getLogger(WebListenerAnnotation.class); + private static final Logger LOG = LoggerFactory.getLogger(WebListenerAnnotation.class); public WebListenerAnnotation(WebAppContext context, String className) { @@ -54,9 +54,6 @@ public class WebListenerAnnotation extends DiscoveredAnnotation super(context, className, resource); } - /** - * @see DiscoveredAnnotation#apply() - */ @Override public void apply() { @@ -91,7 +88,7 @@ public class WebListenerAnnotation extends DiscoveredAnnotation } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to add listener {}", clazz, e); } } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java index b091ef70fb7..919f3a834b0 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -21,13 +21,13 @@ package org.eclipse.jetty.annotations; import org.eclipse.jetty.annotations.AnnotationParser.ClassInfo; import org.eclipse.jetty.annotations.AnnotationParser.FieldInfo; import org.eclipse.jetty.annotations.AnnotationParser.MethodInfo; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WebListenerAnnotationHandler extends AbstractDiscoverableAnnotationHandler { - private static final Logger LOG = Log.getLogger(WebListenerAnnotationHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(WebListenerAnnotationHandler.class); public WebListenerAnnotationHandler(WebAppContext context) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java index 5af95057f1f..c310dfc0036 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -32,20 +32,20 @@ import org.eclipse.jetty.servlet.ServletMapping; import org.eclipse.jetty.servlet.Source; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.DiscoveredAnnotation; import org.eclipse.jetty.webapp.MetaData; import org.eclipse.jetty.webapp.Origin; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * WebServletAnnotation */ public class WebServletAnnotation extends DiscoveredAnnotation { - private static final Logger LOG = Log.getLogger(WebServletAnnotation.class); + private static final Logger LOG = LoggerFactory.getLogger(WebServletAnnotation.class); public WebServletAnnotation(WebAppContext context, String className) { @@ -57,9 +57,6 @@ public class WebServletAnnotation extends DiscoveredAnnotation super(context, className, resource); } - /** - * @see DiscoveredAnnotation#apply() - */ @Override public void apply() { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java index fa8cfc046cc..f3c02f38d87 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -21,9 +21,9 @@ package org.eclipse.jetty.annotations; import org.eclipse.jetty.annotations.AnnotationParser.ClassInfo; import org.eclipse.jetty.annotations.AnnotationParser.FieldInfo; import org.eclipse.jetty.annotations.AnnotationParser.MethodInfo; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * WebServletAnnotationHandler @@ -32,7 +32,7 @@ import org.eclipse.jetty.webapp.WebAppContext; */ public class WebServletAnnotationHandler extends AbstractDiscoverableAnnotationHandler { - private static final Logger LOG = Log.getLogger(WebServletAnnotationHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(WebServletAnnotationHandler.class); public WebServletAnnotationHandler(WebAppContext context) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/package-info.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/package-info.java index 036baf0b38e..5caa2f00486 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/package-info.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-annotations/src/test/java/org/acme/ClassOne.java b/jetty-annotations/src/test/java/org/acme/ClassOne.java index 41c94e75d5f..49dcb92e6d6 100644 --- a/jetty-annotations/src/test/java/org/acme/ClassOne.java +++ b/jetty-annotations/src/test/java/org/acme/ClassOne.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.acme; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassA.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassA.java index 26691a57395..4538f3182f1 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassA.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassA.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassB.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassB.java index 3e8b6947bee..afd3f3e187a 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassB.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassB.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/FilterC.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/FilterC.java index 3bf14f2d794..5f92e44c9a3 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/FilterC.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/FilterC.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -38,7 +38,7 @@ import javax.servlet.http.HttpSession; @WebFilter(filterName = "CFilter", dispatcherTypes = {DispatcherType.REQUEST}, urlPatterns = {"/*"}, initParams = { @WebInitParam(name = "a", value = "99") -}, asyncSupported = false) + }, asyncSupported = false) @RunAs("admin") public class FilterC implements Filter { diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/InterfaceD.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/InterfaceD.java index 5ad229843a1..14c0f9a0b3d 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/InterfaceD.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/InterfaceD.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ListenerC.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ListenerC.java index b2c426f7988..ff0a47ffa49 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ListenerC.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ListenerC.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Multi.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Multi.java index 353a982fc57..8ac8a5a3246 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Multi.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Multi.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Sample.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Sample.java index b46be21ece5..1288733ad4a 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Sample.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/Sample.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletC.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletC.java index fe7d9816bf7..ffc714e3f3c 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletC.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletC.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -38,7 +38,7 @@ import javax.servlet.http.HttpServletResponse; @DeclareRoles({"alice"}) @WebServlet(urlPatterns = {"/foo/*", "/bah/*"}, name = "CServlet", initParams = { @WebInitParam(name = "x", value = "y") -}, loadOnStartup = 2, asyncSupported = false) + }, loadOnStartup = 2, asyncSupported = false) @MultipartConfig(fileSizeThreshold = 1000, maxFileSize = 2000, maxRequestSize = 3000) @RunAs("admin") @ServletSecurity(value = @HttpConstraint(rolesAllowed = {"fred", "bill", "dorothy"}), httpMethodConstraints = { diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletD.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletD.java index 436a8ca10e9..b36ae08a565 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletD.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletD.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -24,8 +24,8 @@ import javax.servlet.http.HttpServlet; @WebServlet(urlPatterns = {"/", "/bah/*"}, name = "DServlet", initParams = { @WebInitParam(name = "x", value = "y") -}, loadOnStartup = 1, asyncSupported = false) + }, loadOnStartup = 1, asyncSupported = false) public class ServletD extends HttpServlet { - + // no op } diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletE.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletE.java new file mode 100644 index 00000000000..5dc8a10b84f --- /dev/null +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletE.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.annotations; + +import javax.annotation.PreDestroy; +import javax.servlet.http.HttpServlet; + +public class ServletE extends HttpServlet +{ + @PreDestroy + public void preDestroy() + { + } +} diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java index e362019e55b..13753551f7c 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -21,7 +21,6 @@ package org.eclipse.jetty.annotations; import java.io.File; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.servlet.ServletContainerInitializer; @@ -30,9 +29,9 @@ import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.JAR; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.webapp.FragmentDescriptor; import org.eclipse.jetty.webapp.RelativeOrdering; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.WebDescriptor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -125,7 +124,7 @@ public class TestAnnotationConfiguration context25.setClassLoader(Thread.currentThread().getContextClassLoader()); context25.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE); context25.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, 0); - context25.getMetaData().setWebXml(Resource.newResource(web25)); + context25.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web25))); context25.getServletContext().setEffectiveMajorVersion(2); context25.getServletContext().setEffectiveMinorVersion(5); config25.configure(context25); @@ -138,7 +137,7 @@ public class TestAnnotationConfiguration context25b.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE); context25b.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, 0); context25b.setConfigurationDiscovered(true); - context25b.getMetaData().setWebXml(Resource.newResource(web25)); + context25b.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web25))); context25b.getServletContext().setEffectiveMajorVersion(2); context25b.getServletContext().setEffectiveMinorVersion(5); config25b.configure(context25b); @@ -150,7 +149,7 @@ public class TestAnnotationConfiguration context31.setClassLoader(Thread.currentThread().getContextClassLoader()); context31.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE); context31.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, 0); - context31.getMetaData().setWebXml(Resource.newResource(web31true)); + context31.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31true))); context31.getServletContext().setEffectiveMajorVersion(3); context31.getServletContext().setEffectiveMinorVersion(1); config31.configure(context31); @@ -162,7 +161,7 @@ public class TestAnnotationConfiguration context31b.setClassLoader(Thread.currentThread().getContextClassLoader()); context31b.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE); context31b.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, 0); - context31b.getMetaData().setWebXml(Resource.newResource(web31false)); + context31b.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31false))); context31b.getServletContext().setEffectiveMajorVersion(3); context31b.getServletContext().setEffectiveMinorVersion(1); config31b.configure(context31b); @@ -183,9 +182,9 @@ public class TestAnnotationConfiguration //test 3.1 webapp loads both server and app scis context.setClassLoader(webAppLoader); - context.getMetaData().addWebInfJar(Resource.newResource(testSciJar.toURI().toURL())); - context.getMetaData().setWebXml(Resource.newResource(web31true)); - context.getMetaData().setWebInfClassesDirs(classes); + context.getMetaData().addWebInfResource(Resource.newResource(testSciJar.toURI().toURL())); + context.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31true))); + context.getMetaData().setWebInfClassesResources(classes); context.getServletContext().setEffectiveMajorVersion(3); context.getServletContext().setEffectiveMinorVersion(1); scis = config.getNonExcludedInitializers(context); @@ -215,9 +214,9 @@ public class TestAnnotationConfiguration // test a 3.1 webapp with metadata-complete=false loads both server // and webapp scis context.setClassLoader(webAppLoader); - context.getMetaData().setWebXml(Resource.newResource(web31false)); - context.getMetaData().setWebInfClassesDirs(classes); - context.getMetaData().addWebInfJar(Resource.newResource(testSciJar.toURI().toURL())); + context.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31false))); + context.getMetaData().setWebInfClassesResources(classes); + context.getMetaData().addWebInfResource(Resource.newResource(testSciJar.toURI().toURL())); context.getServletContext().setEffectiveMajorVersion(3); context.getServletContext().setEffectiveMinorVersion(1); scis = config.getNonExcludedInitializers(context); @@ -260,12 +259,12 @@ public class TestAnnotationConfiguration WebAppContext context = new WebAppContext(); List scis; context.setClassLoader(orderedLoader); - context.getMetaData().setWebXml(Resource.newResource(web31true)); + context.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31true))); RelativeOrdering ordering = new RelativeOrdering(context.getMetaData()); context.getMetaData().setOrdering(ordering); - context.getMetaData().addWebInfJar(Resource.newResource(orderedFragmentJar.toURI().toURL())); - context.getMetaData().addWebInfJar(Resource.newResource(testSciJar.toURI().toURL())); - context.getMetaData().setWebInfClassesDirs(classes); + context.getMetaData().addWebInfResource(Resource.newResource(orderedFragmentJar.toURI().toURL())); + context.getMetaData().addWebInfResource(Resource.newResource(testSciJar.toURI().toURL())); + context.getMetaData().setWebInfClassesResources(classes); context.getMetaData().orderFragments(); context.getServletContext().setEffectiveMajorVersion(3); context.getServletContext().setEffectiveMinorVersion(1); @@ -295,9 +294,9 @@ public class TestAnnotationConfiguration WebAppContext context = new WebAppContext(); List scis; context.setClassLoader(webAppLoader); - context.getMetaData().setWebXml(Resource.newResource(web25)); - context.getMetaData().setWebInfClassesDirs(classes); - context.getMetaData().addWebInfJar(Resource.newResource(testSciJar.toURI().toURL())); + context.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web25))); + context.getMetaData().setWebInfClassesResources(classes); + context.getMetaData().addWebInfResource(Resource.newResource(testSciJar.toURI().toURL())); context.getServletContext().setEffectiveMajorVersion(2); context.getServletContext().setEffectiveMinorVersion(5); scis = config.getNonExcludedInitializers(context); @@ -332,9 +331,9 @@ public class TestAnnotationConfiguration List scis; context.setConfigurationDiscovered(true); context.setClassLoader(webAppLoader); - context.getMetaData().setWebXml(Resource.newResource(web25)); - context.getMetaData().setWebInfClassesDirs(classes); - context.getMetaData().addWebInfJar(Resource.newResource(testSciJar.toURI().toURL())); + context.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web25))); + context.getMetaData().setWebInfClassesResources(classes); + context.getMetaData().addWebInfResource(Resource.newResource(testSciJar.toURI().toURL())); context.getServletContext().setEffectiveMajorVersion(2); context.getServletContext().setEffectiveMinorVersion(5); scis = config.getNonExcludedInitializers(context); @@ -349,24 +348,4 @@ public class TestAnnotationConfiguration Thread.currentThread().setContextClassLoader(old); } } - - @Test - public void testGetFragmentFromJar() throws Exception - { - String dir = MavenTestingUtils.getTargetTestingDir("getFragmentFromJar").getAbsolutePath(); - File file = new File(dir); - file = new File(file.getCanonicalPath()); - URL url = file.toURI().toURL(); - - Resource jar1 = Resource.newResource(url + "file.jar"); - - AnnotationConfiguration config = new AnnotationConfiguration(); - WebAppContext wac = new WebAppContext(); - - List frags = new ArrayList(); - frags.add(new FragmentDescriptor(Resource.newResource("jar:" + url + "file.jar!/fooa.props"))); - frags.add(new FragmentDescriptor(Resource.newResource("jar:" + url + "file2.jar!/foob.props"))); - - assertNotNull(config.getFragmentFromJar(jar1, frags)); - } } diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationDecorator.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationDecorator.java new file mode 100644 index 00000000000..ba6fd673b2e --- /dev/null +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationDecorator.java @@ -0,0 +1,127 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.annotations; + +import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlet.Source; +import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.util.resource.EmptyResource; +import org.eclipse.jetty.webapp.MetaData; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.WebDescriptor; +import org.eclipse.jetty.xml.XmlParser; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestAnnotationDecorator +{ + public class TestWebDescriptor extends WebDescriptor + { + public TestWebDescriptor(MetaData.Complete metadata) + { + super(EmptyResource.INSTANCE); + _metaDataComplete = metadata; + } + + @Override + public void parse(XmlParser parser) throws Exception + { + } + + @Override + public void processVersion() + { + } + + @Override + public void processOrdering() + { + } + + @Override + public void processDistributable() + { + } + + @Override + public int getMajorVersion() + { + return 4; + } + + @Override + public int getMinorVersion() + { + return 0; + } + } + + @Test + public void testAnnotationDecorator() throws Exception + { + assertThrows(NullPointerException.class, () -> + { + new AnnotationDecorator(null); + }); + + WebAppContext context = new WebAppContext(); + AnnotationDecorator decorator = new AnnotationDecorator(context); + ServletE servlet = new ServletE(); + //test without BaseHolder metadata + decorator.decorate(servlet); + LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION); + assertNotNull(callbacks); + assertFalse(callbacks.getPreDestroyCallbacks().isEmpty()); + + //reset + context.removeAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION); + + //test with BaseHolder metadata, should not introspect with metdata-complete==true + context.getMetaData().setWebDescriptor(new TestWebDescriptor(MetaData.Complete.True)); + assertTrue(context.getMetaData().isMetaDataComplete()); + ServletHolder holder = new ServletHolder(new Source(Source.Origin.DESCRIPTOR, "")); + holder.setHeldClass(ServletE.class); + context.getServletHandler().addServlet(holder); + DecoratedObjectFactory.associateInfo(holder); + decorator = new AnnotationDecorator(context); + decorator.decorate(servlet); + DecoratedObjectFactory.disassociateInfo(); + callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION); + assertNull(callbacks); + + //reset + context.removeAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION); + + //test with BaseHolder metadata, should introspect with metadata-complete==false + context.getMetaData().setWebDescriptor(new TestWebDescriptor(MetaData.Complete.False)); + DecoratedObjectFactory.associateInfo(holder); + decorator = new AnnotationDecorator(context); + decorator.decorate(servlet); + DecoratedObjectFactory.disassociateInfo(); + callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION); + assertNotNull(callbacks); + assertFalse(callbacks.getPreDestroyCallbacks().isEmpty()); + } +} diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java index ac5f8551f0f..b00edce6a4d 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationInheritance.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationIntrospector.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationIntrospector.java new file mode 100644 index 00000000000..6458daa52bd --- /dev/null +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationIntrospector.java @@ -0,0 +1,98 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.annotations; + +import java.io.File; + +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlet.Source; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.webapp.FragmentDescriptor; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.WebDescriptor; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestAnnotationIntrospector +{ + @Test + public void testIsIntrospectable() throws Exception + { + try (StacklessLogging ignore = new StacklessLogging(AnnotationIntrospector.class)) + { + WebAppContext wac = new WebAppContext(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); + //can't introspect nothing + assertFalse(introspector.isIntrospectable(null, null)); + + //can introspect if no metadata to say otherwise + assertTrue(introspector.isIntrospectable(new Object(), null)); + + //can introspect if metdata isn't a BaseHolder + assertTrue(introspector.isIntrospectable(new Object(), new Object())); + + //an EMBEDDED sourced servlet can be introspected + ServletHolder holder = new ServletHolder(); + holder.setHeldClass(ServletE.class); + assertTrue(introspector.isIntrospectable(new ServletE(), holder)); + + //a JAVAX API sourced servlet can be introspected + holder = new ServletHolder(Source.JAVAX_API); + holder.setHeldClass(ServletE.class); + assertTrue(introspector.isIntrospectable(new ServletE(), holder)); + + //an ANNOTATION sourced servlet can be introspected + holder = new ServletHolder(new Source(Source.Origin.ANNOTATION, ServletE.class.getName())); + holder.setHeldClass(ServletE.class); + assertTrue(introspector.isIntrospectable(new ServletE(), holder)); + + //a DESCRIPTOR sourced servlet can be introspected if web.xml metdata-complete==false + File file = MavenTestingUtils.getTestResourceFile("web31false.xml"); + Resource resource = Resource.newResource(file); + wac.getMetaData().setWebDescriptor(new WebDescriptor(resource)); + holder = new ServletHolder(new Source(Source.Origin.DESCRIPTOR, resource.toString())); + assertTrue(introspector.isIntrospectable(new ServletE(), holder)); + + //a DESCRIPTOR sourced servlet can be introspected if web-fragment.xml medata-complete==false && web.xml metadata-complete==false + file = MavenTestingUtils.getTestResourceFile("web-fragment4false.xml"); + resource = Resource.newResource(file); + wac.getMetaData().addFragmentDescriptor(Resource.newResource(file.getParentFile()), new FragmentDescriptor(resource)); + holder = new ServletHolder(new Source(Source.Origin.DESCRIPTOR, resource.toString())); + assertTrue(introspector.isIntrospectable(new ServletE(), holder)); + + //a DESCRIPTOR sourced servlet cannot be introspected if web-fragment.xml medata-complete==true (&& web.xml metadata-complete==false) + file = MavenTestingUtils.getTestResourceFile("web-fragment4true.xml"); + resource = Resource.newResource(file); + wac.getMetaData().addFragmentDescriptor(Resource.newResource(file.getParentFile()), new FragmentDescriptor(resource)); + holder = new ServletHolder(new Source(Source.Origin.DESCRIPTOR, resource.toString())); + assertFalse(introspector.isIntrospectable(new ServletE(), holder)); + + //a DESCRIPTOR sourced servlet cannot be introspected if web.xml medata-complete==true + file = MavenTestingUtils.getTestResourceFile("web31true.xml"); + resource = Resource.newResource(file); + wac.getMetaData().setWebDescriptor(new WebDescriptor(resource)); + holder = new ServletHolder(new Source(Source.Origin.DESCRIPTOR, resource.toString())); + assertFalse(introspector.isIntrospectable(new ServletE(), holder)); + } + } +} diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java index b27d1ed67dc..7b762992730 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -220,7 +220,7 @@ public class TestAnnotationParser } @Test - public void testJep238MultiReleaseInJar_JDK10() throws Exception + public void testJep238MultiReleaseInJarJDK10() throws Exception { File jdk10Jar = MavenTestingUtils.getTestResourceFile("jdk10/multirelease-10.jar"); AnnotationParser parser = new AnnotationParser(); diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java index 73c73ed4031..1daf3cd6366 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestSecurityAnnotationConversions.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; @@ -63,16 +63,14 @@ public class TestSecurityAnnotationConversions @ServletSecurity(value = @HttpConstraint(value = EmptyRoleSemantic.PERMIT, transportGuarantee = TransportGuarantee.CONFIDENTIAL, rolesAllowed = { "tom", "dick", "harry" - }), httpMethodConstraints = - {@HttpMethodConstraint(value = "GET")}) + }), httpMethodConstraints = {@HttpMethodConstraint(value = "GET")}) public static class Method1Servlet extends HttpServlet { } @ServletSecurity(value = @HttpConstraint(value = EmptyRoleSemantic.PERMIT, transportGuarantee = TransportGuarantee.CONFIDENTIAL, rolesAllowed = { "tom", "dick", "harry" - }), httpMethodConstraints = - {@HttpMethodConstraint(value = "GET", transportGuarantee = TransportGuarantee.CONFIDENTIAL)}) + }), httpMethodConstraints = {@HttpMethodConstraint(value = "GET", transportGuarantee = TransportGuarantee.CONFIDENTIAL)}) public static class Method2Servlet extends HttpServlet { } @@ -91,7 +89,7 @@ public class TestSecurityAnnotationConversions //Assume we found 1 servlet with a @HttpConstraint with value=EmptyRoleSemantic.DENY security annotation ServletSecurityAnnotationHandler annotationHandler = new ServletSecurityAnnotationHandler(wac); - AnnotationIntrospector introspector = new AnnotationIntrospector(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); introspector.registerHandler(annotationHandler); //set up the expected outcomes: @@ -110,7 +108,7 @@ public class TestSecurityAnnotationConversions expectedMappings[1].setConstraint(expectedConstraint); expectedMappings[1].setPathSpec("*.foo"); - introspector.introspect(DenyServlet.class); + introspector.introspect(new DenyServlet(), null); compareResults(expectedMappings, ((ConstraintAware)wac.getSecurityHandler()).getConstraintMappings()); } @@ -124,15 +122,15 @@ public class TestSecurityAnnotationConversions }); ServletSecurityAnnotationHandler annotationHandler = new ServletSecurityAnnotationHandler(wac); - AnnotationIntrospector introspector = new AnnotationIntrospector(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); introspector.registerHandler(annotationHandler); //set up the expected outcomes - no constraints at all as per Servlet Spec 3.1 pg 129 //1 ConstraintMapping per ServletMapping pathSpec ConstraintMapping[] expectedMappings = new ConstraintMapping[]{}; - - introspector.introspect(PermitServlet.class); + PermitServlet permit = new PermitServlet(); + introspector.introspect(permit, null); compareResults(expectedMappings, ((ConstraintAware)wac.getSecurityHandler()).getConstraintMappings()); } @@ -148,7 +146,7 @@ public class TestSecurityAnnotationConversions }); ServletSecurityAnnotationHandler annotationHandler = new ServletSecurityAnnotationHandler(wac); - AnnotationIntrospector introspector = new AnnotationIntrospector(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); introspector.registerHandler(annotationHandler); //set up the expected outcomes:compareResults @@ -166,8 +164,7 @@ public class TestSecurityAnnotationConversions expectedMappings[1] = new ConstraintMapping(); expectedMappings[1].setConstraint(expectedConstraint); expectedMappings[1].setPathSpec("*.foo"); - - introspector.introspect(RolesServlet.class); + introspector.introspect(new RolesServlet(), null); compareResults(expectedMappings, ((ConstraintAware)wac.getSecurityHandler()).getConstraintMappings()); } @@ -175,7 +172,7 @@ public class TestSecurityAnnotationConversions public void testMethodAnnotation() throws Exception { //ServletSecurity annotation with HttpConstraint of TransportGuarantee.CONFIDENTIAL, and a list of rolesAllowed, and - //a HttpMethodConstraint for GET method that permits all and has TransportGuarantee.NONE (ie is default) + //an HttpMethodConstraint for GET method that permits all and has TransportGuarantee.NONE (ie is default) WebAppContext wac = makeWebAppContext(Method1Servlet.class.getCanonicalName(), "method1Servlet", new String[]{ "/foo/*", "*.foo" @@ -213,10 +210,10 @@ public class TestSecurityAnnotationConversions expectedMappings[3].setPathSpec("*.foo"); expectedMappings[3].setMethod("GET"); - AnnotationIntrospector introspector = new AnnotationIntrospector(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); ServletSecurityAnnotationHandler annotationHandler = new ServletSecurityAnnotationHandler(wac); introspector.registerHandler(annotationHandler); - introspector.introspect(Method1Servlet.class); + introspector.introspect(new Method1Servlet(), null); compareResults(expectedMappings, ((ConstraintAware)wac.getSecurityHandler()).getConstraintMappings()); } @@ -229,7 +226,7 @@ public class TestSecurityAnnotationConversions "/foo/*", "*.foo" }); - AnnotationIntrospector introspector = new AnnotationIntrospector(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); ServletSecurityAnnotationHandler annotationHandler = new ServletSecurityAnnotationHandler(wac); introspector.registerHandler(annotationHandler); @@ -265,7 +262,7 @@ public class TestSecurityAnnotationConversions expectedMappings[3].setPathSpec("*.foo"); expectedMappings[3].setMethod("GET"); - introspector.introspect(Method2Servlet.class); + introspector.introspect(new Method2Servlet(), null); compareResults(expectedMappings, ((ConstraintAware)wac.getSecurityHandler()).getConstraintMappings()); } diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java index c8032f14b80..c8e5d29516f 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestServletAnnotations.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceA.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceA.java index e5b91f72ce8..d291ee5c960 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceA.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceA.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations.resources; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceB.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceB.java index d8fc21ff2e9..36b6b279a81 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceB.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/ResourceB.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations.resources; diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java index 88e19a9a32a..ef98e8ff419 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/resources/TestResourceAnnotations.java @@ -1,25 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.annotations.resources; import java.lang.reflect.Field; -import java.util.List; import java.util.Set; import javax.naming.Context; import javax.naming.InitialContext; @@ -74,11 +73,14 @@ public class TestResourceAnnotations new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false); new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false); - AnnotationIntrospector parser = new AnnotationIntrospector(); + AnnotationIntrospector parser = new AnnotationIntrospector(wac); ResourceAnnotationHandler handler = new ResourceAnnotationHandler(wac); parser.registerHandler(handler); - parser.introspect(ResourceA.class); - parser.introspect(ResourceB.class); + + ResourceA resourceA = new ResourceA(); + ResourceB resourceB = new ResourceB(); + parser.introspect(resourceA, null); + parser.introspect(resourceB, null); //processing classA should give us these jndi name bindings: // java:comp/env/myf @@ -156,11 +158,13 @@ public class TestResourceAnnotations new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false); new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false); - AnnotationIntrospector introspector = new AnnotationIntrospector(); + AnnotationIntrospector introspector = new AnnotationIntrospector(wac); ResourcesAnnotationHandler handler = new ResourcesAnnotationHandler(wac); introspector.registerHandler(handler); - introspector.introspect(ResourceA.class); - introspector.introspect(ResourceB.class); + ResourceA resourceA = new ResourceA(); + ResourceB resourceB = new ResourceB(); + introspector.introspect(resourceA, null); + introspector.introspect(resourceB, null); assertEquals(objA, env.lookup("peach")); assertEquals(objB, env.lookup("pear")); diff --git a/jetty-annotations/src/test/resources/jetty-logging.properties b/jetty-annotations/src/test/resources/jetty-logging.properties index fff7f1b3e39..9c9f7d77b57 100644 --- a/jetty-annotations/src/test/resources/jetty-logging.properties +++ b/jetty-annotations/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.annotations.LEVEL=DEBUG diff --git a/jetty-annotations/src/test/resources/web-fragment4false.xml b/jetty-annotations/src/test/resources/web-fragment4false.xml new file mode 100644 index 00000000000..7d44223765b --- /dev/null +++ b/jetty-annotations/src/test/resources/web-fragment4false.xml @@ -0,0 +1,7 @@ + + + + ardvaark + + + diff --git a/jetty-annotations/src/test/resources/web-fragment4true.xml b/jetty-annotations/src/test/resources/web-fragment4true.xml new file mode 100644 index 00000000000..cf84dc66bde --- /dev/null +++ b/jetty-annotations/src/test/resources/web-fragment4true.xml @@ -0,0 +1,9 @@ + + + + + badger + + + + diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index b66fb07eaeb..c4d79c713f4 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -78,5 +78,14 @@ jetty-annotations ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntMetaInfConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntMetaInfConfiguration.java index 0a45505d434..655130be6f3 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntMetaInfConfiguration.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntMetaInfConfiguration.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java index e46b30941f1..bf6b391cda3 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java @@ -27,7 +27,6 @@ import java.security.CodeSource; import java.security.PermissionCollection; import java.util.ArrayList; import java.util.Enumeration; -import java.util.EventListener; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -50,21 +49,21 @@ import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletMapping; import org.eclipse.jetty.servlet.Source; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Extension of WebAppContext to allow configuration via Ant environment. */ public class AntWebAppContext extends WebAppContext { - private static final Logger LOG = Log.getLogger(WebAppContext.class); + private static final Logger LOG = LoggerFactory.getLogger(WebAppContext.class); public static final String DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN = ".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$|.*/.*jstl[^/]*\\.jar$|.*/.*jsf-impl-[^/]*\\.jar$|.*/.*javax.faces-[^/]*\\.jar$|.*/.*myfaces-impl-[^/]*\\.jar$"; @@ -177,7 +176,7 @@ public class AntWebAppContext extends WebAppContext } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } } @@ -564,9 +563,6 @@ public class AntWebAppContext extends WebAppContext } } - /** - * - */ @Override public void doStart() { @@ -615,9 +611,9 @@ public class AntWebAppContext extends WebAppContext TaskLog.logWithTimestamp("Stopping web application " + this); Thread.currentThread().sleep(500L); super.doStop(); - //remove all filters, servlets and listeners. They will be recreated - //either via application of a context xml file or web.xml or annotation or servlet api - setEventListeners(new EventListener[0]); + // remove all filters and servlets. They will be recreated + // either via application of a context xml file or web.xml or annotation or servlet api. + // Event listeners are reset in ContextHandler.doStop() getServletHandler().setFilters(new FilterHolder[0]); getServletHandler().setFilterMappings(new FilterMapping[0]); getServletHandler().setServlets(new ServletHolder[0]); diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java index c1c224d3a95..57f8e7837a4 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java index a097c78282d..56d5460b25f 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java @@ -21,10 +21,10 @@ package org.eclipse.jetty.ant; import java.io.File; import java.util.List; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.WebXmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This configuration object provides additional way to inject application @@ -34,7 +34,7 @@ import org.eclipse.jetty.webapp.WebXmlConfiguration; */ public class AntWebXmlConfiguration extends WebXmlConfiguration { - private static final Logger LOG = Log.getLogger(WebXmlConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(WebXmlConfiguration.class); /** * List of classpath files. diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyStopTask.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyStopTask.java index 9478bf8c9a8..0a71fc67611 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyStopTask.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyStopTask.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -49,9 +49,6 @@ public class JettyStopTask extends Task TaskLog.setTask(this); } - /** - * @see org.apache.tools.ant.Task#execute() - */ @Override public void execute() throws BuildException { diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java index feb95456da1..16460fe7c18 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java @@ -254,9 +254,6 @@ public class ServerProxyImpl implements ServerProxy this.tempDirectory = tempDirectory; } - /** - * @see org.eclipse.jetty.ant.utils.ServerProxy#start() - */ @Override public void start() { @@ -299,9 +296,6 @@ public class ServerProxyImpl implements ServerProxy } } - /** - * @see org.eclipse.jetty.ant.utils.ServerProxy#getProxiedObject() - */ @Override public Object getProxiedObject() { diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/package-info.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/package-info.java index 8e76918c4fb..d5ec4c617b3 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/package-info.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/package-info.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java index 2bec15d8ebe..f44bc1ae793 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java index 516ed1109df..206945f16e1 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connector.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connector.java index 47ce2c2fd18..fba5fe96d90 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connector.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connector.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/package-info.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/package-info.java index 74366b9abc5..6981b8d46f4 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/package-info.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/package-info.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/package-info.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/package-info.java index 21a25fd4331..f5f470eadea 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/package-info.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/package-info.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java b/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java index a0f20d40c01..e85eb7307f8 100644 --- a/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java +++ b/jetty-ant/src/test/java/org/eclipse/jetty/ant/AntBuild.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -171,7 +171,8 @@ public class AntBuild Matcher mat = pat.getMatcher(line); if (mat.find()) { - int num = 0, count = mat.groupCount(); + int num = 0; + int count = mat.groupCount(); String[] match = new String[count]; while (num++ < count) { diff --git a/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java b/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java index 2d6124cfa6c..97802be1f7f 100644 --- a/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java +++ b/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 64844bddf11..4b073072d34 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -284,6 +284,11 @@ jetty-security 10.0.0-SNAPSHOT + + org.eclipse.jetty + jetty-openid + 10.0.0-SNAPSHOT + org.eclipse.jetty jetty-server @@ -336,37 +341,37 @@ org.eclipse.jetty.websocket - javax-websocket-client + websocket-javax-client 10.0.0-SNAPSHOT org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server 10.0.0-SNAPSHOT org.eclipse.jetty.websocket - javax-websocket-common + websocket-javax-common 10.0.0-SNAPSHOT org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api 10.0.0-SNAPSHOT org.eclipse.jetty.websocket - jetty-websocket-client + websocket-jetty-client 10.0.0-SNAPSHOT org.eclipse.jetty.websocket - jetty-websocket-common + websocket-jetty-common 10.0.0-SNAPSHOT org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server 10.0.0-SNAPSHOT diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index 6255cf83849..faf645f8f0e 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -5,14 +5,43 @@ 10.0.0-SNAPSHOT 4.0.0 - org.eclipse.jetty.cdi - cdi-2 - Jetty :: CDI 2 + org.eclipse.jetty + jetty-cdi + Jetty :: CDI http://www.eclipse.org/jetty jar - ${project.groupId}.cdi2 + ${project.groupId}.cdi + + + org.eclipse.jetty + jetty-util + ${project.version} + compile + + + org.eclipse.jetty + jetty-webapp + ${project.version} + compile + + + org.eclipse.jetty + jetty-annotations + ${project.version} + compile + + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + + diff --git a/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml b/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml new file mode 100644 index 00000000000..484c19df26f --- /dev/null +++ b/jetty-cdi/src/main/config/etc/cdi/jetty-cdi.xml @@ -0,0 +1,8 @@ + + + + + org.eclipse.jetty.cdi + + + diff --git a/jetty-cdi/src/main/config/modules/cdi-decorate.mod b/jetty-cdi/src/main/config/modules/cdi-decorate.mod new file mode 100644 index 00000000000..0468a6a08a4 --- /dev/null +++ b/jetty-cdi/src/main/config/modules/cdi-decorate.mod @@ -0,0 +1,18 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configures Jetty to use the "CdiDecoratingListener" as the default +CDI integration mode that allows a webapp to register it's own CDI +decorator. + +[tag] +cdi + +[provides] +cdi-mode + +[depend] +cdi + +[ini] +jetty.cdi.mode=CdiDecoratingListener diff --git a/jetty-cdi/src/main/config/modules/cdi-spi.mod b/jetty-cdi/src/main/config/modules/cdi-spi.mod new file mode 100644 index 00000000000..5002bf967db --- /dev/null +++ b/jetty-cdi/src/main/config/modules/cdi-spi.mod @@ -0,0 +1,17 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configures Jetty to use the "CdiSpiDecorator" that calls the CDI SPI +as the default CDI integration mode. + +[tag] +cdi + +[provides] +cdi-mode + +[depend] +cdi + +[ini] +jetty.cdi.mode=CdiSpiDecorator diff --git a/jetty-cdi/src/main/config/modules/cdi.mod b/jetty-cdi/src/main/config/modules/cdi.mod index 749aafe4ff6..8542f0693ec 100644 --- a/jetty-cdi/src/main/config/modules/cdi.mod +++ b/jetty-cdi/src/main/config/modules/cdi.mod @@ -1,7 +1,34 @@ # DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Jetty setup to support Weld/CDI2 with WELD inside the webapp +Support for CDI inside the webapp. +This module does not provide CDI, but configures jetty to support various +integration modes with a CDI implementation on the webapp classpath. +CDI integration modes can be selected per webapp with the "org.eclipse.jetty.cdi" +init parameter or defaults to the mode set by the "org.eclipse.jetty.cdi" server +attribute (which is initialised from the "jetty.cdi.mode" start property). +Supported modes are: +CdiSpiDecorator - Jetty will call the CDI SPI within the webapp to decorate + objects (default). +CdiDecoratingLister - The webapp may register a decorator on the context attribute + "org.eclipse.jetty.cdi.decorator". + +[tag] +cdi + +[provides] +cdi [depend] -cdi2 +deploy + +[xml] +etc/cdi/jetty-cdi.xml + +[lib] +lib/jetty-cdi-${jetty.version}.jar +lib/apache-jsp/org.mortbay.jasper.apache-el-*.jar + +[ini] +jetty.webapp.addSystemClasses+=,org.eclipse.jetty.cdi.CdiServletContainerInitializer +jetty.webapp.addServerClasses+=,-org.eclipse.jetty.cdi.CdiServletContainerInitializer \ No newline at end of file diff --git a/jetty-cdi/src/main/config/modules/cdi2.mod b/jetty-cdi/src/main/config/modules/cdi2.mod deleted file mode 100644 index bd89103c0a9..00000000000 --- a/jetty-cdi/src/main/config/modules/cdi2.mod +++ /dev/null @@ -1,20 +0,0 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - -[description] -Jetty setup to support Weld/CDI2 with WELD inside the webapp - -[depend] -annotations - -[lib] -lib/apache-jsp/org.mortbay.jasper.apache-el-*.jar - -[ini] -jetty.webapp.addServerClasses+=,-org.eclipse.jetty.util.Decorator,-org.eclipse.jetty.util.DecoratedObjectFactory -jetty.webapp.addServerClasses+=,-org.eclipse.jetty.server.handler.ContextHandler.,-org.eclipse.jetty.server.handler.ContextHandler,-org.eclipse.jetty.servlet.ServletContextHandler - - -[license] -Weld is an open source project hosted on Github and released under the Apache 2.0 license. -http://weld.cdi-spec.org/ -http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiDecoratingListener.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiDecoratingListener.java new file mode 100644 index 00000000000..35720a0e580 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiDecoratingListener.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.cdi; + +import org.eclipse.jetty.servlet.DecoratingListener; +import org.eclipse.jetty.servlet.ServletContextHandler; + +/** + * A DecoratingListener that listens for "org.eclipse.jetty.cdi.decorator" + */ +class CdiDecoratingListener extends DecoratingListener +{ + public static final String MODE = "CdiDecoratingListener"; + public static final String ATTRIBUTE = "org.eclipse.jetty.cdi.decorator"; + + public CdiDecoratingListener(ServletContextHandler contextHandler) + { + super(contextHandler, ATTRIBUTE); + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiServletContainerInitializer.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiServletContainerInitializer.java new file mode 100644 index 00000000000..70f017f17a3 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiServletContainerInitializer.java @@ -0,0 +1,99 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.cdi; + +import java.util.Objects; +import java.util.Set; +import javax.servlet.ServletContainerInitializer; +import javax.servlet.ServletContext; + +import org.eclipse.jetty.annotations.AnnotationConfiguration; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.Loader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

A {@link ServletContainerInitializer} that introspects for a CDI API + * implementation within a web application and applies an integration + * mode if CDI is found. CDI integration modes can be selected per webapp with + * the "org.eclipse.jetty.cdi" init parameter or default to the mode set by the + * "org.eclipse.jetty.cdi" server attribute. Supported modes are:

+ *
+ *
CdiSpiDecorator
+ *
Jetty will call the CDI SPI within the webapp to decorate objects (default).
+ *
CdiDecoratingLister
+ *
The webapp may register a decorator on the context attribute + * "org.eclipse.jetty.cdi.decorator".
+ *
+ * + * @see AnnotationConfiguration.ServletContainerInitializerOrdering + */ +public class CdiServletContainerInitializer implements ServletContainerInitializer +{ + public static final String CDI_INTEGRATION_ATTRIBUTE = "org.eclipse.jetty.cdi"; + private static final Logger LOG = LoggerFactory.getLogger(CdiServletContainerInitializer.class); + + @Override + public void onStartup(Set> c, ServletContext ctx) + { + try + { + ServletContextHandler context = ServletContextHandler.getServletContextHandler(ctx); + Objects.requireNonNull(context); + + // Test if CDI is in the webapp by trying to load the CDI class. + ClassLoader loader = context.getClassLoader(); + if (loader == null) + Loader.loadClass("javax.enterprise.inject.spi.CDI"); + else + loader.loadClass("javax.enterprise.inject.spi.CDI"); + + String mode = ctx.getInitParameter(CDI_INTEGRATION_ATTRIBUTE); + if (mode == null) + { + mode = (String)context.getServer().getAttribute(CDI_INTEGRATION_ATTRIBUTE); + if (mode == null) + mode = CdiSpiDecorator.MODE; + } + + switch (mode) + { + case CdiSpiDecorator.MODE: + context.getObjectFactory().addDecorator(new CdiSpiDecorator(context)); + break; + + case CdiDecoratingListener.MODE: + context.addEventListener(new CdiDecoratingListener(context)); + break; + + default: + throw new IllegalStateException(mode); + } + + context.setAttribute(CDI_INTEGRATION_ATTRIBUTE, mode); + LOG.info(mode + " enabled in " + ctx); + } + catch (UnsupportedOperationException | ClassNotFoundException e) + { + if (LOG.isDebugEnabled()) + LOG.debug("CDI not found in " + ctx, e); + } + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiSpiDecorator.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiSpiDecorator.java new file mode 100644 index 00000000000..cd77cf513c6 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/CdiSpiDecorator.java @@ -0,0 +1,166 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.cdi; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.Decorator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A Decorator that invokes the CDI provider within a webapp to decorate objects created by + * the contexts {@link org.eclipse.jetty.util.DecoratedObjectFactory} + * (typically Listeners, Filters and Servlets). + * The CDI provider is invoked using {@link MethodHandle}s to avoid any CDI instance + * or dependencies within the server scope. The code invoked is equivalent to: + *
+ * public <T> T decorate(T o)
+ * {
+ *   BeanManager manager = CDI.current().getBeanManager();
+ *   manager.createInjectionTarget(manager.createAnnotatedType((Class<T>)o.getClass()))
+ *     .inject(o,manager.createCreationalContext(null));
+ *   return o;
+ * }
+ * 
+ */ +public class CdiSpiDecorator implements Decorator +{ + private static final Logger LOG = LoggerFactory.getLogger(CdiServletContainerInitializer.class); + public static final String MODE = "CdiSpiDecorator"; + + private final ServletContextHandler _context; + private final Map _decorated = new HashMap<>(); + + private final MethodHandle _current; + private final MethodHandle _getBeanManager; + private final MethodHandle _createAnnotatedType; + private final MethodHandle _createInjectionTarget; + private final MethodHandle _createCreationalContext; + private final MethodHandle _inject; + private final MethodHandle _dispose; + private final MethodHandle _release; + + public CdiSpiDecorator(ServletContextHandler context) throws UnsupportedOperationException + { + _context = context; + ClassLoader classLoader = _context.getClassLoader(); + + try + { + Class cdiClass = classLoader.loadClass("javax.enterprise.inject.spi.CDI"); + Class beanManagerClass = classLoader.loadClass("javax.enterprise.inject.spi.BeanManager"); + Class annotatedTypeClass = classLoader.loadClass("javax.enterprise.inject.spi.AnnotatedType"); + Class injectionTargetClass = classLoader.loadClass("javax.enterprise.inject.spi.InjectionTarget"); + Class creationalContextClass = classLoader.loadClass("javax.enterprise.context.spi.CreationalContext"); + Class contextualClass = classLoader.loadClass("javax.enterprise.context.spi.Contextual"); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + _current = lookup.findStatic(cdiClass, "current", MethodType.methodType(cdiClass)); + _getBeanManager = lookup.findVirtual(cdiClass, "getBeanManager", MethodType.methodType(beanManagerClass)); + _createAnnotatedType = lookup.findVirtual(beanManagerClass, "createAnnotatedType", MethodType.methodType(annotatedTypeClass, Class.class)); + _createInjectionTarget = lookup.findVirtual(beanManagerClass, "createInjectionTarget", MethodType.methodType(injectionTargetClass, annotatedTypeClass)); + _createCreationalContext = lookup.findVirtual(beanManagerClass, "createCreationalContext", MethodType.methodType(creationalContextClass, contextualClass)); + _inject = lookup.findVirtual(injectionTargetClass, "inject", MethodType.methodType(Void.TYPE, Object.class, creationalContextClass)); + _dispose = lookup.findVirtual(injectionTargetClass, "dispose", MethodType.methodType(Void.TYPE, Object.class)); + _release = lookup.findVirtual(creationalContextClass, "release", MethodType.methodType(Void.TYPE)); + } + catch (Exception e) + { + throw new UnsupportedOperationException(e); + } + } + + /** + * Decorate an object. + *

The signature of this method must match what is introspected for by the + * Jetty DecoratingListener class. It is invoked dynamically.

+ * + * @param o The object to be decorated + * @param The type of the object to be decorated + * @return The decorated object + */ + public T decorate(T o) + { + try + { + if (LOG.isDebugEnabled()) + LOG.debug("decorate {} in {}", o, _context); + + _decorated.put(o, new Decorated(o)); + } + catch (Throwable th) + { + LOG.warn("Unable to decorate " + o, th); + } + return o; + } + + /** + * Destroy a decorated object. + *

The signature of this method must match what is introspected for by the + * Jetty DecoratingListener class. It is invoked dynamically.

+ * + * @param o The object to be destroyed + */ + public void destroy(Object o) + { + try + { + Decorated decorated = _decorated.remove(o); + if (decorated != null) + decorated.destroy(o); + } + catch (Throwable th) + { + LOG.warn("Unable to destroy " + o, th); + } + } + + private class Decorated + { + private final Object _injectionTarget; + private final Object _creationalContext; + + Decorated(Object o) throws Throwable + { + // BeanManager manager = CDI.current().getBeanManager(); + Object manager = _getBeanManager.invoke(_current.invoke()); + // AnnotatedType annotatedType = manager.createAnnotatedType((Class)o.getClass()); + Object annotatedType = _createAnnotatedType.invoke(manager, o.getClass()); + // CreationalContext creationalContext = manager.createCreationalContext(null); + _creationalContext = _createCreationalContext.invoke(manager, null); + // InjectionTarget injectionTarget = manager.createInjectionTarget(); + _injectionTarget = _createInjectionTarget.invoke(manager, annotatedType); + // injectionTarget.inject(o, creationalContext); + _inject.invoke(_injectionTarget, o, _creationalContext); + } + + public void destroy(Object o) throws Throwable + { + _dispose.invoke(_injectionTarget, o); + _release.invoke(_creationalContext); + } + } +} diff --git a/jetty-cdi/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/jetty-cdi/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer new file mode 100644 index 00000000000..4e6d2237721 --- /dev/null +++ b/jetty-cdi/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer @@ -0,0 +1 @@ +org.eclipse.jetty.cdi.CdiServletContainerInitializer diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 67c8d231d5a..e859d380e22 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -9,17 +9,21 @@ jetty-client Jetty :: Asynchronous HTTP Client http://www.eclipse.org/jetty + ${project.groupId}.client target/test-policy + maven-surefire-plugin - @{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.client=jetty.servlet.api --add-modules java.security.jgss --add-modules jetty.servlet.api --add-modules org.eclipse.jetty.jmx --add-modules org.slf4j + @{argLine} ${jetty.surefire.argLine} + --add-modules java.security.jgss + --add-modules org.eclipse.jetty.jmx @@ -111,7 +115,6 @@ org.eclipse.jetty jetty-alpn-client ${project.version} - true
org.eclipse.jetty @@ -143,14 +146,20 @@ 1.1.1 test + - org.slf4j - slf4j-api + net.minidev + json-smart + 2.3 test org.slf4j - slf4j-simple + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl test diff --git a/jetty-client/src/main/config/modules/client.mod b/jetty-client/src/main/config/modules/client.mod index ccc1d50db83..4afc5bcb3d3 100644 --- a/jetty-client/src/main/config/modules/client.mod +++ b/jetty-client/src/main/config/modules/client.mod @@ -5,3 +5,4 @@ Adds the Jetty HTTP client to the server classpath. [lib] lib/jetty-client-${jetty.version}.jar +lib/jetty-alpn-client-${jetty.version}.jar diff --git a/jetty-client/src/main/java/module-info.java b/jetty-client/src/main/java/module-info.java index fcb2b0c2d7f..40005b81a79 100644 --- a/jetty-client/src/main/java/module-info.java +++ b/jetty-client/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.client @@ -26,14 +26,13 @@ module org.eclipse.jetty.client exports org.eclipse.jetty.client.proxy; exports org.eclipse.jetty.client.util; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires org.eclipse.jetty.alpn.client; + requires transitive org.eclipse.jetty.http; + requires org.slf4j; // Only required if using SPNEGO. requires static java.security.jgss; - // Only required if using the dynamic transport. - requires static org.eclipse.jetty.alpn.client; // Only required if using JMX. + requires static java.management; requires static org.eclipse.jetty.jmx; } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java index 1d4ebaec7e7..2ad7adc6b54 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -29,13 +29,13 @@ import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable { - private static final Logger LOG = Log.getLogger(AbstractConnectionPool.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractConnectionPool.class); private final AtomicBoolean closed = new AtomicBoolean(); @@ -68,7 +68,7 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable } @ManagedAttribute(value = "The number of pending connections", readonly = true) - public int getPendingCount() + public int getPendingConnectionCount() { return connections.getHi(); } @@ -146,6 +146,19 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable } } + @Override + public boolean accept(Connection connection) + { + while (true) + { + int count = connections.getLo(); + if (count >= maxConnections) + return false; + if (connections.compareAndSetLo(count, count + 1)) + return true; + } + } + protected abstract void onCreated(Connection connection); protected void proceed() diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java index 0c234daa160..129cdcb3748 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -72,7 +72,7 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC context.put(ClientConnector.CLIENT_CONNECTION_FACTORY_CONTEXT_KEY, destination.getClientConnectionFactory()); @SuppressWarnings("unchecked") Promise promise = (Promise)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY); - context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, new Promise.Wrapper<>(promise)); + context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, promise); connector.connect(address, context); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java index e5282e0fce9..7e9722160ef 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -24,13 +24,13 @@ import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject public abstract class AbstractHttpClientTransport extends ContainerLifeCycle implements HttpClientTransport { - protected static final Logger LOG = Log.getLogger(HttpClientTransport.class); + protected static final Logger LOG = LoggerFactory.getLogger(HttpClientTransport.class); private HttpClient client; private ConnectionPool.Factory factory; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java index a0d21e2d5fe..417d27d2e5c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java index 4f3d3a48fa7..4053bb89c54 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -40,13 +40,13 @@ import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.QuotedCSV; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class AuthenticationProtocolHandler implements ProtocolHandler { public static final int DEFAULT_MAX_CONTENT_LENGTH = 16 * 1024; - public static final Logger LOG = Log.getLogger(AuthenticationProtocolHandler.class); + public static final Logger LOG = LoggerFactory.getLogger(AuthenticationProtocolHandler.class); private final HttpClient client; private final int maxContentLength; private final ResponseNotifier notifier; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java index 7cd8a3088de..69845696840 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -52,6 +52,14 @@ public interface ConnectionPool extends Closeable */ Connection acquire(); + /** + *

Accepts the given connection to be managed by this ConnectionPool.

+ * + * @param connection the connection to accept + * @return whether the connection has been accepted + */ + boolean accept(Connection connection); + /** *

Returns the given connection, previously obtained via {@link #acquire()}, * back to this ConnectionPool.

@@ -70,11 +78,6 @@ public interface ConnectionPool extends Closeable */ boolean remove(Connection connection); - /** - * Closes this ConnectionPool. - * - * @see #isClosed() - */ @Override void close(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java index eb69c1d5734..43f26f2b080 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ContinueProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ContinueProtocolHandler.java index fde872d55ce..1ca229175b8 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ContinueProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ContinueProtocolHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java index bfccf42c6b3..73f4b1b734d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -37,14 +37,14 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Sweeper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject public class DuplexConnectionPool extends AbstractConnectionPool implements Sweeper.Sweepable { - private static final Logger LOG = Log.getLogger(DuplexConnectionPool.class); + private static final Logger LOG = LoggerFactory.getLogger(DuplexConnectionPool.class); private final ReentrantLock lock = new ReentrantLock(); private final Deque idleConnections; @@ -309,9 +309,10 @@ public class DuplexConnectionPool extends AbstractConnectionPool implements Swee unlock(); } - return String.format("%s@%x[c=%d/%d,a=%d,i=%d]", + return String.format("%s@%x[c=%d/%d/%d,a=%d,i=%d]", getClass().getSimpleName(), hashCode(), + getPendingConnectionCount(), getConnectionCount(), getMaxConnectionCount(), activeSize, diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java index 1fe94996a33..3650e9a851f 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -27,11 +27,6 @@ public class DuplexHttpDestination extends HttpDestination { public DuplexHttpDestination(HttpClient client, Origin origin) { - this(client, new Key(origin, null)); - } - - public DuplexHttpDestination(HttpClient client, Key key) - { - super(client, key); + super(client, origin); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java b/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java index 7699a98dad8..34cdbe64096 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java index 54122c17d9a..bdc02f24198 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java index a8699fba543..1867615b3ef 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java @@ -1,30 +1,30 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class HttpChannel { - protected static final Logger LOG = Log.getLogger(HttpChannel.class); + protected static final Logger LOG = LoggerFactory.getLogger(HttpChannel.class); private final HttpDestination _destination; private final TimeoutCompleteListener _totalTimeout; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index c53e8e66710..6ae5b0eb1cd 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -74,13 +74,13 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.ThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

HttpClient provides an efficient, asynchronous, non-blocking implementation @@ -122,9 +122,9 @@ import org.eclipse.jetty.util.thread.ThreadPool; public class HttpClient extends ContainerLifeCycle { public static final String USER_AGENT = "Jetty/" + Jetty.VERSION; - private static final Logger LOG = Log.getLogger(HttpClient.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpClient.class); - private final ConcurrentMap destinations = new ConcurrentHashMap<>(); + private final ConcurrentMap destinations = new ConcurrentHashMap<>(); private final ProtocolHandlers handlers = new ProtocolHandlers(); private final List requestListeners = new ArrayList<>(); private final Set decoderFactories = new ContentDecoderFactorySet(); @@ -150,6 +150,8 @@ public class HttpClient extends ContainerLifeCycle private String name = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()); private HttpCompliance httpCompliance = HttpCompliance.RFC7230; private String defaultRequestContentType = "application/octet-stream"; + private boolean useInputDirectByteBuffers = true; + private boolean useOutputDirectByteBuffers = true; /** * Creates a HttpClient instance that can perform HTTP/1.1 requests to non-TLS and TLS destinations. @@ -214,6 +216,7 @@ public class HttpClient extends ContainerLifeCycle handlers.put(new RedirectProtocolHandler(this)); handlers.put(new WWWAuthenticationProtocolHandler(this)); handlers.put(new ProxyAuthenticationProtocolHandler(this)); + handlers.put(new UpgradeProtocolHandler()); decoderFactories.add(new GZIPContentDecoder.Factory(byteBufferPool)); @@ -497,65 +500,47 @@ public class HttpClient extends ContainerLifeCycle return uri; } - /** - * Returns a {@link Destination} for the given scheme, host and port. - * Applications may use {@link Destination}s to create {@link Connection}s - * that will be outside HttpClient's pooling mechanism, to explicitly - * control the connection lifecycle (in particular their termination with - * {@link Connection#close()}). - * - * @param scheme the destination scheme - * @param host the destination host - * @param port the destination port - * @return the destination - * @see #getDestinations() - */ - public Destination getDestination(String scheme, String host, int port) + public Destination resolveDestination(Request request) { - Origin origin = createOrigin(scheme, host, port); - return resolveDestination(new HttpDestination.Key(origin, null)); + HttpClientTransport transport = getTransport(); + Origin origin = transport.newOrigin((HttpRequest)request); + HttpDestination destination = resolveDestination(origin); + if (LOG.isDebugEnabled()) + LOG.debug("Resolved {} for {}", destination, request); + return destination; } - private Origin createOrigin(String scheme, String host, int port) + public Origin createOrigin(HttpRequest request, Origin.Protocol protocol) { + String scheme = request.getScheme(); if (!HttpScheme.HTTP.is(scheme) && !HttpScheme.HTTPS.is(scheme) && !HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme)) throw new IllegalArgumentException("Invalid protocol " + scheme); - scheme = scheme.toLowerCase(Locale.ENGLISH); + String host = request.getHost(); host = host.toLowerCase(Locale.ENGLISH); + int port = request.getPort(); port = normalizePort(scheme, port); - - return new Origin(scheme, host, port); + return new Origin(scheme, host, port, request.getTag(), protocol); } - private HttpDestination resolveDestination(HttpDestination.Key key) + public HttpDestination resolveDestination(Origin origin) { - HttpDestination destination = destinations.get(key); - if (destination == null) + return destinations.computeIfAbsent(origin, o -> { - destination = getTransport().newHttpDestination(key); + HttpDestination destination = getTransport().newHttpDestination(o); // Start the destination before it's published to other threads. addManaged(destination); - HttpDestination existing = destinations.putIfAbsent(key, destination); - if (existing != null) - { - removeBean(destination); - destination = existing; - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Created {}", destination); - } - } - return destination; + if (LOG.isDebugEnabled()) + LOG.debug("Created {}", destination); + return destination; + }); } protected boolean removeDestination(HttpDestination destination) { removeBean(destination); - return destinations.remove(destination.getKey(), destination); + return destinations.remove(destination.getOrigin(), destination); } /** @@ -568,16 +553,7 @@ public class HttpClient extends ContainerLifeCycle protected void send(final HttpRequest request, List listeners) { - Origin origin = createOrigin(request.getScheme(), request.getHost(), request.getPort()); - HttpClientTransport transport = getTransport(); - HttpDestination.Key destinationKey = null; - if (transport instanceof HttpClientTransport.Dynamic) - destinationKey = ((HttpClientTransport.Dynamic)transport).newDestinationKey(request, origin); - if (destinationKey == null) - destinationKey = new HttpDestination.Key(origin, null); - if (LOG.isDebugEnabled()) - LOG.debug("Selected {} for {}", destinationKey, request); - HttpDestination destination = resolveDestination(destinationKey); + HttpDestination destination = (HttpDestination)resolveDestination(request); destination.send(request, listeners); } @@ -1090,6 +1066,40 @@ public class HttpClient extends ContainerLifeCycle this.defaultRequestContentType = contentType; } + /** + * @return whether to use direct ByteBuffers for reading + */ + @ManagedAttribute("Whether to use direct ByteBuffers for reading") + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + /** + * @param useInputDirectByteBuffers whether to use direct ByteBuffers for reading + */ + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + /** + * @return whether to use direct ByteBuffers for writing + */ + @ManagedAttribute("Whether to use direct ByteBuffers for writing") + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + /** + * @param useOutputDirectByteBuffers whether to use direct ByteBuffers for writing + */ + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + /** * @return the forward proxy configuration */ @@ -1128,14 +1138,16 @@ public class HttpClient extends ContainerLifeCycle return port == 80; } - static boolean isSchemeSecure(String scheme) + public static boolean isSchemeSecure(String scheme) { return HttpScheme.HTTPS.is(scheme) || HttpScheme.WSS.is(scheme); } - protected ClientConnectionFactory newSslClientConnectionFactory(ClientConnectionFactory connectionFactory) + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) { - return new SslClientConnectionFactory(getSslContextFactory(), getByteBufferPool(), getExecutor(), connectionFactory); + if (sslContextFactory == null) + sslContextFactory = getSslContextFactory(); + return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory); } private class ContentDecoderFactorySet implements Set diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClientTransport.java index 68aa5772fdc..5e772605494 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClientTransport.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClientTransport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -28,7 +28,7 @@ import org.eclipse.jetty.io.ClientConnectionFactory; * in order to plug-in a different transport for {@link HttpClient}. *

* While the {@link HttpClient} APIs define the HTTP semantic (request, response, headers, etc.) - * how a HTTP exchange is carried over the network depends on implementations of this class. + * how an HTTP exchange is carried over the network depends on implementations of this class. *

* The default implementation uses the HTTP protocol to carry over the network the HTTP exchange, * but the HTTP exchange may also be carried using the FCGI protocol, the HTTP/2 protocol or, @@ -50,16 +50,24 @@ public interface HttpClientTransport extends ClientConnectionFactory */ public void setHttpClient(HttpClient client); + /** + * Creates a new Origin with the given request. + * + * @param request the request that triggers the creation of the Origin + * @return an Origin that identifies a destination + */ + public Origin newOrigin(HttpRequest request); + /** * Creates a new, transport-specific, {@link HttpDestination} object. *

* {@link HttpDestination} controls the destination-connection cardinality: protocols like * HTTP have 1-N cardinality, while multiplexed protocols like HTTP/2 have a 1-1 cardinality. * - * @param key the destination key + * @param origin the destination origin * @return a new, transport-specific, {@link HttpDestination} object */ - public HttpDestination newHttpDestination(HttpDestination.Key key); + public HttpDestination newHttpDestination(Origin origin); /** * Establishes a physical connection to the given {@code address}. @@ -78,20 +86,4 @@ public interface HttpClientTransport extends ClientConnectionFactory * @param factory the factory for ConnectionPool instances */ public void setConnectionPoolFactory(ConnectionPool.Factory factory); - - /** - * Specifies whether a {@link HttpClientTransport} is dynamic. - */ - @FunctionalInterface - public interface Dynamic - { - /** - * Creates a new Key with the given request and origin. - * - * @param request the request that triggers the creation of the Key - * @param origin the origin of the server for the request - * @return a Key that identifies a destination - */ - public HttpDestination.Key newDestinationKey(HttpRequest request, Origin origin); - } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java index 53cb43a7430..cb6cc8f844c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -34,12 +34,12 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.util.HttpCookieStore; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class HttpConnection implements IConnection { - private static final Logger LOG = Log.getLogger(HttpConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpConnection.class); private final HttpDestination destination; private int idleTimeoutGuard; @@ -123,10 +123,16 @@ public abstract class HttpConnection implements IConnection protected void normalizeRequest(Request request) { - final HttpVersion version = request.getVersion(); - final HttpFields headers = request.getHeaders(); - final ContentProvider content = request.getContent(); - final ProxyConfiguration.Proxy proxy = destination.getProxy(); + boolean normalized = ((HttpRequest)request).normalized(); + if (LOG.isDebugEnabled()) + LOG.debug("Normalizing {} {}", !normalized, request); + if (normalized) + return; + + HttpVersion version = request.getVersion(); + HttpFields headers = request.getHeaders(); + ContentProvider content = request.getContent(); + ProxyConfiguration.Proxy proxy = destination.getProxy(); // Make sure the path is there String path = request.getPath(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java index efb5e983e4d..dc9bf42b7e9 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -26,13 +26,14 @@ import java.util.Iterator; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.IO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * {@link HttpContent} is a stateful, linear representation of the request content provided * by a {@link ContentProvider} that can be traversed one-way to obtain content buffers to - * send to a HTTP server. + * send to an HTTP server. *

* {@link HttpContent} offers the notion of a one-way cursor to traverse the content. * The cursor starts in a virtual "before" position and can be advanced using {@link #advance()} @@ -65,7 +66,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HttpContent implements Callback, Closeable { - private static final Logger LOG = Log.getLogger(HttpContent.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpContent.class); private static final ByteBuffer AFTER = ByteBuffer.allocate(0); private static final ByteBuffer CLOSE = ByteBuffer.allocate(0); @@ -218,15 +219,8 @@ public class HttpContent implements Callback, Closeable @Override public void close() { - try - { - if (iterator instanceof Closeable) - ((Closeable)iterator).close(); - } - catch (Throwable x) - { - LOG.ignore(x); - } + if (iterator instanceof Closeable) + IO.close((Closeable)iterator); } @Override diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContentResponse.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContentResponse.java index 2a1aec0cc4b..471f6e5f03e 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContentResponse.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContentResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java index d1151d27b63..1eddf461326 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -25,12 +25,12 @@ import java.util.concurrent.ConcurrentLinkedDeque; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.util.AttributesMap; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpConversation extends AttributesMap { - private static final Logger LOG = Log.getLogger(HttpConversation.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpConversation.class); private final Deque exchanges = new ConcurrentLinkedDeque<>(); private volatile List listeners; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java index 06e300173f6..05527fde9c8 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -23,25 +23,20 @@ import java.io.IOException; import java.nio.channels.AsynchronousCloseException; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.Queue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Function; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; -import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.CyclicTimeout; -import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.HostPort; @@ -51,18 +46,19 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.Sweeper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject -public class HttpDestination extends ContainerLifeCycle implements Destination, Closeable, Callback, Dumpable +public abstract class HttpDestination extends ContainerLifeCycle implements Destination, Closeable, Callback, Dumpable { - protected static final Logger LOG = Log.getLogger(HttpDestination.class); + protected static final Logger LOG = LoggerFactory.getLogger(HttpDestination.class); private final HttpClient client; - private final Key key; + private final Origin origin; private final Queue exchanges; private final RequestNotifier requestNotifier; private final ResponseNotifier responseNotifier; @@ -72,15 +68,10 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, private final TimeoutTask timeout; private ConnectionPool connectionPool; - public HttpDestination(HttpClient client, Key key) - { - this(client, key, Function.identity()); - } - - public HttpDestination(HttpClient client, Key key, Function factoryFn) + public HttpDestination(HttpClient client, Origin origin) { this.client = client; - this.key = key; + this.origin = origin; this.exchanges = newExchangeQueue(client); @@ -95,27 +86,28 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, hostField = new HttpField(HttpHeader.HOST, host); ProxyConfiguration proxyConfig = client.getProxyConfiguration(); - this.proxy = proxyConfig.match(getOrigin()); - - this.connectionFactory = factoryFn.apply(createClientConnectionFactory()); - } - - private ClientConnectionFactory createClientConnectionFactory() - { - ProxyConfiguration.Proxy proxy = getProxy(); - ClientConnectionFactory connectionFactory = getHttpClient().getTransport(); + proxy = proxyConfig.match(origin); + ClientConnectionFactory connectionFactory = client.getTransport(); if (proxy != null) { connectionFactory = proxy.newClientConnectionFactory(connectionFactory); if (proxy.isSecure()) - connectionFactory = newSslClientConnectionFactory(connectionFactory); + connectionFactory = newSslClientConnectionFactory(proxy.getSslContextFactory(), connectionFactory); } else { if (isSecure()) - connectionFactory = newSslClientConnectionFactory(connectionFactory); + connectionFactory = newSslClientConnectionFactory(null, connectionFactory); } - return connectionFactory; + Object tag = origin.getTag(); + if (tag instanceof ClientConnectionFactory.Decorator) + connectionFactory = ((ClientConnectionFactory.Decorator)tag).apply(connectionFactory); + this.connectionFactory = connectionFactory; + } + + public void accept(Connection connection) + { + connectionPool.accept(connection); } @Override @@ -149,9 +141,9 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, return new BlockingArrayQueue<>(client.getMaxRequestsQueuedPerDestination()); } - protected ClientConnectionFactory newSslClientConnectionFactory(ClientConnectionFactory connectionFactory) + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) { - return client.newSslClientConnectionFactory(connectionFactory); + return client.newSslClientConnectionFactory(sslContextFactory, connectionFactory); } public boolean isSecure() @@ -164,14 +156,9 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, return client; } - public Key getKey() - { - return key; - } - public Origin getOrigin() { - return key.origin; + return origin; } public Queue getHttpExchanges() @@ -329,10 +316,10 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, } } - public boolean process(final Connection connection) + public boolean process(Connection connection) { HttpClient client = getHttpClient(); - final HttpExchange exchange = getHttpExchanges().poll(); + HttpExchange exchange = getHttpExchanges().poll(); if (LOG.isDebugEnabled()) LOG.debug("Processing exchange {} on {} of {}", exchange, connection, this); if (exchange == null) @@ -349,7 +336,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, } else { - final Request request = exchange.getRequest(); + Request request = exchange.getRequest(); Throwable cause = request.getAbortCause(); if (cause != null) { @@ -365,21 +352,30 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, } else { - SendFailure result = ((IConnection)connection).send(exchange); + SendFailure result = send((IConnection)connection, exchange); if (result != null) { if (LOG.isDebugEnabled()) LOG.debug("Send failed {} for {}", result, exchange); if (result.retry) + { + // Resend this exchange, likely on another connection, + // and return false to avoid to re-enter this method. send(exchange); - else - request.abort(result.failure); + return false; + } + request.abort(result.failure); } } return getHttpExchanges().peek() != null; } } + protected SendFailure send(IConnection connection, HttpExchange exchange) + { + return connection.send(exchange); + } + @Override public void newConnection(Promise promise) { @@ -498,7 +494,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, public String asString() { - return getKey().asString(); + return getOrigin().asString(); } @Override @@ -506,7 +502,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, { return String.format("%s[%s]@%x%s,queue=%d,pool=%s", HttpDestination.class.getSimpleName(), - asString(), + getOrigin(), hashCode(), proxy == null ? "" : "(via " + proxy + ")", exchanges.size(), @@ -519,166 +515,6 @@ public class HttpDestination extends ContainerLifeCycle implements Destination, void setMaxRequestsPerConnection(int maxRequestsPerConnection); } - /** - *

Class that groups the elements that uniquely identify a destination.

- *

The elements are an {@link Origin}, a {@link Protocol} and an opaque - * string that further distinguishes destinations that have the same origin - * and protocol.

- *

In general it is possible that, for the same origin, the server can - * speak different protocols (for example, clear-text HTTP/1.1 and clear-text - * HTTP/2), so the {@link Protocol} makes that distinction.

- *

Furthermore, it may be desirable to have different destinations for - * the same origin and protocol (for example, when using the PROXY protocol - * in a reverse proxy server, you want to be able to map the client ip:port - * to the destination {@code kind}, so that all the connections to the server - * associated to that destination can specify the PROXY protocol bytes for - * that particular client connection.

- */ - public static class Key - { - private final Origin origin; - private final Protocol protocol; - private final String kind; - - /** - * Creates a Key with the given origin and protocol and a {@code null} kind. - * - * @param origin the origin - * @param protocol the protocol - */ - public Key(Origin origin, Protocol protocol) - { - this(origin, protocol, null); - } - - /** - * Creates a Key with the given origin and protocol and kind. - * - * @param origin the origin - * @param protocol the protocol - * @param kind the opaque kind - */ - public Key(Origin origin, Protocol protocol, String kind) - { - this.origin = origin; - this.protocol = protocol; - this.kind = kind; - } - - public Origin getOrigin() - { - return origin; - } - - public Protocol getProtocol() - { - return protocol; - } - - public String getKind() - { - return kind; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (obj == null || getClass() != obj.getClass()) - return false; - Key that = (Key)obj; - return origin.equals(that.origin) && - Objects.equals(protocol, that.protocol) && - Objects.equals(kind, that.kind); - } - - @Override - public int hashCode() - { - return Objects.hash(origin, protocol, kind); - } - - public String asString() - { - return String.format("%s|%s,kind=%s", - origin.asString(), - protocol == null ? "null" : protocol.asString(), - kind); - } - - @Override - public String toString() - { - return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), asString()); - } - } - - /** - *

The representation of a network protocol.

- *

A network protocol may have multiple protocol names - * associated to it, for example {@code ["h2", "h2-17", "h2-16"]}.

- *

A Protocol is then rendered into a {@link ClientConnectionFactory} - * chain, for example in - * {@link HttpClientTransportDynamic#newConnection(EndPoint, Map)}.

- */ - public static class Protocol - { - private final List protocols; - private final boolean negotiate; - - /** - * Creates a Protocol with the given list of protocol names - * and whether it should negotiate the protocol. - * - * @param protocols the protocol names - * @param negotiate whether the protocol should be negotiated - */ - public Protocol(List protocols, boolean negotiate) - { - this.protocols = protocols; - this.negotiate = negotiate; - } - - public List getProtocols() - { - return protocols; - } - - public boolean isNegotiate() - { - return negotiate; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (obj == null || getClass() != obj.getClass()) - return false; - Protocol that = (Protocol)obj; - return protocols.equals(that.protocols) && negotiate == that.negotiate; - } - - @Override - public int hashCode() - { - return Objects.hash(protocols, negotiate); - } - - public String asString() - { - return String.format("proto=%s,nego=%b", protocols, negotiate); - } - - @Override - public String toString() - { - return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), asString()); - } - } - /** * This class enforces the total timeout for exchanges that are still in the queue. * The total timeout for exchanges that are not in the destination queue is enforced diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java index 74d66ffd797..1a743f496f9 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -22,12 +22,12 @@ import java.util.List; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpExchange { - private static final Logger LOG = Log.getLogger(HttpExchange.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpExchange.class); private final HttpDestination destination; private final HttpRequest request; @@ -50,6 +50,11 @@ public class HttpExchange conversation.updateResponseListeners(null); } + public HttpDestination getHttpDestination() + { + return destination; + } + public HttpConversation getConversation() { return request.getConversation(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java index 07511ff3c5b..64a2812a024 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java @@ -1,47 +1,50 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; import java.io.IOException; +import java.net.InetSocketAddress; import java.net.URI; +import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; +import java.util.Objects; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; +import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpProxy extends ProxyConfiguration.Proxy { - private static final Logger LOG = Log.getLogger(HttpProxy.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpProxy.class); public HttpProxy(String host, int port) { @@ -50,7 +53,27 @@ public class HttpProxy extends ProxyConfiguration.Proxy public HttpProxy(Origin.Address address, boolean secure) { - super(address, secure); + this(address, secure, null, new Origin.Protocol(List.of("http/1.1"), false)); + } + + public HttpProxy(Origin.Address address, boolean secure, Origin.Protocol protocol) + { + this(address, secure, null, Objects.requireNonNull(protocol)); + } + + public HttpProxy(Origin.Address address, SslContextFactory.Client sslContextFactory) + { + this(address, true, sslContextFactory, new Origin.Protocol(List.of("http/1.1"), false)); + } + + public HttpProxy(Origin.Address address, SslContextFactory.Client sslContextFactory, Origin.Protocol protocol) + { + this(address, true, sslContextFactory, Objects.requireNonNull(protocol)); + } + + private HttpProxy(Origin.Address address, boolean secure, SslContextFactory.Client sslContextFactory, Origin.Protocol protocol) + { + super(address, secure, sslContextFactory, Objects.requireNonNull(protocol)); } @Override @@ -62,8 +85,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy @Override public URI getURI() { - String scheme = isSecure() ? HttpScheme.HTTPS.asString() : HttpScheme.HTTP.asString(); - return URI.create(new Origin(scheme, getAddress()).asString()); + return URI.create(getOrigin().asString()); } private class HttpProxyClientConnectionFactory implements ClientConnectionFactory @@ -79,33 +101,26 @@ public class HttpProxy extends ProxyConfiguration.Proxy public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); - SslContextFactory sslContextFactory = destination.getHttpClient().getSslContextFactory(); - if (destination.isSecure()) + Origin.Protocol serverProtocol = destination.getOrigin().getProtocol(); + boolean sameProtocol = proxySpeaksServerProtocol(serverProtocol); + if (destination.isSecure() || !sameProtocol) { - if (sslContextFactory != null) + @SuppressWarnings("unchecked") + Promise promise = (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); + Promise wrapped = promise; + if (promise instanceof Promise.Wrapper) + wrapped = ((Promise.Wrapper)promise).unwrap(); + if (wrapped instanceof TunnelPromise) { - @SuppressWarnings("unchecked") - Promise promise = (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); - Promise wrapped = promise; - if (promise instanceof Promise.Wrapper) - wrapped = ((Promise.Wrapper)promise).unwrap(); - if (wrapped instanceof TunnelPromise) - { - ((TunnelPromise)wrapped).setEndPoint(endPoint); - return connectionFactory.newConnection(endPoint, context); - } - else - { - // Replace the promise with the proxy promise that creates the tunnel to the server. - CreateTunnelPromise tunnelPromise = new CreateTunnelPromise(connectionFactory, endPoint, promise, context); - context.put(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY, tunnelPromise); - return connectionFactory.newConnection(endPoint, context); - } + // In case the server closes the tunnel (e.g. proxy authentication + // required: 407 + Connection: close), we will open another tunnel + // so we need to tell the promise about the new EndPoint. + ((TunnelPromise)wrapped).setEndPoint(endPoint); + return connectionFactory.newConnection(endPoint, context); } else { - throw new IOException("Cannot tunnel request, missing " + - SslContextFactory.class.getName() + " in " + HttpClient.class.getName()); + return newProxyConnection(endPoint, context); } } else @@ -113,6 +128,34 @@ public class HttpProxy extends ProxyConfiguration.Proxy return connectionFactory.newConnection(endPoint, context); } } + + private boolean proxySpeaksServerProtocol(Origin.Protocol serverProtocol) + { + return serverProtocol != null && getProtocol().getProtocols().stream().anyMatch(p -> serverProtocol.getProtocols().stream().anyMatch(p::equalsIgnoreCase)); + } + + private org.eclipse.jetty.io.Connection newProxyConnection(EndPoint endPoint, Map context) throws IOException + { + // Replace the promise with the proxy promise that creates the tunnel to the server. + @SuppressWarnings("unchecked") + Promise promise = (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); + CreateTunnelPromise tunnelPromise = new CreateTunnelPromise(connectionFactory, endPoint, promise, context); + context.put(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY, tunnelPromise); + + // Replace the destination with the proxy destination. + HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + HttpClient client = destination.getHttpClient(); + HttpDestination proxyDestination = client.resolveDestination(getOrigin()); + context.put(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY, proxyDestination); + try + { + return connectionFactory.newConnection(endPoint, context); + } + finally + { + context.put(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY, destination); + } + } } /** @@ -121,7 +164,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy * tunnel after the TCP connection is succeeded, and needs to notify * the nested promise when the tunnel is established (or failed).

*/ - private class CreateTunnelPromise implements Promise + private static class CreateTunnelPromise implements Promise { private final ClientConnectionFactory connectionFactory; private final EndPoint endPoint; @@ -139,6 +182,8 @@ public class HttpProxy extends ProxyConfiguration.Proxy @Override public void succeeded(Connection connection) { + // Replace the promise back with the original. + context.put(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY, promise); HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); tunnel(destination, connection); } @@ -154,61 +199,33 @@ public class HttpProxy extends ProxyConfiguration.Proxy String target = destination.getOrigin().getAddress().asString(); Origin.Address proxyAddress = destination.getConnectAddress(); HttpClient httpClient = destination.getHttpClient(); - long connectTimeout = httpClient.getConnectTimeout(); - Request connect = httpClient.newRequest(proxyAddress.getHost(), proxyAddress.getPort()) - .method(HttpMethod.CONNECT) - .path(target) - .header(HttpHeader.HOST, target) - .idleTimeout(2 * connectTimeout, TimeUnit.MILLISECONDS) - .timeout(connectTimeout, TimeUnit.MILLISECONDS); + Request connect = new TunnelRequest(httpClient, proxyAddress) + .method(HttpMethod.CONNECT) + .path(target) + .header(HttpHeader.HOST, target); ProxyConfiguration.Proxy proxy = destination.getProxy(); - if (proxy != null && proxy.isSecure()) + if (proxy.isSecure()) connect.scheme(HttpScheme.HTTPS.asString()); - final HttpConversation conversation = ((HttpRequest)connect).getConversation(); - conversation.setAttribute(EndPoint.class.getName(), endPoint); - connect.attribute(Connection.class.getName(), new ProxyConnection(destination, connection, promise)); - - connection.send(connect, result -> - { - // The EndPoint may have changed during the conversation, get the latest. - EndPoint endPoint = (EndPoint)conversation.getAttribute(EndPoint.class.getName()); - if (result.isSucceeded()) - { - Response response = result.getResponse(); - if (response.getStatus() == HttpStatus.OK_200) - { - tunnelSucceeded(endPoint); - } - else - { - HttpResponseException failure = new HttpResponseException("Unexpected " + response + - " for " + result.getRequest(), response); - tunnelFailed(endPoint, failure); - } - } - else - { - tunnelFailed(endPoint, result.getFailure()); - } - }); + connection.send(connect, new TunnelListener(connect)); } private void tunnelSucceeded(EndPoint endPoint) { try { - // Replace the promise back with the original - context.put(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY, promise); HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); - HttpClient client = destination.getHttpClient(); - ClientConnectionFactory sslConnectionFactory = client.newSslClientConnectionFactory(connectionFactory); - HttpConnectionOverHTTP oldConnection = (HttpConnectionOverHTTP)endPoint.getConnection(); - org.eclipse.jetty.io.Connection newConnection = sslConnectionFactory.newConnection(endPoint, context); - // Creating the connection will link the new Connection the EndPoint, - // but we need the old Connection linked for the upgrade to do its job. - endPoint.setConnection(oldConnection); + ClientConnectionFactory connectionFactory = this.connectionFactory; + if (destination.isSecure()) + { + // Don't want to do DNS resolution here. + InetSocketAddress address = InetSocketAddress.createUnresolved(destination.getHost(), destination.getPort()); + context.put(ClientConnector.REMOTE_SOCKET_ADDRESS_CONTEXT_KEY, address); + connectionFactory = destination.newSslClientConnectionFactory(null, connectionFactory); + } + var oldConnection = endPoint.getConnection(); + var newConnection = connectionFactory.newConnection(endPoint, context); endPoint.upgrade(newConnection); if (LOG.isDebugEnabled()) LOG.debug("HTTP tunnel established: {} over {}", oldConnection, newConnection); @@ -224,9 +241,43 @@ public class HttpProxy extends ProxyConfiguration.Proxy endPoint.close(); promise.failed(failure); } + + private class TunnelListener extends Response.Listener.Adapter + { + private final HttpConversation conversation; + + private TunnelListener(Request request) + { + this.conversation = ((HttpRequest)request).getConversation(); + } + + @Override + public void onHeaders(Response response) + { + // The EndPoint may have changed during the conversation, get the latest. + EndPoint endPoint = (EndPoint)conversation.getAttribute(EndPoint.class.getName()); + if (response.getStatus() == HttpStatus.OK_200) + { + tunnelSucceeded(endPoint); + } + else + { + HttpResponseException failure = new HttpResponseException("Unexpected " + response + + " for " + response.getRequest(), response); + tunnelFailed(endPoint, failure); + } + } + + @Override + public void onComplete(Result result) + { + if (result.isFailed()) + tunnelFailed(endPoint, result.getFailure()); + } + } } - private class ProxyConnection implements Connection + private static class ProxyConnection implements Connection { private final Destination destination; private final Connection connection; @@ -265,7 +316,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy } } - private class TunnelPromise implements Promise + private static class TunnelPromise implements Promise { private final Request request; private final Response.CompleteListener listener; @@ -296,4 +347,12 @@ public class HttpProxy extends ProxyConfiguration.Proxy conversation.setAttribute(EndPoint.class.getName(), endPoint); } } + + public static class TunnelRequest extends HttpRequest + { + private TunnelRequest(HttpClient client, Origin.Address address) + { + super(client, new HttpConversation(), URI.create("http://" + address.asString())); + } + } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java index 7646656649e..15a4047c4e7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -23,9 +23,14 @@ import java.net.URI; import java.nio.ByteBuffer; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.LongConsumer; +import java.util.function.LongUnaryOperator; import java.util.stream.Collectors; import org.eclipse.jetty.client.api.Response; @@ -35,10 +40,10 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingNestedCallback; +import org.eclipse.jetty.util.MathUtils; import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * {@link HttpReceiver} provides the abstract code to implement the various steps of the receive of HTTP responses. @@ -50,7 +55,7 @@ import org.eclipse.jetty.util.log.Logger; *
    *
  1. {@link #responseBegin(HttpExchange)}, when the HTTP response data containing the HTTP status code * is available
  2. - *
  3. {@link #responseHeader(HttpExchange, HttpField)}, when a HTTP field is available
  4. + *
  5. {@link #responseHeader(HttpExchange, HttpField)}, when an HTTP field is available
  6. *
  7. {@link #responseHeaders(HttpExchange)}, when all HTTP headers are available
  8. *
  9. {@link #responseContent(HttpExchange, ByteBuffer, Callback)}, when HTTP content is available
  10. *
  11. {@link #responseSuccess(HttpExchange)}, when the response is successful
  12. @@ -67,13 +72,15 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class HttpReceiver { - protected static final Logger LOG = Log.getLogger(HttpReceiver.class); + protected static final Logger LOG = LoggerFactory.getLogger(HttpReceiver.class); private final AtomicReference responseState = new AtomicReference<>(ResponseState.IDLE); private final HttpChannel channel; - private List contentListeners; - private ContentDecoder decoder; + private ContentListeners contentListeners; + private Decoder decoder; private Throwable failure; + private long demand; + private boolean stalled; protected HttpReceiver(HttpChannel channel) { @@ -85,6 +92,55 @@ public abstract class HttpReceiver return channel; } + void demand(long n) + { + if (n <= 0) + throw new IllegalArgumentException("Invalid demand " + n); + + boolean resume = false; + synchronized (this) + { + demand = MathUtils.cappedAdd(demand, n); + if (stalled) + { + stalled = false; + resume = true; + } + if (LOG.isDebugEnabled()) + LOG.debug("Response demand={}/{}, resume={}", n, demand, resume); + } + + if (resume) + { + if (decoder != null) + decoder.resume(); + else + receive(); + } + } + + protected long demand() + { + return demand(LongUnaryOperator.identity()); + } + + private long demand(LongUnaryOperator operator) + { + synchronized (this) + { + return demand = operator.applyAsLong(demand); + } + } + + protected boolean hasDemandOrStall() + { + synchronized (this) + { + stalled = demand <= 0; + return !stalled; + } + } + protected HttpExchange getHttpExchange() { return channel.getHttpExchange(); @@ -100,6 +156,10 @@ public abstract class HttpReceiver return responseState.get() == ResponseState.FAILURE; } + protected void receive() + { + } + /** * Method to be invoked when the response status code is available. *

    @@ -116,13 +176,12 @@ public abstract class HttpReceiver if (!updateResponseState(ResponseState.IDLE, ResponseState.TRANSIENT)) return false; - final HttpConversation conversation = exchange.getConversation(); - final HttpResponse response = exchange.getResponse(); + HttpConversation conversation = exchange.getConversation(); + HttpResponse response = exchange.getResponse(); // Probe the protocol handlers - final HttpDestination destination = getHttpDestination(); - final HttpClient client = destination.getHttpClient(); - final ProtocolHandler protocolHandler = client.findProtocolHandler(exchange.getRequest(), response); - + HttpDestination destination = getHttpDestination(); + HttpClient client = destination.getHttpClient(); + ProtocolHandler protocolHandler = client.findProtocolHandler(exchange.getRequest(), response); Response.Listener handlerListener = null; if (protocolHandler != null) { @@ -227,7 +286,7 @@ public abstract class HttpReceiver catch (IOException x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Unable to store cookies {} from {}", field, uri, x); } } @@ -241,23 +300,17 @@ public abstract class HttpReceiver */ protected boolean responseHeaders(HttpExchange exchange) { - out: while (true) { ResponseState current = responseState.get(); - switch (current) + if (current == ResponseState.BEGIN || current == ResponseState.HEADER) { - case BEGIN: - case HEADER: - { - if (updateResponseState(current, ResponseState.TRANSIENT)) - break out; + if (updateResponseState(current, ResponseState.TRANSIENT)) break; - } - default: - { - return false; - } + } + else + { + return false; } } @@ -267,29 +320,35 @@ public abstract class HttpReceiver ResponseNotifier notifier = getHttpDestination().getResponseNotifier(); List responseListeners = exchange.getConversation().getResponseListeners(); notifier.notifyHeaders(responseListeners, response); - contentListeners = responseListeners.stream() - .filter(Response.AsyncContentListener.class::isInstance) - .map(Response.AsyncContentListener.class::cast) - .collect(Collectors.toList()); + contentListeners = new ContentListeners(responseListeners); + contentListeners.notifyBeforeContent(response); - List contentEncodings = response.getHeaders().getCSV(HttpHeader.CONTENT_ENCODING.asString(), false); - if (contentEncodings != null && !contentEncodings.isEmpty()) + if (!contentListeners.isEmpty()) { - for (ContentDecoder.Factory factory : getHttpDestination().getHttpClient().getContentDecoderFactories()) + List contentEncodings = response.getHeaders().getCSV(HttpHeader.CONTENT_ENCODING.asString(), false); + if (contentEncodings != null && !contentEncodings.isEmpty()) { - for (String encoding : contentEncodings) + for (ContentDecoder.Factory factory : getHttpDestination().getHttpClient().getContentDecoderFactories()) { - if (factory.getEncoding().equalsIgnoreCase(encoding)) + for (String encoding : contentEncodings) { - this.decoder = factory.newContentDecoder(); - break; + if (factory.getEncoding().equalsIgnoreCase(encoding)) + { + decoder = new Decoder(response, factory.newContentDecoder()); + break; + } } } } } if (updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADERS)) - return true; + { + boolean hasDemand = hasDemandOrStall(); + if (LOG.isDebugEnabled()) + LOG.debug("Response headers {}, hasDemand={}", response, hasDemand); + return hasDemand; + } terminateResponse(exchange); return false; @@ -307,45 +366,83 @@ public abstract class HttpReceiver */ protected boolean responseContent(HttpExchange exchange, ByteBuffer buffer, Callback callback) { - out: while (true) { ResponseState current = responseState.get(); - switch (current) + if (current == ResponseState.HEADERS || current == ResponseState.CONTENT) { - case HEADERS: - case CONTENT: - { - if (updateResponseState(current, ResponseState.TRANSIENT)) - break out; + if (updateResponseState(current, ResponseState.TRANSIENT)) break; - } - default: - { - callback.failed(new IllegalStateException("Invalid response state " + current)); - return false; - } + } + else + { + callback.failed(new IllegalStateException("Invalid response state " + current)); + return false; } } - HttpResponse response = exchange.getResponse(); - if (LOG.isDebugEnabled()) - LOG.debug("Response content {}{}{}", response, System.lineSeparator(), BufferUtil.toDetailString(buffer)); - - ResponseNotifier notifier = getHttpDestination().getResponseNotifier(); - - ContentDecoder decoder = this.decoder; - if (decoder == null) + boolean proceed = true; + if (demand() <= 0) { - notifier.notifyContent(response, buffer, callback, contentListeners); + callback.failed(new IllegalStateException("No demand for response content")); + proceed = false; } - else + + HttpResponse response = exchange.getResponse(); + if (proceed) { - new Decoder(notifier, response, decoder, buffer, callback).iterate(); + if (LOG.isDebugEnabled()) + LOG.debug("Response content {}{}{}", response, System.lineSeparator(), BufferUtil.toDetailString(buffer)); + + ContentListeners listeners = this.contentListeners; + if (listeners != null) + { + if (listeners.isEmpty()) + { + callback.succeeded(); + } + else + { + Decoder decoder = this.decoder; + if (decoder == null) + { + listeners.notifyContent(response, buffer, callback); + } + else + { + try + { + proceed = decoder.decode(buffer, callback); + } + catch (Throwable x) + { + callback.failed(x); + proceed = false; + } + } + } + } + else + { + // May happen in case of concurrent abort. + proceed = false; + } } if (updateResponseState(ResponseState.TRANSIENT, ResponseState.CONTENT)) - return true; + { + if (proceed) + { + boolean hasDemand = hasDemandOrStall(); + if (LOG.isDebugEnabled()) + LOG.debug("Response content {}, hasDemand={}", response, hasDemand); + return hasDemand; + } + else + { + return false; + } + } terminateResponse(exchange); return false; @@ -386,8 +483,7 @@ public abstract class HttpReceiver // Mark atomically the response as terminated, with // respect to concurrency between request and response. - Result result = exchange.terminateResponse(); - terminateResponse(exchange, result); + terminateResponse(exchange); return true; } @@ -410,6 +506,9 @@ public abstract class HttpReceiver if (exchange == null) return false; + if (LOG.isDebugEnabled()) + LOG.debug("Response failure " + exchange.getResponse(), failure); + // Mark atomically the response as completed, with respect // to concurrency between response success and response failure. if (exchange.responseComplete(failure)) @@ -448,7 +547,7 @@ public abstract class HttpReceiver } /** - * Resets this {@link HttpReceiver} state. + * Resets the state of this HttpReceiver. *

    * Subclasses should override (but remember to call {@code super}) to reset their own state. *

    @@ -456,13 +555,11 @@ public abstract class HttpReceiver */ protected void reset() { - contentListeners = null; - destroyDecoder(decoder); - decoder = null; + cleanup(); } /** - * Disposes this {@link HttpReceiver} state. + * Disposes the state of this HttpReceiver. *

    * Subclasses should override (but remember to call {@code super}) to dispose their own state. *

    @@ -470,41 +567,32 @@ public abstract class HttpReceiver */ protected void dispose() { - destroyDecoder(decoder); - decoder = null; + cleanup(); } - private static void destroyDecoder(ContentDecoder decoder) + private void cleanup() { - if (decoder instanceof Destroyable) - { - ((Destroyable)decoder).destroy(); - } + contentListeners = null; + if (decoder != null) + decoder.destroy(); + decoder = null; + demand = 0; + stalled = false; } public boolean abort(HttpExchange exchange, Throwable failure) { // Update the state to avoid more response processing. boolean terminate; - out: while (true) { ResponseState current = responseState.get(); - switch (current) + if (current == ResponseState.FAILURE) + return false; + if (updateResponseState(current, ResponseState.FAILURE)) { - case FAILURE: - { - return false; - } - default: - { - if (updateResponseState(current, ResponseState.FAILURE)) - { - terminate = current != ResponseState.TRANSIENT; - break out; - } - break; - } + terminate = current != ResponseState.TRANSIENT; + break; } } @@ -514,17 +602,19 @@ public abstract class HttpReceiver HttpResponse response = exchange.getResponse(); if (LOG.isDebugEnabled()) - LOG.debug("Response failure {} {} on {}: {}", response, exchange, getHttpChannel(), failure); + LOG.debug("Response abort {} {} on {}: {}", response, exchange, getHttpChannel(), failure); List listeners = exchange.getConversation().getResponseListeners(); ResponseNotifier notifier = getHttpDestination().getResponseNotifier(); notifier.notifyFailure(listeners, response, failure); + // We want to deliver the "complete" event as last, + // so we emit it here only if no event handlers are + // executing, otherwise they will emit it. if (terminate) { // Mark atomically the response as terminated, with // respect to concurrency between request and response. - Result result = exchange.terminateResponse(); - terminateResponse(exchange, result); + terminateResponse(exchange); return true; } else @@ -591,46 +681,163 @@ public abstract class HttpReceiver FAILURE } - private class Decoder extends IteratingNestedCallback + /** + *

    Wraps a list of content listeners, notifies them about content events and + * tracks individual listener demand to produce a global demand for content.

    + */ + private class ContentListeners { - private final ResponseNotifier notifier; - private final HttpResponse response; - private final ContentDecoder decoder; - private final ByteBuffer buffer; - private ByteBuffer decoded; + private final Map demands = new ConcurrentHashMap<>(); + private final LongConsumer demand = HttpReceiver.this::demand; + private final List listeners; - public Decoder(ResponseNotifier notifier, HttpResponse response, ContentDecoder decoder, ByteBuffer buffer, Callback callback) + private ContentListeners(List responseListeners) { - super(callback); - this.notifier = notifier; - this.response = response; - this.decoder = decoder; - this.buffer = buffer; + listeners = responseListeners.stream() + .filter(Response.DemandedContentListener.class::isInstance) + .map(Response.DemandedContentListener.class::cast) + .collect(Collectors.toList()); } - @Override - protected Action process() throws Throwable + private boolean isEmpty() + { + return listeners.isEmpty(); + } + + private void notifyBeforeContent(HttpResponse response) + { + if (isEmpty()) + { + // If no listeners, we want to proceed and consume any content. + demand.accept(1); + } + else + { + ResponseNotifier notifier = getHttpDestination().getResponseNotifier(); + notifier.notifyBeforeContent(response, this::demand, listeners); + } + } + + private void notifyContent(HttpResponse response, ByteBuffer buffer, Callback callback) + { + HttpReceiver.this.demand(d -> d - 1); + ResponseNotifier notifier = getHttpDestination().getResponseNotifier(); + notifier.notifyContent(response, this::demand, buffer, callback, listeners); + } + + private void demand(Object context, long value) + { + if (listeners.size() > 1) + accept(context, value); + else + demand.accept(value); + } + + private void accept(Object context, long value) + { + // Increment the demand for the given listener. + demands.merge(context, value, MathUtils::cappedAdd); + + // Check if we have demand from all listeners. + if (demands.size() == listeners.size()) + { + long minDemand = Long.MAX_VALUE; + for (Long demand : demands.values()) + { + if (demand < minDemand) + minDemand = demand; + } + if (minDemand > 0) + { + // We are going to demand for minDemand content + // chunks, so decrement the listener's demand by + // minDemand and remove those that have no demand left. + Iterator> iterator = demands.entrySet().iterator(); + while (iterator.hasNext()) + { + Map.Entry entry = iterator.next(); + long newValue = entry.getValue() - minDemand; + if (newValue == 0) + iterator.remove(); + else + entry.setValue(newValue); + } + + // Demand more content chunks for all the listeners. + demand.accept(minDemand); + } + } + } + } + + /** + *

    Implements the decoding of content, producing decoded buffers only if there is demand for content.

    + */ + private class Decoder implements Destroyable + { + private final HttpResponse response; + private final ContentDecoder decoder; + private ByteBuffer encoded; + private Callback callback; + + private Decoder(HttpResponse response, ContentDecoder decoder) + { + this.response = response; + this.decoder = Objects.requireNonNull(decoder); + } + + private boolean decode(ByteBuffer encoded, Callback callback) + { + this.encoded = encoded; + this.callback = callback; + return decode(); + } + + private boolean decode() { while (true) { - decoded = decoder.decode(buffer); - if (decoded.hasRemaining()) - break; - if (!buffer.hasRemaining()) - return Action.SUCCEEDED; - } - if (LOG.isDebugEnabled()) - LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(decoded)); + ByteBuffer buffer; + while (true) + { + buffer = decoder.decode(encoded); + if (buffer.hasRemaining()) + break; + if (!encoded.hasRemaining()) + { + callback.succeeded(); + encoded = null; + callback = null; + return true; + } + } + ByteBuffer decoded = buffer; + if (LOG.isDebugEnabled()) + LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(decoded)); - notifier.notifyContent(response, decoded, this, contentListeners); - return Action.SCHEDULED; + contentListeners.notifyContent(response, decoded, Callback.from(() -> decoder.release(decoded), callback::failed)); + + boolean hasDemand = hasDemandOrStall(); + if (LOG.isDebugEnabled()) + LOG.debug("Response content decoded {}, hasDemand={}", response, hasDemand); + if (!hasDemand) + return false; + } + } + + private void resume() + { + if (LOG.isDebugEnabled()) + LOG.debug("Response content resuming decoding {}", response); + if (decode()) + receive(); } @Override - public void succeeded() + public void destroy() { - decoder.release(decoded); - super.succeeded(); + if (decoder instanceof Destroyable) + ((Destroyable)decoder).destroy(); } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java index 6e5e330cf34..8efcc282065 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -33,8 +33,8 @@ import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.util.BufferingResponseListener; import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility class that handles HTTP redirects. @@ -60,7 +60,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HttpRedirector { - private static final Logger LOG = Log.getLogger(HttpRedirector.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpRedirector.class); private static final String SCHEME_REGEXP = "(^https?)"; private static final String AUTHORITY_REGEXP = "([^/?#]+)"; // The location may be relative so the scheme://authority part may be missing @@ -82,7 +82,7 @@ public class HttpRedirector /** * @param response the response to check for redirects - * @return whether the response code is a HTTP redirect code + * @return whether the response code is an HTTP redirect code */ public boolean isRedirect(Response response) { diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java index c2d0d02df88..0cc192f6cdd 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; +import java.util.function.LongConsumer; import java.util.function.Supplier; import org.eclipse.jetty.client.api.ContentProvider; @@ -76,6 +77,7 @@ public class HttpRequest implements Request private String query; private String method = HttpMethod.GET.asString(); private HttpVersion version = HttpVersion.HTTP_1_1; + private boolean versionExplicit; private long idleTimeout = -1; private long timeout; private long timeoutAt; @@ -86,6 +88,9 @@ public class HttpRequest implements Request private List requestListeners; private BiFunction pushListener; private Supplier trailers; + private String upgradeProtocol; + private Object tag; + private boolean normalized; protected HttpRequest(HttpClient client, HttpConversation conversation, URI uri) { @@ -215,10 +220,16 @@ public class HttpRequest implements Request return version; } + public boolean isVersionExplicit() + { + return versionExplicit; + } + @Override public Request version(HttpVersion version) { this.version = Objects.requireNonNull(version); + this.versionExplicit = true; return this; } @@ -300,7 +311,7 @@ public class HttpRequest implements Request @Override public List getCookies() { - return cookies != null ? cookies : Collections.emptyList(); + return cookies != null ? cookies : Collections.emptyList(); } @Override @@ -312,6 +323,19 @@ public class HttpRequest implements Request return this; } + @Override + public Request tag(Object tag) + { + this.tag = tag; + return this; + } + + @Override + public Object getTag() + { + return tag; + } + @Override public Request attribute(String name, Object value) { @@ -324,7 +348,7 @@ public class HttpRequest implements Request @Override public Map getAttributes() { - return attributes != null ? attributes : Collections.emptyMap(); + return attributes != null ? attributes : Collections.emptyMap(); } @Override @@ -340,7 +364,7 @@ public class HttpRequest implements Request // This method is invoked often in a request/response conversation, // so we avoid allocation if there is no need to filter. if (type == null || requestListeners == null) - return requestListeners != null ? (List)requestListeners : Collections.emptyList(); + return requestListeners != null ? (List)requestListeners : Collections.emptyList(); ArrayList result = new ArrayList<>(); for (RequestListener listener : requestListeners) @@ -501,20 +525,12 @@ public class HttpRequest implements Request @Override public Request onResponseContent(final Response.ContentListener listener) { - this.responseListeners.add(new Response.AsyncContentListener() + this.responseListeners.add(new Response.ContentListener() { @Override - public void onContent(Response response, ByteBuffer content, Callback callback) + public void onContent(Response response, ByteBuffer content) { - try - { - listener.onContent(response, content); - callback.succeeded(); - } - catch (Throwable x) - { - callback.failed(x); - } + listener.onContent(response, content); } }); return this; @@ -534,6 +550,26 @@ public class HttpRequest implements Request return this; } + @Override + public Request onResponseContentDemanded(Response.DemandedContentListener listener) + { + this.responseListeners.add(new Response.DemandedContentListener() + { + @Override + public void onBeforeContent(Response response, LongConsumer demand) + { + listener.onBeforeContent(response, demand); + } + + @Override + public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback) + { + listener.onContent(response, demand, content, callback); + } + }); + return this; + } + @Override public Request onResponseSuccess(final Response.SuccessListener listener) { @@ -602,6 +638,12 @@ public class HttpRequest implements Request return this; } + public HttpRequest upgradeProtocol(String upgradeProtocol) + { + this.upgradeProtocol = upgradeProtocol; + return this; + } + @Override public ContentProvider getContent() { @@ -758,6 +800,11 @@ public class HttpRequest implements Request return trailers; } + public String getUpgradeProtocol() + { + return upgradeProtocol; + } + @Override public boolean abort(Throwable cause) { @@ -776,6 +823,23 @@ public class HttpRequest implements Request return aborted.get(); } + /** + *

    Marks this request as normalized.

    + *

    A request is normalized by setting things that applications give + * for granted such as defaulting the method to {@code GET}, adding the + * {@code Host} header, adding the cookies, adding {@code Authorization} + * headers, etc.

    + * + * @return whether this request was already normalized + * @see HttpConnection#normalizeRequest(Request) + */ + boolean normalized() + { + boolean result = normalized; + normalized = true; + return result; + } + private String buildQuery() { StringBuilder result = new StringBuilder(); @@ -869,7 +933,7 @@ public class HttpRequest implements Request } catch (URISyntaxException x) { - // The "path" of a HTTP request may not be a URI, + // The "path" of an HTTP request may not be a URI, // for example for CONNECT 127.0.0.1:8080. return null; } @@ -878,6 +942,6 @@ public class HttpRequest implements Request @Override public String toString() { - return String.format("%s[%s %s %s]@%x", this.getClass().getSimpleName(), getMethod(), getPath(), getVersion(), hashCode()); + return String.format("%s[%s %s %s]@%x", getClass().getSimpleName(), getMethod(), getPath(), getVersion(), hashCode()); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequestException.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequestException.java index ac383844e6c..ace3e69be4b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequestException.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequestException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java index b4a82af8d6c..fabb277bd44 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java index 9477ae736c8..dae52cd835a 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java index e9e74b7c6f4..beedfb22a53 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -31,8 +31,8 @@ import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * {@link HttpSender} abstracts the algorithm to send HTTP requests, so that subclasses only implement @@ -59,7 +59,7 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class HttpSender implements AsyncContentProvider.Listener { - protected static final Logger LOG = Log.getLogger(HttpSender.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpSender.class); private final AtomicReference requestState = new AtomicReference<>(RequestState.QUEUED); private final AtomicReference senderState = new AtomicReference<>(SenderState.IDLE); @@ -344,6 +344,9 @@ public abstract class HttpSender implements AsyncContentProvider.Listener if (exchange == null) return; + if (LOG.isDebugEnabled()) + LOG.debug("Request failure " + exchange.getRequest(), failure); + // Mark atomically the request as completed, with respect // to concurrency between request success and request failure. if (exchange.requestComplete(failure)) @@ -360,7 +363,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener catch (RejectedExecutionException x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Exchange aborted {}", exchange, x); abort(exchange, failure); } } @@ -559,7 +562,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener Request request = exchange.getRequest(); if (LOG.isDebugEnabled()) - LOG.debug("Request failure {} {} on {}: {}", request, exchange, getHttpChannel(), failure); + LOG.debug("Request abort {} {} on {}: {}", request, exchange, getHttpChannel(), failure); HttpDestination destination = getHttpChannel().getHttpDestination(); destination.getRequestNotifier().notifyFailure(request, failure); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java new file mode 100644 index 00000000000..3f3e5e25f3e --- /dev/null +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.client; + +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; + +/** + *

    HttpUpgrader prepares a HTTP request to upgrade from one protocol to another, + * and implements the upgrade mechanism.

    + *

    The upgrade mechanism can be the + * HTTP/1.1 upgrade mechanism + * or the + * HTTP/2 extended CONNECT mechanism.

    + *

    Given the differences among mechanism implementations, a request needs to be + * prepared before being sent to comply with the mechanism requirements (for example, + * add required headers, etc.).

    + */ +public interface HttpUpgrader +{ + /** + *

    Prepares the request for the upgrade, for example by setting the HTTP method + * or by setting HTTP headers required for the upgrade.

    + * + * @param request the request to prepare + */ + public void prepare(HttpRequest request); + + /** + *

    Upgrades the given {@code endPoint} to a different protocol.

    + *

    The success or failure of the upgrade should be communicated via the given {@code callback}.

    + *

    An exception thrown by this method is equivalent to failing the callback.

    + * + * @param response the response with the information about the upgrade + * @param endPoint the EndPoint to upgrade + * @param callback a callback to notify of the success or failure of the upgrade + */ + public void upgrade(HttpResponse response, EndPoint endPoint, Callback callback); + + /** + *

    A factory for {@link HttpUpgrader}s.

    + *

    A {@link Request} subclass should implement this interface + * if it wants to create a specific HttpUpgrader.

    + */ + public interface Factory + { + public HttpUpgrader newHttpUpgrader(HttpVersion version); + } +} diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/IConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/IConnection.java index 0e935aba1e1..836638c2d8c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/IConnection.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/IConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/LeakTrackingConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/LeakTrackingConnectionPool.java index d631511dbc1..943e1b615bc 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/LeakTrackingConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/LeakTrackingConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -22,12 +22,12 @@ import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.LeakDetector; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class LeakTrackingConnectionPool extends DuplexConnectionPool { - private static final Logger LOG = Log.getLogger(LeakTrackingConnectionPool.class); + private static final Logger LOG = LoggerFactory.getLogger(LeakTrackingConnectionPool.class); private final LeakDetector leakDetector = new LeakDetector() { diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java index 389b05fd76e..57d37018f5b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -32,13 +32,13 @@ import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Sweeper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MultiplexConnectionPool extends AbstractConnectionPool implements ConnectionPool.Multiplexable, Sweeper.Sweepable { - private static final Logger LOG = Log.getLogger(MultiplexConnectionPool.class); + private static final Logger LOG = LoggerFactory.getLogger(MultiplexConnectionPool.class); private final HttpDestination destination; private final Deque idleConnections; @@ -85,6 +85,25 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements C } } + @Override + public boolean accept(Connection connection) + { + boolean accepted = super.accept(connection); + if (LOG.isDebugEnabled()) + LOG.debug("Accepted {} {}", accepted, connection); + if (accepted) + { + synchronized (this) + { + Holder holder = new Holder(connection); + activeConnections.put(connection, holder); + ++holder.count; + } + active(connection); + } + return accepted; + } + @Override public boolean isActive(Connection connection) { @@ -265,9 +284,10 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements C activeSize = activeConnections.size(); idleSize = idleConnections.size(); } - return String.format("%s@%x[connections=%d/%d,multiplex=%d,active=%d,idle=%d]", + return String.format("%s@%x[connections=%d/%d/%d,multiplex=%d,active=%d,idle=%d]", getClass().getSimpleName(), hashCode(), + getPendingConnectionCount(), getConnectionCount(), getMaxConnectionCount(), getMaxMultiplex(), diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java index 693db851102..5f5c7c8e659 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java @@ -1,26 +1,23 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; -import java.util.function.Function; - -import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.util.annotation.ManagedAttribute; /** @@ -34,14 +31,9 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; */ public class MultiplexHttpDestination extends HttpDestination implements HttpDestination.Multiplexed { - public MultiplexHttpDestination(HttpClient client, Key key) + public MultiplexHttpDestination(HttpClient client, Origin origin) { - this(client, key, Function.identity()); - } - - public MultiplexHttpDestination(HttpClient client, Key key, Function factoryFn) - { - super(client, key, factoryFn); + super(client, origin); } @ManagedAttribute(value = "The maximum number of concurrent requests per connection") diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/Origin.java b/jetty-client/src/main/java/org/eclipse/jetty/client/Origin.java index 8c364dba568..6107dc8d38a 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/Origin.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/Origin.java @@ -1,41 +1,85 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; +import java.util.List; +import java.util.Map; import java.util.Objects; +import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; +import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.URIUtil; +/** + *

    Class that groups the elements that uniquely identify a destination.

    + *

    The elements are {@code scheme}, {@code host}, {@code port}, a + * {@link Origin.Protocol} and a tag object that further distinguishes + * destinations that have the same origin and protocol.

    + *

    In general it is possible that, for the same origin, the server can + * speak different protocols (for example, clear-text HTTP/1.1 and clear-text + * HTTP/2), so the {@link Origin.Protocol} makes that distinction.

    + *

    Furthermore, it may be desirable to have different destinations for + * the same origin and protocol (for example, when using the PROXY protocol + * in a reverse proxy server, you want to be able to map the client ip:port + * to the destination {@code tag}, so that all the connections to the server + * associated to that destination can specify the PROXY protocol bytes for + * that particular client connection.

    + */ public class Origin { private final String scheme; private final Address address; + private final Object tag; + private final Protocol protocol; public Origin(String scheme, String host, int port) { - this(scheme, new Address(host, port)); + this(scheme, host, port, null); + } + + public Origin(String scheme, String host, int port, Object tag) + { + this(scheme, new Address(host, port), tag); + } + + public Origin(String scheme, String host, int port, Object tag, Protocol protocol) + { + this(scheme, new Address(host, port), tag, protocol); } public Origin(String scheme, Address address) + { + this(scheme, address, null); + } + + public Origin(String scheme, Address address, Object tag) + { + this(scheme, address, tag, null); + } + + public Origin(String scheme, Address address, Object tag, Protocol protocol) { this.scheme = Objects.requireNonNull(scheme); this.address = address; + this.tag = tag; + this.protocol = protocol; } public String getScheme() @@ -48,6 +92,16 @@ public class Origin return address; } + public Object getTag() + { + return tag; + } + + public Protocol getProtocol() + { + return protocol; + } + @Override public boolean equals(Object obj) { @@ -56,13 +110,16 @@ public class Origin if (obj == null || getClass() != obj.getClass()) return false; Origin that = (Origin)obj; - return scheme.equals(that.scheme) && address.equals(that.address); + return scheme.equals(that.scheme) && + address.equals(that.address) && + Objects.equals(tag, that.tag) && + Objects.equals(protocol, that.protocol); } @Override public int hashCode() { - return Objects.hash(scheme, address); + return Objects.hash(scheme, address, tag, protocol); } public String asString() @@ -75,7 +132,12 @@ public class Origin @Override public String toString() { - return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), asString()); + return String.format("%s@%x[%s,tag=%s,protocol=%s]", + getClass().getSimpleName(), + hashCode(), + asString(), + getTag(), + getProtocol()); } public static class Address @@ -127,4 +189,69 @@ public class Origin return asString(); } } + + /** + *

    The representation of a network protocol.

    + *

    A network protocol may have multiple protocol names + * associated to it, for example {@code ["h2", "h2-17", "h2-16"]}.

    + *

    A Protocol is then rendered into a {@link ClientConnectionFactory} + * chain, for example in + * {@link HttpClientTransportDynamic#newConnection(EndPoint, Map)}.

    + */ + public static class Protocol + { + private final List protocols; + private final boolean negotiate; + + /** + * Creates a Protocol with the given list of protocol names + * and whether it should negotiate the protocol. + * + * @param protocols the protocol names + * @param negotiate whether the protocol should be negotiated + */ + public Protocol(List protocols, boolean negotiate) + { + this.protocols = protocols; + this.negotiate = negotiate; + } + + public List getProtocols() + { + return protocols; + } + + public boolean isNegotiate() + { + return negotiate; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + Protocol that = (Protocol)obj; + return protocols.equals(that.protocols) && negotiate == that.negotiate; + } + + @Override + public int hashCode() + { + return Objects.hash(protocols, negotiate); + } + + public String asString() + { + return String.format("proto=%s,nego=%b", protocols, negotiate); + } + + @Override + public String toString() + { + return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), asString()); + } + } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandler.java index a5486831832..221c0863d8a 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandlers.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandlers.java index fd34210d916..9a7e230633a 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandlers.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandlers.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyAuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyAuthenticationProtocolHandler.java index f55ab074ae9..08458ed5848 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyAuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyAuthenticationProtocolHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -73,7 +73,7 @@ public class ProxyAuthenticationProtocolHandler extends AuthenticationProtocolHa @Override protected URI getAuthenticationURI(Request request) { - HttpDestination destination = (HttpDestination)getHttpClient().getDestination(request.getScheme(), request.getHost(), request.getPort()); + HttpDestination destination = (HttpDestination)getHttpClient().resolveDestination(request); ProxyConfiguration.Proxy proxy = destination.getProxy(); return proxy != null ? proxy.getURI() : request.getURI(); } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java index d8e8acbbc05..56a4e0a1f38 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -24,8 +24,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.util.HostPort; +import org.eclipse.jetty.util.ssl.SslContextFactory; /** * The configuration of the forward proxy to use with {@link org.eclipse.jetty.client.HttpClient}. @@ -59,16 +61,26 @@ public class ProxyConfiguration public abstract static class Proxy { - // TO use IPAddress Map + // TODO use InetAddressSet? Or IncludeExcludeSet? private final Set included = new HashSet<>(); private final Set excluded = new HashSet<>(); - private final Origin.Address address; - private final boolean secure; + private final Origin origin; + private final SslContextFactory.Client sslContextFactory; - protected Proxy(Origin.Address address, boolean secure) + protected Proxy(Origin.Address address, boolean secure, SslContextFactory.Client sslContextFactory, Origin.Protocol protocol) { - this.address = address; - this.secure = secure; + this(new Origin(secure ? HttpScheme.HTTPS.asString() : HttpScheme.HTTP.asString(), address, null, protocol), sslContextFactory); + } + + protected Proxy(Origin origin, SslContextFactory.Client sslContextFactory) + { + this.origin = origin; + this.sslContextFactory = sslContextFactory; + } + + public Origin getOrigin() + { + return origin; } /** @@ -76,7 +88,7 @@ public class ProxyConfiguration */ public Origin.Address getAddress() { - return address; + return origin.getAddress(); } /** @@ -84,7 +96,23 @@ public class ProxyConfiguration */ public boolean isSecure() { - return secure; + return HttpScheme.HTTPS.is(origin.getScheme()); + } + + /** + * @return the optional SslContextFactory to use when connecting to proxies + */ + public SslContextFactory.Client getSslContextFactory() + { + return sslContextFactory; + } + + /** + * @return the protocol spoken by this proxy + */ + public Origin.Protocol getProtocol() + { + return origin.getProtocol(); } /** @@ -159,14 +187,14 @@ public class ProxyConfiguration /** * @param connectionFactory the nested {@link ClientConnectionFactory} - * @return a new {@link ClientConnectionFactory} for this {@link Proxy} + * @return a new {@link ClientConnectionFactory} for this Proxy */ public abstract ClientConnectionFactory newClientConnectionFactory(ClientConnectionFactory connectionFactory); @Override public String toString() { - return address.toString(); + return origin.toString(); } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyProtocolClientConnectionFactory.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyProtocolClientConnectionFactory.java new file mode 100644 index 00000000000..6aac5970989 --- /dev/null +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyProtocolClientConnectionFactory.java @@ -0,0 +1,674 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.client; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Executor; + +import org.eclipse.jetty.io.AbstractConnection; +import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Promise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

    ClientConnectionFactory for the + * PROXY protocol.

    + *

    Use the {@link V1} or {@link V2} versions of this class to specify what version of the + * PROXY protocol you want to use.

    + */ +public abstract class ProxyProtocolClientConnectionFactory implements ClientConnectionFactory +{ + /** + * A ClientConnectionFactory for the PROXY protocol version 1. + */ + public static class V1 extends ProxyProtocolClientConnectionFactory + { + public V1(ClientConnectionFactory factory) + { + super(factory); + } + + @Override + protected ProxyProtocolConnection newProxyProtocolConnection(EndPoint endPoint, Map context) + { + HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + Executor executor = destination.getHttpClient().getExecutor(); + Tag tag = (Tag)destination.getOrigin().getTag(); + if (tag == null) + { + InetSocketAddress local = endPoint.getLocalAddress(); + InetSocketAddress remote = endPoint.getRemoteAddress(); + boolean ipv4 = local.getAddress() instanceof Inet4Address; + tag = new Tag(ipv4 ? "TCP4" : "TCP6", local.getAddress().getHostAddress(), local.getPort(), remote.getAddress().getHostAddress(), remote.getPort()); + } + return new ProxyProtocolConnectionV1(endPoint, executor, getClientConnectionFactory(), context, tag); + } + + /** + *

    PROXY protocol version 1 metadata holder to be used in conjunction + * with {@link org.eclipse.jetty.client.api.Request#tag(Object)}.

    + *

    Instances of this class are associated to a destination so that + * all connections of that destination will initiate the communication + * with the PROXY protocol version 1 bytes specified by this metadata.

    + */ + public static class Tag implements ClientConnectionFactory.Decorator + { + /** + * The PROXY V1 Tag typically used to "ping" the server. + */ + public static final Tag UNKNOWN = new Tag("UNKNOWN", null, 0, null, 0); + + private final String family; + private final String srcIP; + private final int srcPort; + private final String dstIP; + private final int dstPort; + + /** + *

    Creates a Tag whose metadata will be derived from the underlying EndPoint.

    + */ + public Tag() + { + this(null, 0); + } + + /** + *

    Creates a Tag with the given source metadata.

    + *

    The destination metadata will be derived from the underlying EndPoint.

    + * + * @param srcIP the source IP address + * @param srcPort the source port + */ + public Tag(String srcIP, int srcPort) + { + this(null, srcIP, srcPort, null, 0); + } + + /** + *

    Creates a Tag with the given metadata.

    + * + * @param family the protocol family + * @param srcIP the source IP address + * @param srcPort the source port + * @param dstIP the destination IP address + * @param dstPort the destination port + */ + public Tag(String family, String srcIP, int srcPort, String dstIP, int dstPort) + { + this.family = family; + this.srcIP = srcIP; + this.srcPort = srcPort; + this.dstIP = dstIP; + this.dstPort = dstPort; + } + + public String getFamily() + { + return family; + } + + public String getSourceAddress() + { + return srcIP; + } + + public int getSourcePort() + { + return srcPort; + } + + public String getDestinationAddress() + { + return dstIP; + } + + public int getDestinationPort() + { + return dstPort; + } + + @Override + public ClientConnectionFactory apply(ClientConnectionFactory factory) + { + return new V1(factory); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + Tag that = (Tag)obj; + return Objects.equals(family, that.family) && + Objects.equals(srcIP, that.srcIP) && + srcPort == that.srcPort && + Objects.equals(dstIP, that.dstIP) && + dstPort == that.dstPort; + } + + @Override + public int hashCode() + { + return Objects.hash(family, srcIP, srcPort, dstIP, dstPort); + } + } + } + + /** + * A ClientConnectionFactory for the PROXY protocol version 2. + */ + public static class V2 extends ProxyProtocolClientConnectionFactory + { + public V2(ClientConnectionFactory factory) + { + super(factory); + } + + @Override + protected ProxyProtocolConnection newProxyProtocolConnection(EndPoint endPoint, Map context) + { + HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + Executor executor = destination.getHttpClient().getExecutor(); + Tag tag = (Tag)destination.getOrigin().getTag(); + if (tag == null) + { + InetSocketAddress local = endPoint.getLocalAddress(); + InetSocketAddress remote = endPoint.getRemoteAddress(); + boolean ipv4 = local.getAddress() instanceof Inet4Address; + tag = new Tag(Tag.Command.PROXY, ipv4 ? Tag.Family.INET4 : Tag.Family.INET6, Tag.Protocol.STREAM, local.getAddress().getHostAddress(), local.getPort(), remote.getAddress().getHostAddress(), remote.getPort(), null); + } + return new ProxyProtocolConnectionV2(endPoint, executor, getClientConnectionFactory(), context, tag); + } + + /** + *

    PROXY protocol version 2 metadata holder to be used in conjunction + * with {@link org.eclipse.jetty.client.api.Request#tag(Object)}.

    + *

    Instances of this class are associated to a destination so that + * all connections of that destination will initiate the communication + * with the PROXY protocol version 2 bytes specified by this metadata.

    + */ + public static class Tag implements ClientConnectionFactory.Decorator + { + /** + * The PROXY V2 Tag typically used to "ping" the server. + */ + public static final Tag LOCAL = new Tag(Command.LOCAL, Family.UNSPEC, Protocol.UNSPEC, null, 0, null, 0, null); + + private Command command; + private Family family; + private Protocol protocol; + private String srcIP; + private int srcPort; + private String dstIP; + private int dstPort; + private List tlvs; + + /** + *

    Creates a Tag whose metadata will be derived from the underlying EndPoint.

    + */ + public Tag() + { + this(null, 0); + } + + /** + *

    Creates a Tag with the given source metadata.

    + *

    The destination metadata will be derived from the underlying EndPoint.

    + * + * @param srcIP the source IP address + * @param srcPort the source port + */ + public Tag(String srcIP, int srcPort) + { + this(Command.PROXY, null, Protocol.STREAM, srcIP, srcPort, null, 0, null); + } + + /** + *

    Creates a Tag with the given source metadata and Type-Length-Value (TLV) objects.

    + *

    The destination metadata will be derived from the underlying EndPoint.

    + * + * @param srcIP the source IP address + * @param srcPort the source port + * @param tlvs the TLV objects + */ + public Tag(String srcIP, int srcPort, List tlvs) + { + this(Command.PROXY, null, Protocol.STREAM, srcIP, srcPort, null, 0, tlvs); + } + + /** + *

    Creates a Tag with the given metadata.

    + * + * @param command the LOCAL or PROXY command + * @param family the protocol family + * @param protocol the protocol type + * @param srcIP the source IP address + * @param srcPort the source port + * @param dstIP the destination IP address + * @param dstPort the destination port + * @param tlvs the TLV objects + */ + public Tag(Command command, Family family, Protocol protocol, String srcIP, int srcPort, String dstIP, int dstPort, List tlvs) + { + this.command = command; + this.family = family; + this.protocol = protocol; + this.srcIP = srcIP; + this.srcPort = srcPort; + this.dstIP = dstIP; + this.dstPort = dstPort; + this.tlvs = tlvs; + } + + public Command getCommand() + { + return command; + } + + public Family getFamily() + { + return family; + } + + public Protocol getProtocol() + { + return protocol; + } + + public String getSourceAddress() + { + return srcIP; + } + + public int getSourcePort() + { + return srcPort; + } + + public String getDestinationAddress() + { + return dstIP; + } + + public int getDestinationPort() + { + return dstPort; + } + + public List getTLVs() + { + return tlvs; + } + + @Override + public ClientConnectionFactory apply(ClientConnectionFactory factory) + { + return new V2(factory); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + Tag that = (Tag)obj; + return command == that.command && + family == that.family && + protocol == that.protocol && + Objects.equals(srcIP, that.srcIP) && + srcPort == that.srcPort && + Objects.equals(dstIP, that.dstIP) && + dstPort == that.dstPort && + Objects.equals(tlvs, that.tlvs); + } + + @Override + public int hashCode() + { + return Objects.hash(command, family, protocol, srcIP, srcPort, dstIP, dstPort, tlvs); + } + + public enum Command + { + LOCAL, PROXY + } + + public enum Family + { + UNSPEC, INET4, INET6, UNIX + } + + public enum Protocol + { + UNSPEC, STREAM, DGRAM + } + + public static class TLV + { + private final int type; + private final byte[] value; + + public TLV(int type, byte[] value) + { + if (type < 0 || type > 255) + throw new IllegalArgumentException("Invalid type: " + type); + if (value != null && value.length > 65535) + throw new IllegalArgumentException("Invalid value length: " + value.length); + this.type = type; + this.value = Objects.requireNonNull(value); + } + + public int getType() + { + return type; + } + + public byte[] getValue() + { + return value; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + TLV that = (TLV)obj; + return type == that.type && Arrays.equals(value, that.value); + } + + @Override + public int hashCode() + { + int result = Objects.hash(type); + result = 31 * result + Arrays.hashCode(value); + return result; + } + } + } + } + + private final ClientConnectionFactory factory; + + private ProxyProtocolClientConnectionFactory(ClientConnectionFactory factory) + { + this.factory = factory; + } + + public ClientConnectionFactory getClientConnectionFactory() + { + return factory; + } + + @Override + public Connection newConnection(EndPoint endPoint, Map context) + { + ProxyProtocolConnection connection = newProxyProtocolConnection(endPoint, context); + return customize(connection, context); + } + + protected abstract ProxyProtocolConnection newProxyProtocolConnection(EndPoint endPoint, Map context); + + protected abstract static class ProxyProtocolConnection extends AbstractConnection implements Callback + { + protected static final Logger LOG = LoggerFactory.getLogger(ProxyProtocolConnection.class); + + private final ClientConnectionFactory factory; + private final Map context; + + private ProxyProtocolConnection(EndPoint endPoint, Executor executor, ClientConnectionFactory factory, Map context) + { + super(endPoint, executor); + this.factory = factory; + this.context = context; + } + + @Override + public void onOpen() + { + super.onOpen(); + writePROXYBytes(getEndPoint(), this); + } + + protected abstract void writePROXYBytes(EndPoint endPoint, Callback callback); + + @Override + public void succeeded() + { + try + { + EndPoint endPoint = getEndPoint(); + Connection connection = factory.newConnection(endPoint, context); + if (LOG.isDebugEnabled()) + LOG.debug("Written PROXY line, upgrading to {}", connection); + endPoint.upgrade(connection); + } + catch (Throwable x) + { + failed(x); + } + } + + @Override + public void failed(Throwable x) + { + close(); + Promise promise = (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); + promise.failed(x); + } + + @Override + public InvocationType getInvocationType() + { + return InvocationType.NON_BLOCKING; + } + + @Override + public void onFillable() + { + } + } + + private static class ProxyProtocolConnectionV1 extends ProxyProtocolConnection + { + private final V1.Tag tag; + + public ProxyProtocolConnectionV1(EndPoint endPoint, Executor executor, ClientConnectionFactory factory, Map context, V1.Tag tag) + { + super(endPoint, executor, factory, context); + this.tag = tag; + } + + @Override + protected void writePROXYBytes(EndPoint endPoint, Callback callback) + { + try + { + InetSocketAddress localAddress = endPoint.getLocalAddress(); + InetSocketAddress remoteAddress = endPoint.getRemoteAddress(); + String family = tag.getFamily(); + String srcIP = tag.getSourceAddress(); + int srcPort = tag.getSourcePort(); + String dstIP = tag.getDestinationAddress(); + int dstPort = tag.getDestinationPort(); + if (family == null) + family = localAddress.getAddress() instanceof Inet4Address ? "TCP4" : "TCP6"; + family = family.toUpperCase(Locale.ENGLISH); + boolean unknown = family.equals("UNKNOWN"); + StringBuilder builder = new StringBuilder(64); + builder.append("PROXY ").append(family); + if (!unknown) + { + if (srcIP == null) + srcIP = localAddress.getAddress().getHostAddress(); + builder.append(" ").append(srcIP); + if (dstIP == null) + dstIP = remoteAddress.getAddress().getHostAddress(); + builder.append(" ").append(dstIP); + if (srcPort <= 0) + srcPort = localAddress.getPort(); + builder.append(" ").append(srcPort); + if (dstPort <= 0) + dstPort = remoteAddress.getPort(); + builder.append(" ").append(dstPort); + } + builder.append("\r\n"); + String line = builder.toString(); + if (LOG.isDebugEnabled()) + LOG.debug("Writing PROXY bytes: {}", line.trim()); + ByteBuffer buffer = ByteBuffer.wrap(line.getBytes(StandardCharsets.US_ASCII)); + endPoint.write(callback, buffer); + } + catch (Throwable x) + { + callback.failed(x); + } + } + } + + private static class ProxyProtocolConnectionV2 extends ProxyProtocolConnection + { + private static final byte[] MAGIC = {0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}; + + private final V2.Tag tag; + + public ProxyProtocolConnectionV2(EndPoint endPoint, Executor executor, ClientConnectionFactory factory, Map context, V2.Tag tag) + { + super(endPoint, executor, factory, context); + this.tag = tag; + } + + @Override + protected void writePROXYBytes(EndPoint endPoint, Callback callback) + { + try + { + int capacity = MAGIC.length; + capacity += 1; // version and command + capacity += 1; // family and protocol + capacity += 2; // length + capacity += 216; // max address length + List tlvs = tag.getTLVs(); + int vectorsLength = tlvs == null ? 0 : tlvs.stream() + .mapToInt(tlv -> 1 + 2 + tlv.getValue().length) + .sum(); + capacity += vectorsLength; + ByteBuffer buffer = ByteBuffer.allocateDirect(capacity); + buffer.put(MAGIC); + V2.Tag.Command command = tag.getCommand(); + int versionAndCommand = (2 << 4) | (command.ordinal() & 0x0F); + buffer.put((byte)versionAndCommand); + V2.Tag.Family family = tag.getFamily(); + String srcAddr = tag.getSourceAddress(); + if (srcAddr == null) + srcAddr = endPoint.getLocalAddress().getAddress().getHostAddress(); + int srcPort = tag.getSourcePort(); + if (srcPort <= 0) + srcPort = endPoint.getLocalAddress().getPort(); + if (family == null) + family = InetAddress.getByName(srcAddr) instanceof Inet4Address ? V2.Tag.Family.INET4 : V2.Tag.Family.INET6; + V2.Tag.Protocol protocol = tag.getProtocol(); + if (protocol == null) + protocol = V2.Tag.Protocol.STREAM; + int familyAndProtocol = (family.ordinal() << 4) | protocol.ordinal(); + buffer.put((byte)familyAndProtocol); + int length = 0; + switch (family) + { + case UNSPEC: + break; + case INET4: + length = 12; + break; + case INET6: + length = 36; + break; + case UNIX: + length = 216; + break; + default: + throw new IllegalStateException(); + } + length += vectorsLength; + buffer.putShort((short)length); + String dstAddr = tag.getDestinationAddress(); + if (dstAddr == null) + dstAddr = endPoint.getRemoteAddress().getAddress().getHostAddress(); + int dstPort = tag.getDestinationPort(); + if (dstPort <= 0) + dstPort = endPoint.getRemoteAddress().getPort(); + switch (family) + { + case UNSPEC: + break; + case INET4: + case INET6: + buffer.put(InetAddress.getByName(srcAddr).getAddress()); + buffer.put(InetAddress.getByName(dstAddr).getAddress()); + buffer.putShort((short)srcPort); + buffer.putShort((short)dstPort); + break; + case UNIX: + int position = buffer.position(); + buffer.put(srcAddr.getBytes(StandardCharsets.US_ASCII)); + buffer.position(position + 108); + buffer.put(dstAddr.getBytes(StandardCharsets.US_ASCII)); + break; + default: + throw new IllegalStateException(); + } + if (tlvs != null) + { + for (V2.Tag.TLV tlv : tlvs) + { + buffer.put((byte)tlv.getType()); + byte[] data = tlv.getValue(); + buffer.putShort((short)data.length); + buffer.put(data); + } + } + buffer.flip(); + endPoint.write(callback, buffer); + } + catch (Throwable x) + { + callback.failed(x); + } + } + } +} diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectProtocolHandler.java index 6b0cb3e0bb8..dbaba9f9038 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectProtocolHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RequestNotifier.java b/jetty-client/src/main/java/org/eclipse/jetty/client/RequestNotifier.java index 9d27f62187b..a4886519114 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/RequestNotifier.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/RequestNotifier.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -22,12 +22,12 @@ import java.nio.ByteBuffer; import java.util.List; import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class RequestNotifier { - private static final Logger LOG = Log.getLogger(ResponseNotifier.class); + private static final Logger LOG = LoggerFactory.getLogger(ResponseNotifier.class); private final HttpClient client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ResponseNotifier.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ResponseNotifier.java index 7561e6f63ca..1d3f959f10d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ResponseNotifier.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ResponseNotifier.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -21,6 +21,8 @@ package org.eclipse.jetty.client; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.List; +import java.util.function.LongConsumer; +import java.util.function.ObjLongConsumer; import java.util.stream.Collectors; import org.eclipse.jetty.client.api.ContentResponse; @@ -30,12 +32,12 @@ import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.CountingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ResponseNotifier { - private static final Logger LOG = Log.getLogger(ResponseNotifier.class); + private static final Logger LOG = LoggerFactory.getLogger(ResponseNotifier.class); public void notifyBegin(List listeners, Response response) { @@ -103,36 +105,54 @@ public class ResponseNotifier } } - public void notifyContent(List listeners, Response response, ByteBuffer buffer, Callback callback) + public void notifyBeforeContent(Response response, ObjLongConsumer demand, List contentListeners) { - List contentListeners = listeners.stream() - .filter(Response.AsyncContentListener.class::isInstance) - .map(Response.AsyncContentListener.class::cast) - .collect(Collectors.toList()); - notifyContent(response, buffer, callback, contentListeners); + for (Response.DemandedContentListener listener : contentListeners) + { + notifyBeforeContent(listener, response, d -> demand.accept(listener, d)); + } } - public void notifyContent(Response response, ByteBuffer buffer, Callback callback, List contentListeners) + private void notifyBeforeContent(Response.DemandedContentListener listener, Response response, LongConsumer demand) { - if (contentListeners.isEmpty()) + try + { + listener.onBeforeContent(response, demand); + } + catch (Throwable x) + { + LOG.info("Exception while notifying listener " + listener, x); + } + } + + public void notifyContent(Response response, ObjLongConsumer demand, ByteBuffer buffer, Callback callback, List contentListeners) + { + int count = contentListeners.size(); + if (count == 0) { callback.succeeded(); + demand.accept(null, 1); + } + else if (count == 1) + { + Response.DemandedContentListener listener = contentListeners.get(0); + notifyContent(listener, response, d -> demand.accept(listener, d), buffer.slice(), callback); } else { - CountingCallback counter = new CountingCallback(callback, contentListeners.size()); - for (Response.AsyncContentListener listener : contentListeners) + callback = new CountingCallback(callback, count); + for (Response.DemandedContentListener listener : contentListeners) { - notifyContent(listener, response, buffer.slice(), counter); + notifyContent(listener, response, d -> demand.accept(listener, d), buffer.slice(), callback); } } } - private void notifyContent(Response.AsyncContentListener listener, Response response, ByteBuffer buffer, Callback callback) + private void notifyContent(Response.DemandedContentListener listener, Response response, LongConsumer demand, ByteBuffer buffer, Callback callback) { try { - listener.onContent(response, buffer, callback); + listener.onContent(response, demand, buffer, callback); } catch (Throwable x) { @@ -236,7 +256,15 @@ public class ResponseNotifier { byte[] content = ((ContentResponse)response).getContent(); if (content != null && content.length > 0) - notifyContent(listeners, response, ByteBuffer.wrap(content), Callback.NOOP); + { + List contentListeners = listeners.stream() + .filter(Response.DemandedContentListener.class::isInstance) + .map(Response.DemandedContentListener.class::cast) + .collect(Collectors.toList()); + ObjLongConsumer demand = (context, value) -> {}; + notifyBeforeContent(response, demand, contentListeners); + notifyContent(response, demand, ByteBuffer.wrap(content), Callback.NOOP, contentListeners); + } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java index d16af4f2d87..10087188c5f 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -214,9 +214,10 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool implements } } } - return String.format("%s@%x[c=%d/%d,a=%d]", + return String.format("%s@%x[c=%d/%d/%d,a=%d]", getClass().getSimpleName(), hashCode(), + getPendingConnectionCount(), present, getMaxConnectionCount(), active diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SendFailure.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SendFailure.java index 53df9eb3449..dcf7f608a9c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SendFailure.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SendFailure.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -32,6 +32,10 @@ public class SendFailure @Override public String toString() { - return String.format("%s[failure=%s,retry=%b]", super.toString(), failure, retry); + return String.format("%s@%x[failure=%s,retry=%b]", + getClass().getSimpleName(), + hashCode(), + failure, + retry); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java b/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java index 677867f1f6a..b7351316649 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; import java.io.IOException; +import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Map; @@ -29,12 +30,13 @@ import java.util.regex.Pattern; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Socks4Proxy extends ProxyConfiguration.Proxy { @@ -45,7 +47,7 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy public Socks4Proxy(Origin.Address address, boolean secure) { - super(address, secure); + super(address, secure, null, null); } @Override @@ -64,7 +66,7 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy } @Override - public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) { HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); Executor executor = destination.getHttpClient().getExecutor(); @@ -76,7 +78,7 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy private static class Socks4ProxyConnection extends AbstractConnection implements Callback { private static final Pattern IPv4_PATTERN = Pattern.compile("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})"); - private static final Logger LOG = Log.getLogger(Socks4ProxyConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(Socks4ProxyConnection.class); private final Socks4Parser parser = new Socks4Parser(); private final ClientConnectionFactory connectionFactory; @@ -195,10 +197,12 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy try { HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); - HttpClient client = destination.getHttpClient(); + // Don't want to do DNS resolution here. + InetSocketAddress address = InetSocketAddress.createUnresolved(destination.getHost(), destination.getPort()); + context.put(ClientConnector.REMOTE_SOCKET_ADDRESS_CONTEXT_KEY, address); ClientConnectionFactory connectionFactory = this.connectionFactory; if (destination.isSecure()) - connectionFactory = client.newSslClientConnectionFactory(connectionFactory); + connectionFactory = destination.newSslClientConnectionFactory(null, connectionFactory); org.eclipse.jetty.io.Connection newConnection = connectionFactory.newConnection(getEndPoint(), context); getEndPoint().upgrade(newConnection); if (LOG.isDebugEnabled()) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/Synchronizable.java b/jetty-client/src/main/java/org/eclipse/jetty/client/Synchronizable.java index e1a77121b63..58a1d9a2fc1 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/Synchronizable.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/Synchronizable.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java index 7a3121a755b..f2048452c3a 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -26,13 +26,13 @@ import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.io.CyclicTimeout; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TimeoutCompleteListener extends CyclicTimeout implements Response.CompleteListener { - private static final Logger LOG = Log.getLogger(TimeoutCompleteListener.class); + private static final Logger LOG = LoggerFactory.getLogger(TimeoutCompleteListener.class); private final AtomicReference request = new AtomicReference<>(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/UpgradeProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/UpgradeProtocolHandler.java new file mode 100644 index 00000000000..da6a30b3d70 --- /dev/null +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/UpgradeProtocolHandler.java @@ -0,0 +1,110 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.client; + +import java.util.List; + +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; + +/** + *

    A protocol handler that handles HTTP 101 responses.

    + */ +public class UpgradeProtocolHandler implements ProtocolHandler +{ + private final List protocols = List.of("websocket", "h2c"); + + @Override + public String getName() + { + return "upgrade"; + } + + @Override + public boolean accept(Request request, Response response) + { + boolean upgraded = HttpStatus.SWITCHING_PROTOCOLS_101 == response.getStatus(); + boolean accepted = false; + if (upgraded) + accepted = acceptHeaders(request, response); + return upgraded && accepted; + } + + protected boolean acceptHeaders(Request request, Response response) + { + HttpField responseUpgrade = response.getHeaders().getField(HttpHeader.UPGRADE); + if (responseUpgrade != null && protocols.stream().anyMatch(responseUpgrade::contains)) + return true; + // The response may not contain the Upgrade header, so check the request. + HttpField requestUpgrade = request.getHeaders().getField(HttpHeader.UPGRADE); + return requestUpgrade != null && protocols.stream().anyMatch(requestUpgrade::contains); + } + + @Override + public Response.Listener getResponseListener() + { + return new Response.Listener.Adapter() + { + @Override + public void onComplete(Result result) + { + HttpResponse response = (HttpResponse)result.getResponse(); + HttpRequest request = (HttpRequest)response.getRequest(); + if (result.isSucceeded()) + { + try + { + HttpConversation conversation = request.getConversation(); + HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName()); + if (upgrader == null) + throw new HttpResponseException("101 response without " + HttpUpgrader.class.getSimpleName(), response); + EndPoint endPoint = (EndPoint)conversation.getAttribute(EndPoint.class.getName()); + if (endPoint == null) + throw new HttpResponseException("Upgrade without " + EndPoint.class.getSimpleName(), response); + upgrader.upgrade(response, endPoint, Callback.from(Callback.NOOP::succeeded, x -> forwardFailureComplete(request, null, response, x))); + } + catch (Throwable x) + { + forwardFailureComplete(request, null, response, x); + } + } + else + { + forwardFailureComplete(request, result.getRequestFailure(), response, result.getResponseFailure()); + } + } + }; + } + + private void forwardFailureComplete(HttpRequest request, Throwable requestFailure, Response response, Throwable responseFailure) + { + HttpConversation conversation = request.getConversation(); + conversation.updateResponseListeners(null); + List responseListeners = conversation.getResponseListeners(); + ResponseNotifier notifier = new ResponseNotifier(); + notifier.forwardFailure(responseListeners, response, responseFailure); + notifier.notifyComplete(responseListeners, new Result(request, requestFailure, response, responseFailure)); + } +} diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java index 9f6e2e7d475..7aec6712b7d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -30,9 +30,9 @@ import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    A connection pool that validates connections before @@ -59,7 +59,7 @@ import org.eclipse.jetty.util.thread.Scheduler; */ public class ValidatingConnectionPool extends DuplexConnectionPool { - private static final Logger LOG = Log.getLogger(ValidatingConnectionPool.class); + private static final Logger LOG = LoggerFactory.getLogger(ValidatingConnectionPool.class); private final Scheduler scheduler; private final long timeout; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/WWWAuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/WWWAuthenticationProtocolHandler.java index 2ab13b00446..042fa98d8d7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/WWWAuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/WWWAuthenticationProtocolHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Authentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Authentication.java index 1b94643e51b..58ab1cb9316 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Authentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Authentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java index 14315103d75..32552fe8f72 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Connection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Connection.java index b50bead1881..3d62bced80d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Connection.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Connection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java index ba11fdbc636..f9a705af082 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentResponse.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentResponse.java index 01e22efa62b..dbbfb905ec7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentResponse.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/ContentResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Destination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Destination.java index 2325657c0fb..23c6eaf49dd 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Destination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Destination.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; @@ -29,7 +29,7 @@ import org.eclipse.jetty.util.Promise; * {@link Destination} holds a pool of {@link Connection}s, but allows to create unpooled * connections if the application wants full control over connection management via {@link #newConnection(Promise)}. *

    - * {@link Destination}s may be obtained via {@link HttpClient#getDestination(String, String, int)} + * {@link Destination}s may be obtained via {@link HttpClient#resolveDestination(Request)} */ public interface Destination { diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java index 9e872adb16c..8b7d97d1248 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; @@ -40,7 +40,7 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.util.Fields; /** - *

    {@link Request} represents a HTTP request, and offers a fluent interface to customize + *

    {@link Request} represents an HTTP request, and offers a fluent interface to customize * various attributes such as the path, the headers, the content, etc.

    *

    You can create {@link Request} objects via {@link HttpClient#newRequest(String)} and * you can send them using either {@link #send()} for a blocking semantic, or @@ -180,6 +180,28 @@ public interface Request */ Request cookie(HttpCookie cookie); + /** + *

    Tags this request with the given metadata tag.

    + *

    Each different tag will create a different destination, + * even if the destination origin is the same.

    + *

    This is particularly useful in proxies, where requests + * for the same origin but from different clients may be tagged + * with client's metadata (e.g. the client remote address).

    + *

    The tag metadata class must correctly implement + * {@link Object#hashCode()} and {@link Object#equals(Object)} + * so that it can be used, along with the origin, to identify + * a destination.

    + * + * @param tag the metadata to tag the request with + * @return this request object + */ + Request tag(Object tag); + + /** + * @return the metadata this request has been tagged with + */ + Object getTag(); + /** * @param name the name of the attribute * @param value the value of the attribute @@ -370,6 +392,12 @@ public interface Request */ Request onResponseContentAsync(Response.AsyncContentListener listener); + /** + * @param listener an asynchronous listener for response content events + * @return this request object + */ + Request onResponseContentDemanded(Response.DemandedContentListener listener); + /** * @param listener a listener for response success event * @return this request object @@ -545,45 +573,46 @@ public interface Request */ public interface Listener extends QueuedListener, BeginListener, HeadersListener, CommitListener, ContentListener, SuccessListener, FailureListener { + @Override + public default void onQueued(Request request) + { + } + + @Override + public default void onBegin(Request request) + { + } + + @Override + public default void onHeaders(Request request) + { + } + + @Override + public default void onCommit(Request request) + { + } + + @Override + public default void onContent(Request request, ByteBuffer content) + { + } + + @Override + public default void onSuccess(Request request) + { + } + + @Override + public default void onFailure(Request request, Throwable failure) + { + } + /** * An empty implementation of {@link Listener} */ public static class Adapter implements Listener { - @Override - public void onQueued(Request request) - { - } - - @Override - public void onBegin(Request request) - { - } - - @Override - public void onHeaders(Request request) - { - } - - @Override - public void onCommit(Request request) - { - } - - @Override - public void onContent(Request request, ByteBuffer content) - { - } - - @Override - public void onSuccess(Request request) - { - } - - @Override - public void onFailure(Request request, Throwable failure) - { - } } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Response.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Response.java index 95605aad404..9c830cb1904 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Response.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Response.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; @@ -21,6 +21,8 @@ package org.eclipse.jetty.client.api; import java.nio.ByteBuffer; import java.util.EventListener; import java.util.List; +import java.util.concurrent.Flow; +import java.util.function.LongConsumer; import org.eclipse.jetty.client.util.BufferingResponseListener; import org.eclipse.jetty.http.HttpField; @@ -29,7 +31,7 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.util.Callback; /** - *

    {@link Response} represents a HTTP response and offers methods to retrieve status code, HTTP version + *

    {@link Response} represents an HTTP response and offers methods to retrieve status code, HTTP version * and headers.

    *

    {@link Response} objects are passed as parameters to {@link Response.Listener} callbacks, or as * future result of {@link Request#send()}.

    @@ -83,14 +85,14 @@ public interface Response /** * Common, empty, super-interface for response listeners */ - public interface ResponseListener extends EventListener + interface ResponseListener extends EventListener { } /** * Listener for the response begin event. */ - public interface BeginListener extends ResponseListener + interface BeginListener extends ResponseListener { /** * Callback method invoked when the response line containing HTTP version, @@ -100,83 +102,151 @@ public interface Response * * @param response the response containing the response line data */ - public void onBegin(Response response); + void onBegin(Response response); } /** * Listener for a response header event. */ - public interface HeaderListener extends ResponseListener + interface HeaderListener extends ResponseListener { /** - * Callback method invoked when a response header has been received, + * Callback method invoked when a response header has been received and parsed, * returning whether the header should be processed or not. * * @param response the response containing the response line data and the headers so far * @param field the header received * @return true to process the header, false to skip processing of the header */ - public boolean onHeader(Response response, HttpField field); + boolean onHeader(Response response, HttpField field); } /** * Listener for the response headers event. */ - public interface HeadersListener extends ResponseListener + interface HeadersListener extends ResponseListener { /** - * Callback method invoked when the response headers have been received and parsed. + * Callback method invoked when all the response headers have been received and parsed. * * @param response the response containing the response line data and the headers */ - public void onHeaders(Response response); + void onHeaders(Response response); } /** - * Listener for the response content events. + * Synchronous listener for the response content events. + * + * @see AsyncContentListener */ - public interface ContentListener extends ResponseListener + interface ContentListener extends AsyncContentListener { /** - * Callback method invoked when the response content has been received. - * This method may be invoked multiple times, and the {@code content} buffer must be consumed - * before returning from this method. + * Callback method invoked when the response content has been received, parsed and there is demand. + * This method may be invoked multiple times, and the {@code content} buffer + * must be consumed (or copied) before returning from this method. * * @param response the response containing the response line data and the headers * @param content the content bytes received */ - public void onContent(Response response, ByteBuffer content); + void onContent(Response response, ByteBuffer content); + + @Override + default void onContent(Response response, ByteBuffer content, Callback callback) + { + try + { + onContent(response, content); + callback.succeeded(); + } + catch (Throwable x) + { + callback.failed(x); + } + } } - public interface AsyncContentListener extends ResponseListener + /** + * Asynchronous listener for the response content events. + * + * @see DemandedContentListener + */ + interface AsyncContentListener extends DemandedContentListener { /** - * Callback method invoked asynchronously when the response content has been received. + * Callback method invoked when the response content has been received, parsed and there is demand. + * The {@code callback} object should be succeeded to signal that the + * {@code content} buffer has been consumed and to demand more content. * * @param response the response containing the response line data and the headers * @param content the content bytes received - * @param callback the callback to call when the content is consumed. + * @param callback the callback to call when the content is consumed and to demand more content */ - public void onContent(Response response, ByteBuffer content, Callback callback); + void onContent(Response response, ByteBuffer content, Callback callback); + + @Override + default void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback) + { + onContent(response, content, Callback.from(() -> + { + callback.succeeded(); + demand.accept(1); + }, callback::failed)); + } + } + + /** + * Asynchronous listener for the response content events. + */ + interface DemandedContentListener extends ResponseListener + { + /** + * Callback method invoked before response content events. + * The {@code demand} object should be used to demand content, otherwise + * the demand remains at zero (no demand) and + * {@link #onContent(Response, LongConsumer, ByteBuffer, Callback)} will + * not be invoked even if content has been received and parsed. + * + * @param response the response containing the response line data and the headers + * @param demand the object that allows to demand content buffers + */ + default void onBeforeContent(Response response, LongConsumer demand) + { + demand.accept(1); + } + + /** + * Callback method invoked when the response content has been received. + * The {@code callback} object should be succeeded to signal that the + * {@code content} buffer has been consumed. + * The {@code demand} object should be used to demand more content, + * similarly to {@link Flow.Subscription#request(long)}. + * + * @param response the response containing the response line data and the headers + * @param demand the object that allows to demand content buffers + * @param content the content bytes received + * @param callback the callback to call when the content is consumed + */ + void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback); } /** * Listener for the response succeeded event. */ - public interface SuccessListener extends ResponseListener + interface SuccessListener extends ResponseListener { /** * Callback method invoked when the whole response has been successfully received. * * @param response the response containing the response line data and the headers */ - public void onSuccess(Response response); + void onSuccess(Response response); } /** * Listener for the response failure event. */ - public interface FailureListener extends ResponseListener + interface FailureListener extends ResponseListener { /** * Callback method invoked when the response has failed in the process of being received @@ -184,13 +254,13 @@ public interface Response * @param response the response containing data up to the point the failure happened * @param failure the failure happened */ - public void onFailure(Response response, Throwable failure); + void onFailure(Response response, Throwable failure); } /** * Listener for the request and response completed event. */ - public interface CompleteListener extends ResponseListener + interface CompleteListener extends ResponseListener { /** * Callback method invoked when the request and the response have been processed, @@ -206,68 +276,55 @@ public interface Response * * @param result the result of the request / response exchange */ - public void onComplete(Result result); + void onComplete(Result result); } /** * Listener for all response events. */ - public interface Listener extends BeginListener, HeaderListener, HeadersListener, ContentListener, AsyncContentListener, SuccessListener, FailureListener, CompleteListener + interface Listener extends BeginListener, HeaderListener, HeadersListener, ContentListener, SuccessListener, FailureListener, CompleteListener { + @Override + public default void onBegin(Response response) + { + } + + @Override + public default boolean onHeader(Response response, HttpField field) + { + return true; + } + + @Override + public default void onHeaders(Response response) + { + } + + @Override + public default void onContent(Response response, ByteBuffer content) + { + } + + @Override + public default void onSuccess(Response response) + { + } + + @Override + public default void onFailure(Response response, Throwable failure) + { + } + + @Override + public default void onComplete(Result result) + { + } + /** * An empty implementation of {@link Listener} */ - public static class Adapter implements Listener + class Adapter implements Listener { - @Override - public void onBegin(Response response) - { - } - - @Override - public boolean onHeader(Response response, HttpField field) - { - return true; - } - - @Override - public void onHeaders(Response response) - { - } - - @Override - public void onContent(Response response, ByteBuffer content) - { - } - - @Override - public void onContent(Response response, ByteBuffer content, Callback callback) - { - try - { - onContent(response, content); - callback.succeeded(); - } - catch (Throwable x) - { - callback.failed(x); - } - } - - @Override - public void onSuccess(Response response) - { - } - - @Override - public void onFailure(Response response, Throwable failure) - { - } - - @Override - public void onComplete(Result result) - { - } } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Result.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Result.java index d354c881607..913c0add69c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Result.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Result.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java index b038f552a1b..5766bf8a017 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java b/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java index 27cb983c197..732d6d843ef 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.dynamic; @@ -21,6 +21,7 @@ package org.eclipse.jetty.client.dynamic; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -28,6 +29,7 @@ import java.util.stream.Collectors; import org.eclipse.jetty.alpn.client.ALPNClientConnection; import org.eclipse.jetty.alpn.client.ALPNClientConnectionFactory; import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClientTransport; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpRequest; @@ -35,7 +37,6 @@ import org.eclipse.jetty.client.MultiplexConnectionPool; import org.eclipse.jetty.client.MultiplexHttpDestination; import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.http.HttpClientConnectionFactory; -import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; @@ -53,9 +54,9 @@ import org.eclipse.jetty.io.EndPoint; * // Configure the clientConnector. * * // Prepare the application protocols. - * HttpClientConnectionFactory.Key h1 = HttpClientConnectionFactory.HTTP; + * ClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP; * HTTP2Client http2Client = new HTTP2Client(clientConnector); - * ClientConnectionFactory.Key h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); + * ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); * * // Create the HttpClientTransportDynamic, preferring h2 over h1. * HttpClientTransport transport = new HttpClientTransportDynamic(clientConnector, h2, h1); @@ -66,19 +67,18 @@ import org.eclipse.jetty.io.EndPoint; *

    Note how in the code above the HttpClientTransportDynamic has been created with the application * protocols {@code h2} and {@code h1}, without the need to specify TLS (which is implied by the request * scheme) or ALPN (which is implied by HTTP/2 over TLS).

    - *

    When a request is first sent, a destination needs to be created, and the {@link org.eclipse.jetty.client.Origin} - * {@code (scheme, host, port)} is not enough to identify the destination because the same origin may speak - * different protocols. + *

    When a request is first sent, {@code (scheme, host, port)} are not enough to identify the destination + * because the same origin may speak different protocols. * For example, the Jetty server supports speaking clear-text {@code http/1.1} and {@code h2c} on the same port. * Imagine a client sending a {@code h2c} request to that port; this will create a destination and connections * that speak {@code h2c}; it won't be possible to use the connections from that destination to send * {@code http/1.1} requests. - * Therefore a destination is identified by a {@link org.eclipse.jetty.client.HttpDestination.Key} and - * applications can customize the creation of the destination key (for example depending on request protocol + * Therefore a destination is identified by a {@link org.eclipse.jetty.client.Origin} and + * applications can customize the creation of the origin (for example depending on request protocol * version, or request headers, or request attributes, or even request path) by overriding - * {@link #newDestinationKey(HttpRequest, Origin)}.

    + * {@link HttpClientTransport#newOrigin(HttpRequest)}.

    */ -public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTransport implements HttpClientTransport.Dynamic +public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTransport { private final List factoryInfos; private final List protocols; @@ -102,55 +102,68 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans super(connector); addBean(connector); if (factoryInfos.length == 0) - throw new IllegalArgumentException("Missing ClientConnectionFactory"); + factoryInfos = new Info[]{HttpClientConnectionFactory.HTTP11}; this.factoryInfos = Arrays.asList(factoryInfos); this.protocols = Arrays.stream(factoryInfos) - .flatMap(info -> info.getProtocols().stream()) - .distinct() - .collect(Collectors.toList()); - for (ClientConnectionFactory.Info factoryInfo : factoryInfos) - { - addBean(factoryInfo); - } + .flatMap(info -> info.getProtocols().stream()) + .distinct() + .map(p -> p.toLowerCase(Locale.ENGLISH)) + .collect(Collectors.toList()); + Arrays.stream(factoryInfos).forEach(this::addBean); setConnectionPoolFactory(destination -> - new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, 1)); + new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, 1)); } @Override - public HttpDestination.Key newDestinationKey(HttpRequest request, Origin origin) + public Origin newOrigin(HttpRequest request) { - boolean ssl = HttpScheme.HTTPS.is(request.getScheme()); + boolean ssl = HttpClient.isSchemeSecure(request.getScheme()); + String http1 = "http/1.1"; String http2 = ssl ? "h2" : "h2c"; List protocols = List.of(); - if (request.getVersion() == HttpVersion.HTTP_2) + if (request.isVersionExplicit()) { - // The application is explicitly asking for HTTP/2, so exclude HTTP/1.1. - if (this.protocols.contains(http2)) - protocols = List.of(http2); + HttpVersion version = request.getVersion(); + String desired = version == HttpVersion.HTTP_2 ? http2 : http1; + if (this.protocols.contains(desired)) + protocols = List.of(desired); } else { - // Preserve the order of protocols chosen by the application. - protocols = this.protocols.stream() - .filter(p -> p.equals("http/1.1") || p.equals(http2)) - .collect(Collectors.toList()); + if (ssl) + { + // There may be protocol negotiation, so preserve the order + // of protocols chosen by the application. + // We need to keep multiple protocols in case the protocol + // is negotiated: e.g. [http/1.1, h2] negotiates [h2], but + // here we don't know yet what will be negotiated. + protocols = this.protocols.stream() + .filter(p -> p.equals(http1) || p.equals(http2)) + .collect(Collectors.toList()); + } + else + { + // Pick the first. + protocols = List.of(this.protocols.get(0)); + } } - if (protocols.isEmpty()) - return new HttpDestination.Key(origin, null); - return new HttpDestination.Key(origin, new HttpDestination.Protocol(protocols, ssl)); + Origin.Protocol protocol = null; + if (!protocols.isEmpty()) + protocol = new Origin.Protocol(protocols, ssl && protocols.contains(http2)); + return getHttpClient().createOrigin(request, protocol); } @Override - public HttpDestination newHttpDestination(HttpDestination.Key key) + public HttpDestination newHttpDestination(Origin origin) { - return new MultiplexHttpDestination(getHttpClient(), key); + return new MultiplexHttpDestination(getHttpClient(), origin); } @Override public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY); - HttpDestination.Protocol protocol = destination.getKey().getProtocol(); + Origin.Protocol protocol = destination.getOrigin().getProtocol(); ClientConnectionFactory.Info factoryInfo; if (protocol == null) { @@ -166,12 +179,21 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans else { factoryInfo = findClientConnectionFactoryInfo(protocol.getProtocols()) - .orElseThrow(() -> new IOException("Cannot find " + ClientConnectionFactory.class.getSimpleName() + " for " + protocol)); + .orElseThrow(() -> new IOException("Cannot find " + ClientConnectionFactory.class.getSimpleName() + " for " + protocol)); } } return factoryInfo.getClientConnectionFactory().newConnection(endPoint, context); } + public void upgrade(EndPoint endPoint, Map context) + { + HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY); + Origin.Protocol protocol = destination.getOrigin().getProtocol(); + Info info = findClientConnectionFactoryInfo(protocol.getProtocols()) + .orElseThrow(() -> new IllegalStateException("Cannot find " + ClientConnectionFactory.class.getSimpleName() + " to upgrade to " + protocol)); + info.upgrade(endPoint, context); + } + protected Connection newNegotiatedConnection(EndPoint endPoint, Map context) throws IOException { try @@ -184,7 +206,7 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans throw new IOException("Could not negotiate protocol among " + alpnConnection.getProtocols()); List protocols = List.of(protocol); Info factoryInfo = findClientConnectionFactoryInfo(protocols) - .orElseThrow(() -> new IOException("Cannot find " + ClientConnectionFactory.class.getSimpleName() + " for negotiated protocol " + protocol)); + .orElseThrow(() -> new IOException("Cannot find " + ClientConnectionFactory.class.getSimpleName() + " for negotiated protocol " + protocol)); return factoryInfo.getClientConnectionFactory().newConnection(endPoint, context); } catch (Throwable failure) @@ -197,7 +219,7 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans private Optional findClientConnectionFactoryInfo(List protocols) { return factoryInfos.stream() - .filter(info -> info.matches(protocols)) - .findFirst(); + .filter(info -> info.matches(protocols)) + .findFirst(); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java index 6bd8cd84d9d..871c6d7f382 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java @@ -1,31 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; -import java.util.Locale; import java.util.concurrent.atomic.LongAdder; import org.eclipse.jetty.client.HttpChannel; import org.eclipse.jetty.client.HttpExchange; -import org.eclipse.jetty.client.HttpRequest; -import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.HttpResponseException; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.http.HttpFields; @@ -91,42 +87,6 @@ public class HttpChannelOverHTTP extends HttpChannel connection.release(); } - @Override - public Result exchangeTerminating(HttpExchange exchange, Result result) - { - if (result.isFailed()) - return result; - - HttpResponse response = exchange.getResponse(); - - if ((response.getVersion() == HttpVersion.HTTP_1_1) && - (response.getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101)) - { - String nextConnection = response.getHeaders().get(HttpHeader.CONNECTION); - if ((nextConnection == null) || !nextConnection.toLowerCase(Locale.US).contains("upgrade")) - { - return new Result(result, new HttpResponseException("101 Switching Protocols without Connection: Upgrade not supported", response)); - } - - // Upgrade Response - HttpRequest request = exchange.getRequest(); - HttpConnectionUpgrader upgrader = (HttpConnectionUpgrader)request.getConversation().getAttribute(HttpConnectionUpgrader.class.getName()); - if (upgrader != null) - { - try - { - upgrader.upgrade(response, getHttpConnection()); - } - catch (Throwable x) - { - return new Result(result, x); - } - } - } - - return result; - } - public void receive() { inMessages.increment(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientConnectionFactory.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientConnectionFactory.java index fca30689e9e..418616175f6 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientConnectionFactory.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; @@ -21,12 +21,8 @@ package org.eclipse.jetty.client.http; import java.util.List; import java.util.Map; -import org.eclipse.jetty.client.HttpClientTransport; -import org.eclipse.jetty.client.HttpDestination; -import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.Promise; public class HttpClientConnectionFactory implements ClientConnectionFactory { @@ -35,9 +31,7 @@ public class HttpClientConnectionFactory implements ClientConnectionFactory @Override public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) { - HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); - @SuppressWarnings("unchecked") - Promise promise = (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); - return customize(new HttpConnectionOverHTTP(endPoint, destination, promise), context); + HttpConnectionOverHTTP connection = new HttpConnectionOverHTTP(endPoint, context); + return customize(connection, context); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java index da1aaf23d83..e880afba89b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java @@ -1,40 +1,49 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; import java.io.IOException; +import java.util.List; import java.util.Map; import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport; import org.eclipse.jetty.client.DuplexConnectionPool; import org.eclipse.jetty.client.DuplexHttpDestination; import org.eclipse.jetty.client.HttpDestination; -import org.eclipse.jetty.client.api.Connection; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.Origin; +import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.ProcessorUtils; -import org.eclipse.jetty.util.Promise; +import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @ManagedObject("The HTTP/1.1 client transport") public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTransport { + public static final Origin.Protocol HTTP11 = new Origin.Protocol(List.of("http/1.1"), false); + + private final ClientConnectionFactory factory = new HttpClientConnectionFactory(); + private int headerCacheSize = 1024; + private boolean headerCacheCaseSensitive; + public HttpClientTransportOverHTTP() { this(Math.max(1, ProcessorUtils.availableProcessors() / 2)); @@ -53,25 +62,45 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran } @Override - public HttpDestination newHttpDestination(HttpDestination.Key key) + public Origin newOrigin(HttpRequest request) { - return new DuplexHttpDestination(getHttpClient(), key); + return getHttpClient().createOrigin(request, HTTP11); + } + + @Override + public HttpDestination newHttpDestination(Origin origin) + { + return new DuplexHttpDestination(getHttpClient(), origin); } @Override public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { - HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY); - @SuppressWarnings("unchecked") - Promise promise = (Promise)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY); - org.eclipse.jetty.io.Connection connection = newHttpConnection(endPoint, destination, promise); + var connection = factory.newConnection(endPoint, context); if (LOG.isDebugEnabled()) LOG.debug("Created {}", connection); - return customize(connection, context); + return connection; } - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + @ManagedAttribute("The maximum allowed size in bytes for an HTTP header field cache") + public int getHeaderCacheSize() { - return new HttpConnectionOverHTTP(endPoint, destination, promise); + return headerCacheSize; + } + + public void setHeaderCacheSize(int headerCacheSize) + { + this.headerCacheSize = headerCacheSize; + } + + @ManagedAttribute("Whether the header field cache is case sensitive") + public boolean isHeaderCacheCaseSensitive() + { + return headerCacheCaseSensitive; + } + + public void setHeaderCacheCaseSensitive(boolean headerCacheCaseSensitive) + { + this.headerCacheCaseSensitive = headerCacheCaseSensitive; } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java index fcc2bb2b67f..1375d799458 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java @@ -1,58 +1,82 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousCloseException; +import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.LongAdder; +import org.eclipse.jetty.client.HttpClientTransport; import org.eclipse.jetty.client.HttpConnection; +import org.eclipse.jetty.client.HttpConversation; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpExchange; +import org.eclipse.jetty.client.HttpProxy; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.IConnection; import org.eclipse.jetty.client.SendFailure; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Sweeper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpConnectionOverHTTP extends AbstractConnection implements IConnection, org.eclipse.jetty.io.Connection.UpgradeFrom, Sweeper.Sweepable { - private static final Logger LOG = Log.getLogger(HttpConnectionOverHTTP.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpConnectionOverHTTP.class); private final AtomicBoolean closed = new AtomicBoolean(); private final AtomicInteger sweeps = new AtomicInteger(); private final Promise promise; private final Delegate delegate; private final HttpChannelOverHTTP channel; - private long idleTimeout; - private final LongAdder bytesIn = new LongAdder(); private final LongAdder bytesOut = new LongAdder(); + private long idleTimeout; + + public HttpConnectionOverHTTP(EndPoint endPoint, Map context) + { + this(endPoint, destinationFrom(context), promiseFrom(context)); + } + + private static HttpDestination destinationFrom(Map context) + { + return (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + } + + @SuppressWarnings("unchecked") + private static Promise promiseFrom(Map context) + { + return (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); + } public HttpConnectionOverHTTP(EndPoint endPoint, HttpDestination destination, Promise promise) { @@ -141,26 +165,21 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne public boolean onIdleExpired() { long idleTimeout = getEndPoint().getIdleTimeout(); - boolean close = delegate.onIdleTimeout(idleTimeout); + boolean close = onIdleTimeout(idleTimeout); if (close) close(new TimeoutException("Idle timeout " + idleTimeout + " ms")); return false; } + protected boolean onIdleTimeout(long idleTimeout) + { + return delegate.onIdleTimeout(idleTimeout); + } + @Override public void onFillable() { - HttpExchange exchange = channel.getHttpExchange(); - if (exchange != null) - { - channel.receive(); - } - else - { - // If there is no exchange, then could be either a remote close, - // or garbage bytes; in both cases we close the connection - close(); - } + channel.receive(); } @Override @@ -256,6 +275,42 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne return send(channel, exchange); } + @Override + protected void normalizeRequest(Request request) + { + super.normalizeRequest(request); + + if (request instanceof HttpProxy.TunnelRequest) + { + long connectTimeout = getHttpClient().getConnectTimeout(); + request.timeout(connectTimeout, TimeUnit.MILLISECONDS) + .idleTimeout(2 * connectTimeout, TimeUnit.MILLISECONDS); + } + + HttpRequest httpRequest = (HttpRequest)request; + HttpConversation conversation = httpRequest.getConversation(); + HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName()); + if (upgrader == null) + { + if (request instanceof HttpUpgrader.Factory) + { + upgrader = ((HttpUpgrader.Factory)request).newHttpUpgrader(HttpVersion.HTTP_1_1); + conversation.setAttribute(HttpUpgrader.class.getName(), upgrader); + upgrader.prepare(httpRequest); + } + else + { + String protocol = request.getHeaders().get(HttpHeader.UPGRADE); + if (protocol != null) + { + upgrader = new ProtocolHttpUpgrader(getHttpDestination(), protocol); + conversation.setAttribute(HttpUpgrader.class.getName(), upgrader); + upgrader.prepare(httpRequest); + } + } + } + } + @Override public void close() { diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionUpgrader.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionUpgrader.java deleted file mode 100644 index e1da68d11c5..00000000000 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionUpgrader.java +++ /dev/null @@ -1,26 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.client.http; - -import org.eclipse.jetty.client.HttpResponse; - -public interface HttpConnectionUpgrader -{ - public void upgrade(HttpResponse response, HttpConnectionOverHTTP connection); -} diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java index 0df897bd79b..4bd4307fed1 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; @@ -22,6 +22,7 @@ import java.io.EOFException; import java.nio.ByteBuffer; import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.HttpClientTransport; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpReceiver; import org.eclipse.jetty.client.HttpResponse; @@ -34,20 +35,29 @@ import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.RetainableByteBuffer; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.CompletableCallback; +import org.eclipse.jetty.util.Callback; public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.ResponseHandler { private final HttpParser parser; - private ByteBuffer buffer; + private RetainableByteBuffer networkBuffer; private boolean shutdown; private boolean complete; public HttpReceiverOverHTTP(HttpChannelOverHTTP channel) { super(channel); - parser = new HttpParser(this, -1, channel.getHttpDestination().getHttpClient().getHttpCompliance()); + HttpClient httpClient = channel.getHttpDestination().getHttpClient(); + parser = new HttpParser(this, -1, httpClient.getHttpCompliance()); + HttpClientTransport transport = httpClient.getTransport(); + if (transport instanceof HttpClientTransportOverHTTP) + { + HttpClientTransportOverHTTP httpTransport = (HttpClientTransportOverHTTP)transport; + parser.setHeaderCacheSize(httpTransport.getHeaderCacheSize()); + parser.setHeaderCacheCaseSensitive(httpTransport.isHeaderCacheCaseSensitive()); + } } @Override @@ -63,41 +73,68 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res protected ByteBuffer getResponseBuffer() { - return buffer; + return networkBuffer == null ? null : networkBuffer.getBuffer(); } + @Override public void receive() { - if (buffer == null) - acquireBuffer(); + if (networkBuffer == null) + acquireNetworkBuffer(); process(); } - private void acquireBuffer() + private void acquireNetworkBuffer() { - HttpClient client = getHttpDestination().getHttpClient(); - ByteBufferPool bufferPool = client.getByteBufferPool(); - buffer = bufferPool.acquire(client.getResponseBufferSize(), true); + networkBuffer = newNetworkBuffer(); + if (LOG.isDebugEnabled()) + LOG.debug("Acquired {}", networkBuffer); } - private void releaseBuffer() + private void reacquireNetworkBuffer() { - if (buffer == null) + RetainableByteBuffer currentBuffer = networkBuffer; + if (currentBuffer == null) throw new IllegalStateException(); - if (BufferUtil.hasContent(buffer)) + + if (currentBuffer.hasRemaining()) throw new IllegalStateException(); + + currentBuffer.release(); + networkBuffer = newNetworkBuffer(); + if (LOG.isDebugEnabled()) + LOG.debug("Reacquired {} <- {}", currentBuffer, networkBuffer); + } + + private RetainableByteBuffer newNetworkBuffer() + { HttpClient client = getHttpDestination().getHttpClient(); ByteBufferPool bufferPool = client.getByteBufferPool(); - bufferPool.release(buffer); - buffer = null; + boolean direct = client.isUseInputDirectByteBuffers(); + return new RetainableByteBuffer(bufferPool, client.getResponseBufferSize(), direct); + } + + private void releaseNetworkBuffer() + { + if (networkBuffer == null) + throw new IllegalStateException(); + if (networkBuffer.hasRemaining()) + throw new IllegalStateException(); + networkBuffer.release(); + if (LOG.isDebugEnabled()) + LOG.debug("Released {}", networkBuffer); + networkBuffer = null; } protected ByteBuffer onUpgradeFrom() { - if (BufferUtil.hasContent(buffer)) + if (networkBuffer.hasRemaining()) { - ByteBuffer upgradeBuffer = ByteBuffer.allocate(buffer.remaining()); - upgradeBuffer.put(buffer).flip(); + HttpClient client = getHttpDestination().getHttpClient(); + ByteBuffer upgradeBuffer = BufferUtil.allocate(networkBuffer.remaining(), client.isUseInputDirectByteBuffers()); + BufferUtil.clearToFill(upgradeBuffer); + BufferUtil.put(networkBuffer.getBuffer(), upgradeBuffer); + BufferUtil.flipToFlush(upgradeBuffer, 0); return upgradeBuffer; } return null; @@ -105,45 +142,48 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res private void process() { + HttpConnectionOverHTTP connection = getHttpConnection(); + EndPoint endPoint = connection.getEndPoint(); try { - HttpConnectionOverHTTP connection = getHttpConnection(); - EndPoint endPoint = connection.getEndPoint(); while (true) { - boolean upgraded = connection != endPoint.getConnection(); + // Always parse even empty buffers to advance the parser. + boolean stopProcessing = parse(); // Connection may be closed or upgraded in a parser callback. + boolean upgraded = connection != endPoint.getConnection(); if (connection.isClosed() || upgraded) { if (LOG.isDebugEnabled()) LOG.debug("{} {}", connection, upgraded ? "upgraded" : "closed"); - releaseBuffer(); + releaseNetworkBuffer(); return; } - if (parse()) + if (stopProcessing) return; - int read = endPoint.fill(buffer); + if (networkBuffer.getReferences() > 1) + reacquireNetworkBuffer(); + + int read = endPoint.fill(networkBuffer.getBuffer()); if (LOG.isDebugEnabled()) - LOG.debug("Read {} bytes {} from {}", read, BufferUtil.toDetailString(buffer), endPoint); + LOG.debug("Read {} bytes in {} from {}", read, networkBuffer, endPoint); if (read > 0) { connection.addBytesIn(read); - if (parse()) - return; } else if (read == 0) { - releaseBuffer(); + releaseNetworkBuffer(); fillInterested(); return; } else { - releaseBuffer(); + releaseNetworkBuffer(); shutdown(); return; } @@ -152,16 +192,15 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); - BufferUtil.clear(buffer); - if (buffer != null) - releaseBuffer(); + LOG.debug("Unable to fill from endpoint {}", endPoint, x); + networkBuffer.clear(); + releaseNetworkBuffer(); failAndClose(x); } } /** - * Parses a HTTP response in the receivers buffer. + * Parses an HTTP response in the receivers buffer. * * @return true to indicate that parsing should be interrupted (and will be resumed by another thread). */ @@ -169,20 +208,20 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res { while (true) { - boolean handle = parser.parseNext(buffer); + boolean handle = parser.parseNext(networkBuffer.getBuffer()); boolean complete = this.complete; this.complete = false; if (LOG.isDebugEnabled()) - LOG.debug("Parsed {}, remaining {} {}", handle, buffer.remaining(), parser); + LOG.debug("Parsed {}, remaining {} {}", handle, networkBuffer.remaining(), parser); if (handle) return true; - if (!buffer.hasRemaining()) + if (networkBuffer.isEmpty()) return false; if (complete) { if (LOG.isDebugEnabled()) - LOG.debug("Discarding unexpected content after response: {}", BufferUtil.toDetailString(buffer)); - BufferUtil.clear(buffer); + LOG.debug("Discarding unexpected content after response: {}", networkBuffer); + networkBuffer.clear(); return false; } } @@ -215,32 +254,18 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res } @Override - public int getHeaderCacheSize() - { - // TODO get from configuration - return 4096; - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - // TODO get from configuration - return false; - } - - @Override - public boolean startResponse(HttpVersion version, int status, String reason) + public void startResponse(HttpVersion version, int status, String reason) { HttpExchange exchange = getHttpExchange(); if (exchange == null) - return false; + return; String method = exchange.getRequest().getMethod(); parser.setHeadResponse(HttpMethod.HEAD.is(method) || (HttpMethod.CONNECT.is(method) && status == HttpStatus.OK_200)); exchange.getResponse().version(version).status(status).reason(reason); - return !responseBegin(exchange); + responseBegin(exchange); } @Override @@ -260,6 +285,8 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res if (exchange == null) return false; + // Store the EndPoint is case of upgrades, tunnels, etc. + exchange.getRequest().getConversation().setAttribute(EndPoint.class.getName(), getHttpConnection().getEndPoint()); return !responseHeaders(exchange); } @@ -270,26 +297,8 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res if (exchange == null) return false; - CompletableCallback callback = new CompletableCallback() - { - @Override - public void resume() - { - if (LOG.isDebugEnabled()) - LOG.debug("Content consumed asynchronously, resuming processing"); - process(); - } - - @Override - public void abort(Throwable x) - { - failAndClose(x); - } - }; - // Do not short circuit these calls. - boolean proceed = responseContent(exchange, buffer, callback); - boolean async = callback.tryComplete(); - return !proceed || async; + networkBuffer.retain(); + return !responseContent(exchange, buffer, Callback.from(networkBuffer::release, this::failAndClose)); } @Override @@ -327,8 +336,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res if (status == HttpStatus.SWITCHING_PROTOCOLS_101) return true; - if (HttpMethod.CONNECT.is(exchange.getRequest().getMethod()) && - status == HttpStatus.OK_200) + if (HttpMethod.CONNECT.is(exchange.getRequest().getMethod()) && status == HttpStatus.OK_200) return true; return false; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java index b8e23ef058d..b3e88b836df 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; @@ -35,17 +35,19 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpSenderOverHTTP extends HttpSender { + private static final Logger LOG = LoggerFactory.getLogger(HttpSenderOverHTTP.class); + private final HttpGenerator generator = new HttpGenerator(); - private final HttpClient httpClient; private boolean shutdown; public HttpSenderOverHTTP(HttpChannelOverHTTP channel) { super(channel); - httpClient = channel.getHttpDestination().getHttpClient(); } @Override @@ -64,7 +66,7 @@ public class HttpSenderOverHTTP extends HttpSender catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Unable to send headers on exchange {}", exchange, x); callback.failed(x); } } @@ -74,7 +76,9 @@ public class HttpSenderOverHTTP extends HttpSender { try { + HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient(); ByteBufferPool bufferPool = httpClient.getByteBufferPool(); + boolean useDirectByteBuffers = httpClient.isUseOutputDirectByteBuffers(); ByteBuffer chunk = null; while (true) { @@ -89,12 +93,12 @@ public class HttpSenderOverHTTP extends HttpSender { case NEED_CHUNK: { - chunk = bufferPool.acquire(HttpGenerator.CHUNK_SIZE, false); + chunk = bufferPool.acquire(HttpGenerator.CHUNK_SIZE, useDirectByteBuffers); break; } case NEED_CHUNK_TRAILER: { - chunk = bufferPool.acquire(httpClient.getRequestBufferSize(), false); + chunk = bufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers); break; } case FLUSH: @@ -133,7 +137,7 @@ public class HttpSenderOverHTTP extends HttpSender catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Unable to send content on {}", exchange, x); callback.failed(x); } } @@ -218,21 +222,30 @@ public class HttpSenderOverHTTP extends HttpSender chunkBuffer == null ? -1 : chunkBuffer.remaining(), contentBuffer == null ? -1 : contentBuffer.remaining(), result, generator); + HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient(); + ByteBufferPool byteBufferPool = httpClient.getByteBufferPool(); + boolean useDirectByteBuffers = httpClient.isUseOutputDirectByteBuffers(); switch (result) { case NEED_HEADER: { - headerBuffer = httpClient.getByteBufferPool().acquire(httpClient.getRequestBufferSize(), false); + headerBuffer = byteBufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers); break; } + case HEADER_OVERFLOW: + { + httpClient.getByteBufferPool().release(headerBuffer); + headerBuffer = null; + throw new IllegalArgumentException("Request header too large"); + } case NEED_CHUNK: { - chunkBuffer = httpClient.getByteBufferPool().acquire(HttpGenerator.CHUNK_SIZE, false); + chunkBuffer = byteBufferPool.acquire(HttpGenerator.CHUNK_SIZE, useDirectByteBuffers); break; } case NEED_CHUNK_TRAILER: { - chunkBuffer = httpClient.getByteBufferPool().acquire(httpClient.getRequestBufferSize(), false); + chunkBuffer = byteBufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers); break; } case FLUSH: @@ -288,7 +301,6 @@ public class HttpSenderOverHTTP extends HttpSender public void failed(Throwable x) { release(); - callback.failed(x); super.failed(x); } @@ -299,8 +311,16 @@ public class HttpSenderOverHTTP extends HttpSender callback.succeeded(); } + @Override + protected void onCompleteFailure(Throwable cause) + { + super.onCompleteFailure(cause); + callback.failed(cause); + } + private void release() { + HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient(); ByteBufferPool bufferPool = httpClient.getByteBufferPool(); if (!BufferUtil.isTheEmptyBuffer(headerBuffer)) bufferPool.release(headerBuffer); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/ProtocolHttpUpgrader.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/ProtocolHttpUpgrader.java new file mode 100644 index 00000000000..688b424ac18 --- /dev/null +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/ProtocolHttpUpgrader.java @@ -0,0 +1,101 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.client.http; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.HttpClientTransport; +import org.eclipse.jetty.client.HttpDestination; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.HttpUpgrader; +import org.eclipse.jetty.client.Origin; +import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Promise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

    A HttpUpgrader that upgrades to a given protocol.

    + *

    Works in conjunction with {@link HttpClientTransportDynamic} + * so that the protocol to upgrade to must be one of the application + * protocols supported by HttpClientTransportDynamic.

    + *

    + */ +public class ProtocolHttpUpgrader implements HttpUpgrader +{ + private static final Logger LOG = LoggerFactory.getLogger(ProtocolHttpUpgrader.class); + + private final HttpDestination destination; + private final String protocol; + + public ProtocolHttpUpgrader(HttpDestination destination, String protocol) + { + this.destination = destination; + this.protocol = protocol; + } + + @Override + public void prepare(HttpRequest request) + { + } + + @Override + public void upgrade(HttpResponse response, EndPoint endPoint, Callback callback) + { + if (response.getHeaders().contains(HttpHeader.UPGRADE, protocol)) + { + HttpClient httpClient = destination.getHttpClient(); + HttpClientTransport transport = httpClient.getTransport(); + if (transport instanceof HttpClientTransportDynamic) + { + HttpClientTransportDynamic dynamicTransport = (HttpClientTransportDynamic)transport; + + Origin origin = destination.getOrigin(); + Origin newOrigin = new Origin(origin.getScheme(), origin.getAddress(), origin.getTag(), new Origin.Protocol(List.of(protocol), false)); + HttpDestination newDestination = httpClient.resolveDestination(newOrigin); + + Map context = new HashMap<>(); + context.put(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY, newDestination); + context.put(HttpResponse.class.getName(), response); + context.put(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY, Promise.from(y -> callback.succeeded(), callback::failed)); + + if (LOG.isDebugEnabled()) + LOG.debug("Upgrading {} on {}", response.getRequest(), endPoint); + + dynamicTransport.upgrade(endPoint, context); + } + else + { + callback.failed(new HttpResponseException(HttpClientTransportDynamic.class.getName() + " required to upgrade to: " + protocol, response)); + } + } + else + { + callback.failed(new HttpResponseException("Not an upgrade to: " + protocol, response)); + } + } +} diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/jmx/HttpClientMBean.java b/jetty-client/src/main/java/org/eclipse/jetty/client/jmx/HttpClientMBean.java index dac274d4ccf..f3677af8586 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/jmx/HttpClientMBean.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/jmx/HttpClientMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.jmx; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java b/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java index af26327a722..feca2d5e7ae 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/proxy/ProxyProtocolClientConnectionFactory.java b/jetty-client/src/main/java/org/eclipse/jetty/client/proxy/ProxyProtocolClientConnectionFactory.java index e60c0d90aa6..4da66ec27f5 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/proxy/ProxyProtocolClientConnectionFactory.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/proxy/ProxyProtocolClientConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.proxy; @@ -36,8 +36,8 @@ import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ProxyProtocolClientConnectionFactory implements ClientConnectionFactory { @@ -61,7 +61,7 @@ public class ProxyProtocolClientConnectionFactory implements ClientConnectionFac private class ProxyProtocolConnection extends AbstractConnection implements Callback { - private final Logger log = Log.getLogger(ProxyProtocolConnection.class); + private final Logger log = LoggerFactory.getLogger(ProxyProtocolConnection.class); private final Map context; public ProxyProtocolConnection(EndPoint endPoint, Executor executor, Map context) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractAuthentication.java index c0475d22ff5..40c47e2b6c3 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractTypedContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractTypedContentProvider.java index e2eba112dc7..679de25be1b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractTypedContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/AbstractTypedContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java index be22484dd0c..ed3665074f0 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BufferingResponseListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BufferingResponseListener.java index 68e3313c416..a605b5057ad 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BufferingResponseListener.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BufferingResponseListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java index 845d6eb0a33..1342dc6cc0c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/ByteBufferContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java index 534b98ed7fa..631311fdb37 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BytesContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java index 29b8ed9a925..174b2e25356 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DeferredContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java index fd095cb6805..466ea8168b6 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java index 8e04561ab2d..280494282d8 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FutureResponseListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FutureResponseListener.java index f848340fbd6..04e3d041650 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FutureResponseListener.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FutureResponseListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java index 7077dbbe130..2f81b71f94b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -28,8 +28,8 @@ import java.util.NoSuchElementException; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A {@link ContentProvider} for an {@link InputStream}. @@ -53,7 +53,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class InputStreamContentProvider implements ContentProvider, Callback, Closeable { - private static final Logger LOG = Log.getLogger(InputStreamContentProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(InputStreamContentProvider.class); private final InputStreamContentProviderIterator iterator = new InputStreamContentProviderIterator(); private final InputStream stream; @@ -131,7 +131,7 @@ public class InputStreamContentProvider implements ContentProvider, Callback, Cl } catch (IOException x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } } @@ -199,7 +199,7 @@ public class InputStreamContentProvider implements ContentProvider, Callback, Cl catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Failed to read", x); if (failure == null) { failure = x; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamResponseListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamResponseListener.java index c31a68b7d43..94d7dac43b8 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamResponseListener.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/InputStreamResponseListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -41,8 +41,8 @@ import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Implementation of {@link Listener} that produces an {@link InputStream} @@ -75,7 +75,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class InputStreamResponseListener extends Listener.Adapter { - private static final Logger LOG = Log.getLogger(InputStreamResponseListener.class); + private static final Logger LOG = LoggerFactory.getLogger(InputStreamResponseListener.class); private static final DeferredContentProvider.Chunk EOF = new DeferredContentProvider.Chunk(BufferUtil.EMPTY_BUFFER, Callback.NOOP); private final Object lock = this; private final CountDownLatch responseLatch = new CountDownLatch(1); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java index f540ade09c5..8252e3e7413 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -38,8 +38,9 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.IO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    A {@link ContentProvider} for form uploads with the {@code "multipart/form-data"} @@ -65,7 +66,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class MultiPartContentProvider extends AbstractTypedContentProvider implements AsyncContentProvider, Closeable { - private static final Logger LOG = Log.getLogger(MultiPartContentProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(MultiPartContentProvider.class); private static final byte[] COLON_SPACE_BYTES = new byte[]{':', ' '}; private static final byte[] CR_LF_BYTES = new byte[]{'\r', '\n'}; @@ -345,10 +346,16 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple if (iterator.hasNext()) return iterator.next(); ++index; - if (index == parts.size()) - state = State.LAST_BOUNDARY; - else + if (index < parts.size()) + { state = State.MIDDLE_BOUNDARY; + if (iterator instanceof Closeable) + IO.close((Closeable)iterator); + } + else + { + state = State.LAST_BOUNDARY; + } break; } case MIDDLE_BOUNDARY: @@ -383,14 +390,14 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple @Override public void succeeded() { - if (iterator instanceof Callback) + if (state == State.CONTENT && iterator instanceof Callback) ((Callback)iterator).succeeded(); } @Override public void failed(Throwable x) { - if (iterator instanceof Callback) + if (state == State.CONTENT && iterator instanceof Callback) ((Callback)iterator).failed(x); } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java index 096c4a85c17..edffa00bd68 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/OutputStreamContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java index aa562e5111b..ffa41c752bb 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/PathContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -32,8 +32,9 @@ import java.util.NoSuchElementException; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.BufferUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    A {@link ContentProvider} for files using JDK 7's {@code java.nio.file} APIs.

    @@ -45,12 +46,13 @@ import org.eclipse.jetty.util.log.Logger; */ public class PathContentProvider extends AbstractTypedContentProvider { - private static final Logger LOG = Log.getLogger(PathContentProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(PathContentProvider.class); private final Path filePath; private final long fileSize; private final int bufferSize; private ByteBufferPool bufferPool; + private boolean useDirectByteBuffers = true; public PathContentProvider(Path filePath) throws IOException { @@ -101,6 +103,16 @@ public class PathContentProvider extends AbstractTypedContentProvider this.bufferPool = byteBufferPool; } + public boolean isUseDirectByteBuffers() + { + return useDirectByteBuffers; + } + + public void setUseDirectByteBuffers(boolean useDirectByteBuffers) + { + this.useDirectByteBuffers = useDirectByteBuffers; + } + @Override public Iterator iterator() { @@ -127,8 +139,8 @@ public class PathContentProvider extends AbstractTypedContentProvider if (channel == null) { buffer = bufferPool == null - ? ByteBuffer.allocateDirect(bufferSize) - : bufferPool.acquire(bufferSize, true); + ? BufferUtil.allocate(bufferSize, isUseDirectByteBuffers()) + : bufferPool.acquire(bufferSize, isUseDirectByteBuffers()); channel = Files.newByteChannel(filePath, StandardOpenOption.READ); if (LOG.isDebugEnabled()) LOG.debug("Opened file {}", filePath); @@ -171,7 +183,7 @@ public class PathContentProvider extends AbstractTypedContentProvider } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java index b8dc609f011..5f3d7742604 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -41,13 +41,13 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.Attributes; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import org.ietf.jgss.Oid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    Implementation of the SPNEGO (or "Negotiate") authentication defined in RFC 4559.

    @@ -61,7 +61,7 @@ import org.ietf.jgss.Oid; */ public class SPNEGOAuthentication extends AbstractAuthentication { - private static final Logger LOG = Log.getLogger(SPNEGOAuthentication.class); + private static final Logger LOG = LoggerFactory.getLogger(SPNEGOAuthentication.class); private static final String NEGOTIATE = HttpHeader.NEGOTIATE.asString(); private final GSSManager gssManager = GSSManager.getInstance(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java index 0489e76e4c6..2b3f1f4598b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/StringContentProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java index af36359f78e..4bdd6718eda 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java index 6aae24e7b0e..085ce79e211 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -196,7 +196,7 @@ public abstract class AbstractHttpClientServerTest private void configure(SslContextFactory ssl) { - Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore.jks"); + Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore.p12"); ssl.setKeyStorePath(keystorePath.toString()); ssl.setKeyStorePassword("storepwd"); } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java index ca6137238f4..8f3d2144e92 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -23,7 +23,6 @@ import java.io.InterruptedIOException; import java.nio.ByteBuffer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -49,13 +48,13 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest { @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ClientConnectionClose_ServerConnectionClose_ClientClosesAfterExchange(Scenario scenario) throws Exception + public void testClientConnectionCloseServerConnectionCloseClientClosesAfterExchange(Scenario scenario) throws Exception { byte[] data = new byte[128 * 1024]; start(scenario, new AbstractHandler() { @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); @@ -85,33 +84,34 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); - DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - - ContentResponse response = client.newRequest(host, port) + var request = client.newRequest(host, port) .scheme(scenario.getScheme()) .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) .content(new StringContentProvider("0")) - .onRequestSuccess(request -> + .onRequestSuccess(r -> { + HttpDestination destination = (HttpDestination)client.resolveDestination(r); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)connectionPool.getActiveConnections().iterator().next(); assertFalse(connection.getEndPoint().isOutputShutdown()); - }) - .send(); + }); + ContentResponse response = request.send(); assertEquals(HttpStatus.OK_200, response.getStatus()); assertArrayEquals(data, response.getContent()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ClientConnectionClose_ServerDoesNotRespond_ClientIdleTimeout(Scenario scenario) throws Exception + public void testClientConnectionCloseServerDoesNotRespondClientIdleTimeout(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) { baseRequest.setHandled(true); request.startAsync(); @@ -122,39 +122,40 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); - DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - CountDownLatch resultLatch = new CountDownLatch(1); long idleTimeout = 1000; - client.newRequest(host, port) + var request = client.newRequest(host, port) .scheme(scenario.getScheme()) .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) .idleTimeout(idleTimeout, TimeUnit.MILLISECONDS) - .onRequestSuccess(request -> + .onRequestSuccess(r -> { + HttpDestination destination = (HttpDestination)client.resolveDestination(r); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)connectionPool.getActiveConnections().iterator().next(); assertFalse(connection.getEndPoint().isOutputShutdown()); - }) - .send(result -> - { - if (result.isFailed()) - resultLatch.countDown(); }); + request.send(result -> + { + if (result.isFailed()) + resultLatch.countDown(); + }); assertTrue(resultLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS)); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ClientConnectionClose_ServerPartialResponse_ClientIdleTimeout(Scenario scenario) throws Exception + public void testClientConnectionCloseServerPartialResponseClientIdleTimeout(Scenario scenario) throws Exception { long idleTimeout = 1000; start(scenario, new AbstractHandler() { @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); @@ -183,41 +184,42 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); - DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - DeferredContentProvider content = new DeferredContentProvider(ByteBuffer.allocate(8)); CountDownLatch resultLatch = new CountDownLatch(1); - client.newRequest(host, port) + var request = client.newRequest(host, port) .scheme(scenario.getScheme()) .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) .content(content) .idleTimeout(idleTimeout, TimeUnit.MILLISECONDS) - .onRequestSuccess(request -> + .onRequestSuccess(r -> { + HttpDestination destination = (HttpDestination)client.resolveDestination(r); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)connectionPool.getActiveConnections().iterator().next(); assertFalse(connection.getEndPoint().isOutputShutdown()); - }) - .send(result -> - { - if (result.isFailed()) - resultLatch.countDown(); }); + request.send(result -> + { + if (result.isFailed()) + resultLatch.countDown(); + }); content.offer(ByteBuffer.allocate(8)); content.close(); assertTrue(resultLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS)); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ClientConnectionClose_ServerNoConnectionClose_ClientCloses(Scenario scenario) throws Exception + public void testClientConnectionCloseServerNoConnectionCloseClientCloses(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); response.setContentLength(0); @@ -238,21 +240,22 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); - DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - - ContentResponse response = client.newRequest(host, port) + var request = client.newRequest(host, port) .scheme(scenario.getScheme()) .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) - .onRequestSuccess(request -> + .onRequestSuccess(r -> { + HttpDestination destination = (HttpDestination)client.resolveDestination(r); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)connectionPool.getActiveConnections().iterator().next(); assertFalse(connection.getEndPoint().isOutputShutdown()); }) - .onResponseHeaders(r -> r.getHeaders().remove(HttpHeader.CONNECTION)) - .send(); + .onResponseHeaders(r -> r.getHeaders().remove(HttpHeader.CONNECTION)); + ContentResponse response = request.send(); assertEquals(HttpStatus.OK_200, response.getStatus()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java index 39eb9c52f62..c90329b07a2 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java index 8c230c80858..2920cdd54dd 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java b/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java index 1287ed445e1..3a1513b1555 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -26,10 +26,10 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; -public class EmptyServerHandler extends AbstractHandler.ErrorDispatchHandler +public class EmptyServerHandler extends AbstractHandler { @Override - protected final void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public final void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { jettyRequest.setHandled(true); service(target, jettyRequest, request, response); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java index 7be1119be48..a9e25c57371 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java index 99614a56d2d..fc1edcc5eff 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -37,7 +37,6 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -48,7 +47,6 @@ import static org.junit.jupiter.api.Assertions.fail; * This test class runs tests to make sure that hostname verification (http://www.ietf.org/rfc/rfc2818.txt * section 3.1) is configurable in SslContextFactory and works as expected. */ -@Disabled public class HostnameVerificationTest { private SslContextFactory.Client clientSslContextFactory = new SslContextFactory.Client(); @@ -64,7 +62,7 @@ public class HostnameVerificationTest server = new Server(serverThreads); SslContextFactory.Server serverSslContextFactory = new SslContextFactory.Server(); - serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); serverSslContextFactory.setKeyStorePassword("storepwd"); connector = new ServerConnector(server, serverSslContextFactory); server.addConnector(connector); @@ -80,7 +78,7 @@ public class HostnameVerificationTest server.start(); // The keystore contains a hostname which doesn't match localhost - clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); clientSslContextFactory.setKeyStorePassword("storepwd"); ClientConnector clientConnector = new ClientConnector(); @@ -100,18 +98,15 @@ public class HostnameVerificationTest { client.stop(); server.stop(); - server.join(); } /** * This test is supposed to verify that hostname verification works as described in: * http://www.ietf.org/rfc/rfc2818.txt section 3.1. It uses a certificate with a common name different to localhost - * and sends a request to localhost. This should fail with a SSLHandshakeException. - * - * @throws Exception on test failure + * and sends a request to localhost. This should fail with an SSLHandshakeException. */ @Test - public void simpleGetWithHostnameVerificationEnabledTest() throws Exception + public void simpleGetWithHostnameVerificationEnabledTest() { clientSslContextFactory.setEndpointIdentificationAlgorithm("HTTPS"); String uri = "https://localhost:" + connector.getLocalPort() + "/"; @@ -119,8 +114,16 @@ public class HostnameVerificationTest ExecutionException x = assertThrows(ExecutionException.class, () -> client.GET(uri)); Throwable cause = x.getCause(); assertThat(cause, Matchers.instanceOf(SSLHandshakeException.class)); - Throwable root = cause.getCause().getCause(); - assertThat(root, Matchers.instanceOf(CertificateException.class)); + + // Search for the CertificateException. + Throwable certificateException = cause.getCause(); + while (certificateException != null) + { + if (certificateException instanceof CertificateException) + break; + certificateException = certificateException.getCause(); + } + assertThat(certificateException, Matchers.instanceOf(CertificateException.class)); } /** diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java index d775854090b..3fb17bfa0cd 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java index ee980f6dc47..8e11bfcc684 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java index 2a732d2b92f..b10039ea904 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -115,51 +115,51 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BasicAuthentication(Scenario scenario) throws Exception + public void testBasicAuthentication(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort()); - test_Authentication(scenario, new BasicAuthentication(uri, realm, "basic", "basic")); + testAuthentication(scenario, new BasicAuthentication(uri, realm, "basic", "basic")); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BasicEmptyRealm(Scenario scenario) throws Exception + public void testBasicEmptyRealm(Scenario scenario) throws Exception { realm = ""; startBasic(scenario, new EmptyServerHandler()); URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort()); - test_Authentication(scenario, new BasicAuthentication(uri, realm, "basic", "basic")); + testAuthentication(scenario, new BasicAuthentication(uri, realm, "basic", "basic")); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BasicAnyRealm(Scenario scenario) throws Exception + public void testBasicAnyRealm(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort()); - test_Authentication(scenario, new BasicAuthentication(uri, ANY_REALM, "basic", "basic")); + testAuthentication(scenario, new BasicAuthentication(uri, ANY_REALM, "basic", "basic")); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_DigestAuthentication(Scenario scenario) throws Exception + public void testDigestAuthentication(Scenario scenario) throws Exception { startDigest(scenario, new EmptyServerHandler()); URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort()); - test_Authentication(scenario, new DigestAuthentication(uri, realm, "digest", "digest")); + testAuthentication(scenario, new DigestAuthentication(uri, realm, "digest", "digest")); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_DigestAnyRealm(Scenario scenario) throws Exception + public void testDigestAnyRealm(Scenario scenario) throws Exception { startDigest(scenario, new EmptyServerHandler()); URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort()); - test_Authentication(scenario, new DigestAuthentication(uri, ANY_REALM, "digest", "digest")); + testAuthentication(scenario, new DigestAuthentication(uri, ANY_REALM, "digest", "digest")); } - private void test_Authentication(final Scenario scenario, Authentication authentication) throws Exception + private void testAuthentication(final Scenario scenario, Authentication authentication) throws Exception { AuthenticationStore authenticationStore = client.getAuthenticationStore(); @@ -226,7 +226,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BasicAuthentication_ThenRedirect(Scenario scenario) throws Exception + public void testBasicAuthenticationThenRedirect(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler() { @@ -271,7 +271,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_Redirect_ThenBasicAuthentication(Scenario scenario) throws Exception + public void testRedirectThenBasicAuthentication(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler() { @@ -310,7 +310,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BasicAuthentication_WithAuthenticationRemoved(Scenario scenario) throws Exception + public void testBasicAuthenticationWithAuthenticationRemoved(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); @@ -359,7 +359,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BasicAuthentication_WithWrongPassword(Scenario scenario) throws Exception + public void testBasicAuthenticationWithWrongPassword(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); @@ -379,7 +379,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_Authentication_ThrowsException(Scenario scenario) throws Exception + public void testAuthenticationThrowsException(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); @@ -419,7 +419,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PreemptedAuthentication(Scenario scenario) throws Exception + public void testPreemptedAuthentication(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); @@ -449,7 +449,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_NonReproducibleContent(Scenario scenario) throws Exception + public void testNonReproducibleContent(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler()); @@ -484,7 +484,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_RequestFailsAfterResponse(Scenario scenario) throws Exception + public void testRequestFailsAfterResponse(Scenario scenario) throws Exception { startBasic(scenario, new EmptyServerHandler() { @@ -576,7 +576,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_InfiniteAuthentication(Scenario scenario) throws Exception + public void testInfiniteAuthentication(Scenario scenario) throws Exception { String authType = "Authenticate"; start(scenario, new EmptyServerHandler() @@ -657,10 +657,10 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest assertEquals("1523430383", headerInfo.getParameter("nonce")); // test multiple authentications - List headerInfoList = aph.getHeaderInfo("Digest qop=\"auth\", realm=\"thermostat\", nonce=\"1523430383\", " - + "Digest realm=\"thermostat2\", qop=\"auth2\", nonce=\"4522530354\", " - + "Digest qop=\"auth3\", nonce=\"9523570528\", realm=\"thermostat3\", " - + "Digest qop=\"auth4\", nonce=\"3526435321\""); + List headerInfoList = aph.getHeaderInfo("Digest qop=\"auth\", realm=\"thermostat\", nonce=\"1523430383\", " + + "Digest realm=\"thermostat2\", qop=\"auth2\", nonce=\"4522530354\", " + + "Digest qop=\"auth3\", nonce=\"9523570528\", realm=\"thermostat3\", " + + "Digest qop=\"auth4\", nonce=\"3526435321\""); assertTrue(headerInfoList.get(0).getType().equalsIgnoreCase("Digest")); assertEquals("auth", headerInfoList.get(0).getParameter("qop")); @@ -744,8 +744,8 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest assertTrue(headerInfo.getType().equalsIgnoreCase("Negotiate")); assertEquals("TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFAs4OAAAADw==", headerInfo.getBase64()); - headerInfos = aph.getHeaderInfo("Negotiate TlRMTVNTUAABAAAAAAAAAFAs4OAAAADw==, " - + "Negotiate YIIJvwYGKwYBBQUCoIIJszCCCa+gJDAi="); + headerInfos = aph.getHeaderInfo("Negotiate TlRMTVNTUAABAAAAAAAAAFAs4OAAAADw==, " + + "Negotiate YIIJvwYGKwYBBQUCoIIJszCCCa+gJDAi="); assertTrue(headerInfos.get(0).getType().equalsIgnoreCase("Negotiate")); assertEquals("TlRMTVNTUAABAAAAAAAAAFAs4OAAAADw==", headerInfos.get(0).getBase64()); @@ -766,9 +766,9 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest assertEquals("=1523430383=", headerInfo.getParameter("nonce")); // test multiple authentications - List headerInfoList = aph.getHeaderInfo("Digest qop=\"=au=th=\", realm=\"=ther=mostat=\", nonce=\"=152343=0383=\", " - + "Digest realm=\"=thermostat2\", qop=\"=auth2\", nonce=\"=4522530354\", " - + "Digest qop=\"auth3=\", nonce=\"9523570528=\", realm=\"thermostat3=\", "); + List headerInfoList = aph.getHeaderInfo("Digest qop=\"=au=th=\", realm=\"=ther=mostat=\", nonce=\"=152343=0383=\", " + + "Digest realm=\"=thermostat2\", qop=\"=auth2\", nonce=\"=4522530354\", " + + "Digest qop=\"auth3=\", nonce=\"9523570528=\", realm=\"thermostat3=\", "); assertTrue(headerInfoList.get(0).getType().equalsIgnoreCase("Digest")); assertEquals("=au=th=", headerInfoList.get(0).getParameter("qop")); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java index f35bffdb027..557b0209bd2 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -63,7 +63,7 @@ public class HttpClientChunkedContentTest } @Test - public void test_Server_HeadersPauseTerminal_Client_Response() throws Exception + public void testServerHeadersPauseTerminalClientResponse() throws Exception { startClient(); @@ -115,7 +115,7 @@ public class HttpClientChunkedContentTest } @Test - public void test_Server_ContentTerminal_Client_ContentDelay() throws Exception + public void testServerContentTerminalClientContentDelay() throws Exception { startClient(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java index ac7e58d6eb6..3fa4680c475 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java index ea4d68982ab..0027ac657a3 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -116,7 +116,7 @@ public class HttpClientCustomProxyTest { private CAFEBABEProxy(Origin.Address address, boolean secure) { - super(address, secure); + super(address, secure, null, null); } @Override diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientExplicitConnectionTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientExplicitConnectionTest.java index 762c002bf83..a06f611b3c6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientExplicitConnectionTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientExplicitConnectionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -45,12 +45,12 @@ public class HttpClientExplicitConnectionTest extends AbstractHttpClientServerTe { start(scenario, new EmptyServerHandler()); - Destination destination = client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); + Destination destination = client.resolveDestination(request); FuturePromise futureConnection = new FuturePromise<>(); destination.newConnection(futureConnection); try (Connection connection = futureConnection.get(5, TimeUnit.SECONDS)) { - Request request = client.newRequest(destination.getHost(), destination.getPort()).scheme(scenario.getScheme()); FutureResponseListener listener = new FutureResponseListener(request); connection.send(request, listener); ContentResponse response = listener.get(5, TimeUnit.SECONDS); @@ -71,11 +71,11 @@ public class HttpClientExplicitConnectionTest extends AbstractHttpClientServerTe { start(scenario, new EmptyServerHandler()); - Destination destination = client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); + Destination destination = client.resolveDestination(request); FuturePromise futureConnection = new FuturePromise<>(); destination.newConnection(futureConnection); Connection connection = futureConnection.get(5, TimeUnit.SECONDS); - Request request = client.newRequest(destination.getHost(), destination.getPort()).scheme(scenario.getScheme()); FutureResponseListener listener = new FutureResponseListener(request); connection.send(request, listener); ContentResponse response = listener.get(5, TimeUnit.SECONDS); @@ -105,14 +105,14 @@ public class HttpClientExplicitConnectionTest extends AbstractHttpClientServerTe { start(scenario, new EmptyServerHandler()); - Destination destination = client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + CountDownLatch responseLatch = new CountDownLatch(1); + Request request = client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .onResponseSuccess(response -> responseLatch.countDown()); + Destination destination = client.resolveDestination(request); FuturePromise futureConnection = new FuturePromise<>(); destination.newConnection(futureConnection); Connection connection = futureConnection.get(5, TimeUnit.SECONDS); - CountDownLatch responseLatch = new CountDownLatch(1); - Request request = client.newRequest(destination.getHost(), destination.getPort()) - .scheme(scenario.getScheme()) - .onResponseSuccess(response -> responseLatch.countDown()); FutureResponseListener listener = new FutureResponseListener(request); connection.send(request, listener); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientFailureTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientFailureTest.java index b3f2af246ad..a7c32775530 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientFailureTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientFailureTest.java @@ -1,30 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; +import java.io.IOException; import java.nio.ByteBuffer; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; import org.eclipse.jetty.client.util.DeferredContentProvider; @@ -33,7 +34,6 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -77,9 +77,9 @@ public class HttpClientFailureTest client = new HttpClient(new HttpClientTransportOverHTTP(1) { @Override - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { - HttpConnectionOverHTTP connection = super.newHttpConnection(endPoint, destination, promise); + HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)super.newConnection(endPoint, context); connectionRef.set(connection); return connection; } @@ -107,9 +107,9 @@ public class HttpClientFailureTest client = new HttpClient(new HttpClientTransportOverHTTP(1) { @Override - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { - HttpConnectionOverHTTP connection = super.newHttpConnection(endPoint, destination, promise); + HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)super.newConnection(endPoint, context); connectionRef.set(connection); return connection; } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java index 6ec23d1c966..b95584da0c4 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -24,7 +24,7 @@ import java.io.InterruptedIOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Random; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; @@ -44,7 +44,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.lessThan; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assumptions.assumeTrue; public class HttpClientGZIPTest extends AbstractHttpClientServerTest @@ -217,16 +217,11 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest } }); - final CountDownLatch latch = new CountDownLatch(1); - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .send(result -> - { - if (result.isFailed()) - latch.countDown(); - }); - - assertTrue(latch.await(5, TimeUnit.SECONDS)); + assertThrows(ExecutionException.class, () -> + client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .timeout(5, TimeUnit.SECONDS) + .send()); } @ParameterizedTest diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java new file mode 100644 index 00000000000..56a55f917ee --- /dev/null +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java @@ -0,0 +1,170 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.client; + +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; +import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class HttpClientIdleTimeoutTest +{ + private Server server; + private ServerConnector connector; + private HttpClient client; + + private void start(Handler handler) throws Exception + { + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + connector = new ServerConnector(server, 1, 1); + server.addConnector(connector); + server.setHandler(handler); + server.start(); + } + + @AfterEach + public void dispose() throws Exception + { + if (server != null) + server.stop(); + if (client != null) + client.stop(); + } + + @Test + public void testRequestIsRetriedWhenSentDuringIdleTimeout() throws Exception + { + start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + Cookie[] cookies = request.getCookies(); + if (cookies == null || cookies.length == 0) + { + // Send a cookie in the first response. + response.addCookie(new Cookie("name", "value")); + } + else + { + // Verify that there is only one cookie, i.e. + // that the request has not been normalized twice. + assertEquals(1, cookies.length); + } + } + }); + + CountDownLatch idleTimeoutLatch = new CountDownLatch(1); + CountDownLatch requestLatch = new CountDownLatch(1); + CountDownLatch retryLatch = new CountDownLatch(1); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + client = new HttpClient(new HttpClientTransportOverHTTP(1) + { + @Override + public HttpDestination newHttpDestination(Origin origin) + { + return new DuplexHttpDestination(getHttpClient(), origin) + { + @Override + protected SendFailure send(IConnection connection, HttpExchange exchange) + { + SendFailure result = super.send(connection, exchange); + if (result != null && result.retry) + retryLatch.countDown(); + return result; + } + }; + } + + @Override + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) + { + return new HttpConnectionOverHTTP(endPoint, context) + { + @Override + protected boolean onIdleTimeout(long idleTimeout) + { + boolean result = super.onIdleTimeout(idleTimeout); + if (result) + idleTimeoutLatch.countDown(); + assertTrue(await(requestLatch)); + return result; + } + }; + } + }); + client.setExecutor(clientThreads); + client.start(); + + long idleTimeout = 1000; + client.setIdleTimeout(idleTimeout); + + // Create one connection. + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()).send(); + assertEquals(response.getStatus(), HttpStatus.OK_200); + + assertTrue(idleTimeoutLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS)); + + // Send a request exactly while the connection is idle timing out. + CountDownLatch responseLatch = new CountDownLatch(1); + client.newRequest("localhost", connector.getLocalPort()).send(result -> + { + assertTrue(result.isSucceeded()); + assertEquals(HttpStatus.OK_200, result.getResponse().getStatus()); + responseLatch.countDown(); + }); + assertTrue(retryLatch.await(5, TimeUnit.SECONDS)); + requestLatch.countDown(); + + assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); + } + + private boolean await(CountDownLatch latch) + { + try + { + return latch.await(15, TimeUnit.SECONDS); + } + catch (InterruptedException x) + { + throw new RuntimeException(x); + } + } +} diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java new file mode 100644 index 00000000000..bdf75fbbdb9 --- /dev/null +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java @@ -0,0 +1,283 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.client; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Destination; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.ProxyConnectionFactory; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V1; +import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V2; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class HttpClientProxyProtocolTest +{ + private Server server; + private ServerConnector connector; + private HttpClient client; + + private void startServer(Handler handler) throws Exception + { + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + connector = new ServerConnector(server, 1, 1, proxy, http); + server.addConnector(connector); + server.setHandler(handler); + server.start(); + } + + private void startClient() throws Exception + { + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + client = new HttpClient(); + client.setExecutor(clientThreads); + client.setRemoveIdleDestinations(false); + client.start(); + } + + @AfterEach + public void dispose() throws Exception + { + if (server != null) + server.stop(); + if (client != null) + client.stop(); + } + + @Test + public void testClientProxyProtocolV1() throws Exception + { + startServer(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString()); + response.getOutputStream().print(request.getRemotePort()); + } + }); + startClient(); + + int serverPort = connector.getLocalPort(); + + int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536); + V1.Tag tag = new V1.Tag("127.0.0.1", clientPort); + + ContentResponse response = client.newRequest("localhost", serverPort) + .tag(tag) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort), response.getContentAsString()); + } + + @Test + public void testClientProxyProtocolV1Unknown() throws Exception + { + startServer(new EmptyServerHandler()); + startClient(); + + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .tag(V1.Tag.UNKNOWN) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + } + + @Test + public void testClientProxyProtocolV2() throws Exception + { + startServer(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString()); + response.getOutputStream().print(request.getRemotePort()); + } + }); + startClient(); + + int serverPort = connector.getLocalPort(); + + int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536); + V2.Tag tag = new V2.Tag("127.0.0.1", clientPort); + + ContentResponse response = client.newRequest("localhost", serverPort) + .tag(tag) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort), response.getContentAsString()); + } + + @Test + public void testClientProxyProtocolV2Local() throws Exception + { + startServer(new EmptyServerHandler()); + startClient(); + + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .tag(V2.Tag.LOCAL) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + } + + @Test + public void testClientProxyProtocolV2WithVectors() throws Exception + { + int typeTLS = 0x20; + String tlsVersion = "TLSv1.3"; + byte[] tlsVersionBytes = tlsVersion.getBytes(StandardCharsets.US_ASCII); + startServer(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + EndPoint endPoint = jettyRequest.getHttpChannel().getEndPoint(); + assertTrue(endPoint instanceof ProxyConnectionFactory.ProxyEndPoint); + ProxyConnectionFactory.ProxyEndPoint proxyEndPoint = (ProxyConnectionFactory.ProxyEndPoint)endPoint; + if (target.equals("/tls_version")) + { + assertNotNull(proxyEndPoint.getTLV(typeTLS)); + assertEquals(tlsVersion, proxyEndPoint.getAttribute(ProxyConnectionFactory.TLS_VERSION)); + } + response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString()); + response.getOutputStream().print(request.getRemotePort()); + } + }); + startClient(); + + int serverPort = connector.getLocalPort(); + + int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536); + byte[] dataTLS = new byte[1 + 4 + (1 + 2 + tlsVersionBytes.length)]; + dataTLS[0] = 0x01; // CLIENT_SSL + dataTLS[5] = 0x21; // SUBTYPE_SSL_VERSION + dataTLS[6] = 0x00; // Length, hi byte + dataTLS[7] = (byte)tlsVersionBytes.length; // Length, lo byte + System.arraycopy(tlsVersionBytes, 0, dataTLS, 8, tlsVersionBytes.length); + V2.Tag.TLV tlv = new V2.Tag.TLV(typeTLS, dataTLS); + V2.Tag tag = new V2.Tag("127.0.0.1", clientPort, Collections.singletonList(tlv)); + + ContentResponse response = client.newRequest("localhost", serverPort) + .path("/tls_version") + .tag(tag) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort), response.getContentAsString()); + + // Make another request with the same address information, but different TLV. + V2.Tag.TLV tlv2 = new V2.Tag.TLV(0x01, "http/1.1".getBytes(StandardCharsets.UTF_8)); + V2.Tag tag2 = new V2.Tag("127.0.0.1", clientPort, Collections.singletonList(tlv2)); + response = client.newRequest("localhost", serverPort) + .tag(tag2) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort), response.getContentAsString()); + + // Make sure the two TLVs created two destinations. + assertEquals(2, client.getDestinations().size()); + } + + @Test + public void testProxyProtocolWrappingHTTPProxy() throws Exception + { + startServer(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString()); + response.getOutputStream().print(request.getRemotePort()); + } + }); + startClient(); + + int proxyPort = connector.getLocalPort(); + int serverPort = proxyPort + 1; // Any port will do. + client.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyPort)); + + // We are simulating to be a HttpClient inside a proxy. + // The server is configured with the PROXY protocol to know the socket address of clients. + + // The proxy receives a request from the client, and it extracts the client address. + int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536); + V1.Tag tag = new V1.Tag("127.0.0.1", clientPort); + + // The proxy maps the client address, then sends the request. + ContentResponse response = client.newRequest("localhost", serverPort) + .tag(tag) + .header(HttpHeader.CONNECTION, "close") + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort), response.getContentAsString()); + List destinations = client.getDestinations(); + assertEquals(1, destinations.size()); + HttpDestination destination = (HttpDestination)destinations.get(0); + assertTrue(destination.getConnectionPool().isEmpty()); + + // The previous connection has been closed. + // Make another request from the same client address. + response = client.newRequest("localhost", serverPort) + .tag(tag) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort), response.getContentAsString()); + destinations = client.getDestinations(); + assertEquals(1, destinations.size()); + assertSame(destination, destinations.get(0)); + + // Make another request from a different client address. + int clientPort2 = clientPort + 1; + V1.Tag tag2 = new V1.Tag("127.0.0.1", clientPort2); + response = client.newRequest("localhost", serverPort) + .tag(tag2) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(String.valueOf(clientPort2), response.getContentAsString()); + destinations = client.getDestinations(); + assertEquals(2, destinations.size()); + } +} diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java index 605c4b7795e..e223f8ba2e0 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java index 6a6999d1282..a6ef79dcaa7 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -59,7 +59,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest { @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_303(Scenario scenario) throws Exception + public void test303(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -75,7 +75,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_303_302(Scenario scenario) throws Exception + public void test303302(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -91,7 +91,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_303_302_OnDifferentDestinations(Scenario scenario) throws Exception + public void test303302OnDifferentDestinations(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -107,7 +107,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_301(Scenario scenario) throws Exception + public void test301(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -124,7 +124,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_301_WithWrongMethod(Scenario scenario) throws Exception + public void test301WithWrongMethod(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -144,7 +144,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_307_WithRequestContent(Scenario scenario) throws Exception + public void test307WithRequestContent(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -184,7 +184,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_303_WithConnectionClose_WithBigRequest(Scenario scenario) throws Exception + public void test303WithConnectionCloseWithBigRequest(Scenario scenario) throws Exception { start(scenario, new RedirectHandler()); @@ -314,84 +314,84 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_HEAD_301(Scenario scenario) throws Exception + public void testHEAD301(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.HEAD, HttpStatus.MOVED_PERMANENTLY_301); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_301(Scenario scenario) throws Exception + public void testPOST301(Scenario scenario) throws Exception { testGETRedirect(scenario, HttpMethod.POST, HttpStatus.MOVED_PERMANENTLY_301); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PUT_301(Scenario scenario) throws Exception + public void testPUT301(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.PUT, HttpStatus.MOVED_PERMANENTLY_301); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_HEAD_302(Scenario scenario) throws Exception + public void testHEAD302(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.HEAD, HttpStatus.FOUND_302); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_302(Scenario scenario) throws Exception + public void testPOST302(Scenario scenario) throws Exception { testGETRedirect(scenario, HttpMethod.POST, HttpStatus.FOUND_302); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PUT_302(Scenario scenario) throws Exception + public void testPUT302(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.PUT, HttpStatus.FOUND_302); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_HEAD_303(Scenario scenario) throws Exception + public void testHEAD303(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.HEAD, HttpStatus.SEE_OTHER_303); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_303(Scenario scenario) throws Exception + public void testPOST303(Scenario scenario) throws Exception { testGETRedirect(scenario, HttpMethod.POST, HttpStatus.SEE_OTHER_303); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PUT_303(Scenario scenario) throws Exception + public void testPUT303(Scenario scenario) throws Exception { testGETRedirect(scenario, HttpMethod.PUT, HttpStatus.SEE_OTHER_303); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_HEAD_307(Scenario scenario) throws Exception + public void testHEAD307(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.HEAD, HttpStatus.TEMPORARY_REDIRECT_307); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_307(Scenario scenario) throws Exception + public void testPOST307(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.POST, HttpStatus.TEMPORARY_REDIRECT_307); } @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PUT_307(Scenario scenario) throws Exception + public void testPUT307(Scenario scenario) throws Exception { testSameMethodRedirect(scenario, HttpMethod.PUT, HttpStatus.TEMPORARY_REDIRECT_307); } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientSynchronizationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientSynchronizationTest.java index a0d8d24f267..eab4e28f00d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientSynchronizationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientSynchronizationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java index de240b7bcd1..2678e18778b 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java @@ -1,36 +1,43 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSocket; @@ -39,17 +46,26 @@ import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; +import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslHandshakeListener; +import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.ExecutorThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledOnJre; @@ -111,7 +127,7 @@ public class HttpClientTLSTest private void configureSslContextFactory(SslContextFactory sslContextFactory) { - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); } @@ -423,48 +439,46 @@ public class HttpClientTLSTest String host = "localhost"; int port = connector.getLocalPort(); - Socket socket = new Socket(host, port); - SSLSocket sslSocket = (SSLSocket)clientTLSFactory.getSslContext().getSocketFactory().createSocket(socket, host, port, true); + Socket socket1 = new Socket(host, port); + SSLSocket sslSocket1 = (SSLSocket)clientTLSFactory.getSslContext().getSocketFactory().createSocket(socket1, host, port, true); CountDownLatch handshakeLatch1 = new CountDownLatch(1); AtomicReference session1 = new AtomicReference<>(); - sslSocket.addHandshakeCompletedListener(event -> + sslSocket1.addHandshakeCompletedListener(event -> { session1.set(event.getSession().getId()); handshakeLatch1.countDown(); }); - sslSocket.startHandshake(); + sslSocket1.startHandshake(); assertTrue(handshakeLatch1.await(5, TimeUnit.SECONDS)); // In TLS 1.3 the server sends a NewSessionTicket post-handshake message // to enable session resumption and without a read, the message is not processed. - try + + assertThrows(SocketTimeoutException.class, () -> { - sslSocket.setSoTimeout(1000); - sslSocket.getInputStream().read(); - } - catch (SocketTimeoutException expected) - { - } + sslSocket1.setSoTimeout(1000); + sslSocket1.getInputStream().read(); + }); // The client closes abruptly. - socket.close(); + socket1.close(); // Try again and compare the session ids. - socket = new Socket(host, port); - sslSocket = (SSLSocket)clientTLSFactory.getSslContext().getSocketFactory().createSocket(socket, host, port, true); + Socket socket2 = new Socket(host, port); + SSLSocket sslSocket2 = (SSLSocket)clientTLSFactory.getSslContext().getSocketFactory().createSocket(socket2, host, port, true); CountDownLatch handshakeLatch2 = new CountDownLatch(1); AtomicReference session2 = new AtomicReference<>(); - sslSocket.addHandshakeCompletedListener(event -> + sslSocket2.addHandshakeCompletedListener(event -> { session2.set(event.getSession().getId()); handshakeLatch2.countDown(); }); - sslSocket.startHandshake(); + sslSocket2.startHandshake(); assertTrue(handshakeLatch2.await(5, TimeUnit.SECONDS)); assertArrayEquals(session1.get(), session2.get()); - sslSocket.close(); + sslSocket2.close(); } @Test @@ -483,10 +497,10 @@ public class HttpClientTLSTest client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)) { @Override - protected ClientConnectionFactory newSslClientConnectionFactory(ClientConnectionFactory connectionFactory) + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) { - SslClientConnectionFactory ssl = (SslClientConnectionFactory)super.newSslClientConnectionFactory(connectionFactory); - ssl.setAllowMissingCloseMessage(false); + SslClientConnectionFactory ssl = (SslClientConnectionFactory)super.newSslClientConnectionFactory(sslContextFactory, connectionFactory); + ssl.setRequireCloseMessage(true); return ssl; } }; @@ -513,19 +527,19 @@ public class HttpClientTLSTest break; } - // If the response is Content-Length delimited, allowing the - // missing TLS Close Message is fine because the application - // will see a EOFException anyway. - // If the response is connection delimited, allowing the - // missing TLS Close Message is bad because the application - // will see a successful response with truncated content. + // If the response is Content-Length delimited, the lack of + // the TLS Close Message is fine because the application + // will see a EOFException anyway: the Content-Length and + // the actual content bytes count won't match. + // If the response is connection delimited, the lack of the + // TLS Close Message is bad because the application will + // see a successful response, but with truncated content. - // Verify that by not allowing the missing - // TLS Close Message we get a response failure. + // Verify that by requiring the TLS Close Message we get + // a response failure. byte[] half = new byte[8]; String response = "HTTP/1.1 200 OK\r\n" + -// "Content-Length: " + (half.length * 2) + "\r\n" + "Connection: close\r\n" + "\r\n"; OutputStream output = sslSocket.getOutputStream(); @@ -565,4 +579,368 @@ public class HttpClientTLSTest assertTrue(latch.await(5, TimeUnit.SECONDS)); } + + @Test + public void testNeverUsedConnectionThenServerIdleTimeout() throws Exception + { + long idleTimeout = 2000; + + SslContextFactory.Server serverTLSFactory = createServerSslContextFactory(); + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + HttpConfiguration httpConfig = new HttpConfiguration(); + httpConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory http = new HttpConnectionFactory(httpConfig); + AtomicLong serverBytes = new AtomicLong(); + SslConnectionFactory ssl = new SslConnectionFactory(serverTLSFactory, http.getProtocol()) + { + @Override + protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected int networkFill(ByteBuffer input) throws IOException + { + int n = super.networkFill(input); + if (n > 0) + serverBytes.addAndGet(n); + return n; + } + }; + } + }; + connector = new ServerConnector(server, 1, 1, ssl, http); + connector.setIdleTimeout(idleTimeout); + server.addConnector(connector); + server.setHandler(new EmptyServerHandler()); + server.start(); + + SslContextFactory.Client clientTLSFactory = createClientSslContextFactory(); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(clientTLSFactory); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + AtomicLong clientBytes = new AtomicLong(); + client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)) + { + @Override + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) + { + if (sslContextFactory == null) + sslContextFactory = getSslContextFactory(); + return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory) + { + @Override + protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected int networkFill(ByteBuffer input) throws IOException + { + int n = super.networkFill(input); + if (n > 0) + clientBytes.addAndGet(n); + return n; + } + }; + } + }; + } + }; + client.setExecutor(clientThreads); + client.start(); + + // Create a connection but don't use it. + Origin origin = new Origin(HttpScheme.HTTPS.asString(), "localhost", connector.getLocalPort()); + HttpDestination destination = client.resolveDestination(origin); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); + // Trigger the creation of a new connection, but don't use it. + connectionPool.tryCreate(-1); + // Verify that the connection has been created. + while (true) + { + Thread.sleep(50); + if (connectionPool.getConnectionCount() == 1) + break; + } + + // Wait for the server to idle timeout the connection. + Thread.sleep(idleTimeout + idleTimeout / 2); + + // The connection should be gone from the connection pool. + assertEquals(0, connectionPool.getConnectionCount(), connectionPool.dump()); + assertEquals(0, serverBytes.get()); + assertEquals(0, clientBytes.get()); + } + + @Test + public void testNeverUsedConnectionThenClientIdleTimeout() throws Exception + { + SslContextFactory.Server serverTLSFactory = createServerSslContextFactory(); + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + HttpConfiguration httpConfig = new HttpConfiguration(); + httpConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory http = new HttpConnectionFactory(httpConfig); + AtomicLong serverBytes = new AtomicLong(); + SslConnectionFactory ssl = new SslConnectionFactory(serverTLSFactory, http.getProtocol()) + { + @Override + protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected int networkFill(ByteBuffer input) throws IOException + { + int n = super.networkFill(input); + if (n > 0) + serverBytes.addAndGet(n); + return n; + } + }; + } + }; + connector = new ServerConnector(server, 1, 1, ssl, http); + server.addConnector(connector); + server.setHandler(new EmptyServerHandler()); + server.start(); + + long idleTimeout = 2000; + + SslContextFactory.Client clientTLSFactory = createClientSslContextFactory(); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(clientTLSFactory); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + AtomicLong clientBytes = new AtomicLong(); + client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)) + { + @Override + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) + { + if (sslContextFactory == null) + sslContextFactory = getSslContextFactory(); + return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory) + { + @Override + protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected int networkFill(ByteBuffer input) throws IOException + { + int n = super.networkFill(input); + if (n > 0) + clientBytes.addAndGet(n); + return n; + } + }; + } + }; + } + }; + client.setIdleTimeout(idleTimeout); + client.setExecutor(clientThreads); + client.start(); + + // Create a connection but don't use it. + Origin origin = new Origin(HttpScheme.HTTPS.asString(), "localhost", connector.getLocalPort()); + HttpDestination destination = client.resolveDestination(origin); + DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); + // Trigger the creation of a new connection, but don't use it. + connectionPool.tryCreate(-1); + // Verify that the connection has been created. + while (true) + { + Thread.sleep(50); + if (connectionPool.getConnectionCount() == 1) + break; + } + + // Wait for the client to idle timeout the connection. + Thread.sleep(idleTimeout + idleTimeout / 2); + + // The connection should be gone from the connection pool. + assertEquals(0, connectionPool.getConnectionCount(), connectionPool.dump()); + assertEquals(0, serverBytes.get()); + assertEquals(0, clientBytes.get()); + } + + @Test + public void testSSLEngineClosedDuringHandshake() throws Exception + { + SslContextFactory.Server serverTLSFactory = createServerSslContextFactory(); + startServer(serverTLSFactory, new EmptyServerHandler()); + + SslContextFactory.Client clientTLSFactory = createClientSslContextFactory(); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(clientTLSFactory); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)) + { + @Override + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) + { + if (sslContextFactory == null) + sslContextFactory = getSslContextFactory(); + return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory) + { + @Override + protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException + { + sslEngine.closeOutbound(); + return super.wrap(sslEngine, input, output); + } + }; + } + }; + } + }; + client.setExecutor(clientThreads); + client.start(); + + ExecutionException failure = assertThrows(ExecutionException.class, () -> client.newRequest("localhost", connector.getLocalPort()) + .scheme(HttpScheme.HTTPS.asString()) + .send()); + Throwable cause = failure.getCause(); + assertThat(cause, Matchers.instanceOf(SSLHandshakeException.class)); + } + + @Test + public void testTLSLargeFragments() throws Exception + { + CountDownLatch serverLatch = new CountDownLatch(1); + SslContextFactory.Server serverTLSFactory = createServerSslContextFactory(); + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + HttpConfiguration httpConfig = new HttpConfiguration(); + httpConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory http = new HttpConnectionFactory(httpConfig); + SslConnectionFactory ssl = new SslConnectionFactory(serverTLSFactory, http.getProtocol()) + { + @Override + protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected SSLEngineResult unwrap(SSLEngine sslEngine, ByteBuffer input, ByteBuffer output) throws SSLException + { + int inputBytes = input.remaining(); + SSLEngineResult result = super.unwrap(sslEngine, input, output); + if (inputBytes == 5) + serverLatch.countDown(); + return result; + } + }; + } + }; + connector = new ServerConnector(server, 1, 1, ssl, http); + server.addConnector(connector); + server.setHandler(new EmptyServerHandler()); + server.start(); + + long idleTimeout = 2000; + + CountDownLatch clientLatch = new CountDownLatch(1); + SslContextFactory.Client clientTLSFactory = createClientSslContextFactory(); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(clientTLSFactory); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)) + { + @Override + protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) + { + if (sslContextFactory == null) + sslContextFactory = getSslContextFactory(); + return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory) + { + @Override + protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine) + { + return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption()) + { + @Override + protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException + { + try + { + clientLatch.countDown(); + assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); + return super.wrap(sslEngine, input, output); + } + catch (InterruptedException x) + { + throw new SSLException(x); + } + } + }; + } + }; + } + }; + client.setIdleTimeout(idleTimeout); + client.setExecutor(clientThreads); + client.start(); + + String host = "localhost"; + int port = connector.getLocalPort(); + + CountDownLatch responseLatch = new CountDownLatch(1); + client.newRequest(host, port) + .scheme(HttpScheme.HTTPS.asString()) + .send(result -> + { + assertTrue(result.isSucceeded()); + assertEquals(HttpStatus.OK_200, result.getResponse().getStatus()); + responseLatch.countDown(); + }); + // Wait for the TLS buffers to be acquired by the client, then the + // HTTP request will be paused waiting for the TLS buffer to be expanded. + assertTrue(clientLatch.await(5, TimeUnit.SECONDS)); + + // Send the large frame bytes that will enlarge the TLS buffers. + try (Socket socket = new Socket(host, port)) + { + OutputStream output = socket.getOutputStream(); + byte[] largeFrameBytes = new byte[5]; + largeFrameBytes[0] = 22; // Type = handshake + largeFrameBytes[1] = 3; // Major TLS version + largeFrameBytes[2] = 3; // Minor TLS version + // Frame length is 0x7FFF == 32767, i.e. a "large fragment". + // Maximum allowed by RFC 8446 is 16384, but SSLEngine supports up to 33093. + largeFrameBytes[3] = 0x7F; // Length hi byte + largeFrameBytes[4] = (byte)0xFF; // Length lo byte + output.write(largeFrameBytes); + output.flush(); + // Just close the connection now, the large frame + // length was enough to trigger the buffer expansion. + } + + // The HTTP request will resume and be forced to handle the TLS buffer expansion. + assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); + } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java index cc21b0b9df7..868fc335bb4 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -39,6 +40,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; import java.util.Random; import java.util.concurrent.CountDownLatch; @@ -50,6 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.LongConsumer; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; @@ -79,16 +82,17 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.Net; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.SocketAddressResolver; -import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; @@ -106,6 +110,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck @ExtendWith(WorkDirExtension.class) public class HttpClientTest extends AbstractHttpClientServerTest { @@ -120,10 +125,11 @@ public class HttpClientTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); String path = "/"; - Response response = client.GET(scenario.getScheme() + "://" + host + ":" + port + path); + Request request = client.newRequest(scenario.getScheme() + "://" + host + ":" + port + path); + Response response = request.send(); assertEquals(200, response.getStatus()); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); long start = System.nanoTime(); @@ -148,7 +154,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_DestinationCount(Scenario scenario) throws Exception + public void testDestinationCount(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); @@ -168,7 +174,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_GET_ResponseWithoutContent(Scenario scenario) throws Exception + public void testGETResponseWithoutContent(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); @@ -180,9 +186,9 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_GET_ResponseWithContent(Scenario scenario) throws Exception + public void testGETResponseWithContent(Scenario scenario) throws Exception { - final byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7}; + byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7}; start(scenario, new AbstractHandler() { @Override @@ -204,10 +210,10 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_GET_WithParameters_ResponseWithContent(Scenario scenario) throws Exception + public void testGETWithParametersResponseWithContent(Scenario scenario) throws Exception { - final String paramName1 = "a"; - final String paramName2 = "b"; + String paramName1 = "a"; + String paramName2 = "b"; start(scenario, new AbstractHandler() { @Override @@ -237,10 +243,10 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_GET_WithParametersMultiValued_ResponseWithContent(Scenario scenario) throws Exception + public void testGETWithParametersMultiValuedResponseWithContent(Scenario scenario) throws Exception { - final String paramName1 = "a"; - final String paramName2 = "b"; + String paramName1 = "a"; + String paramName2 = "b"; start(scenario, new AbstractHandler() { @Override @@ -276,10 +282,10 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_WithParameters(Scenario scenario) throws Exception + public void testPOSTWithParameters(Scenario scenario) throws Exception { - final String paramName = "a"; - final String paramValue = "\u20AC"; + String paramName = "a"; + String paramValue = "\u20AC"; start(scenario, new AbstractHandler() { @Override @@ -308,11 +314,11 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PUT_WithParameters(Scenario scenario) throws Exception + public void testPUTWithParameters(Scenario scenario) throws Exception { - final String paramName = "a"; - final String paramValue = "\u20AC"; - final String encodedParamValue = URLEncoder.encode(paramValue, "UTF-8"); + String paramName = "a"; + String paramValue = "\u20AC"; + String encodedParamValue = URLEncoder.encode(paramValue, "UTF-8"); start(scenario, new AbstractHandler() { @Override @@ -342,11 +348,11 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_WithParameters_WithContent(Scenario scenario) throws Exception + public void testPOSTWithParametersWithContent(Scenario scenario) throws Exception { - final byte[] content = {0, 1, 2, 3}; - final String paramName = "a"; - final String paramValue = "\u20AC"; + byte[] content = {0, 1, 2, 3}; + String paramName = "a"; + String paramValue = "\u20AC"; start(scenario, new AbstractHandler() { @Override @@ -377,7 +383,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_WithContent_NotifiesRequestContentListener(Scenario scenario) throws Exception + public void testPOSTWithContentNotifiesRequestContentListener(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @@ -389,7 +395,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final byte[] content = {0, 1, 2, 3}; + byte[] content = {0, 1, 2, 3}; ContentResponse response = client.POST(scenario.getScheme() + "://localhost:" + connector.getLocalPort()) .onRequestContent((request, buffer) -> { @@ -408,7 +414,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_POST_WithContent_TracksProgress(Scenario scenario) throws Exception + public void testPOSTWithContentTracksProgress(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @@ -420,7 +426,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final AtomicInteger progress = new AtomicInteger(); + AtomicInteger progress = new AtomicInteger(); ContentResponse response = client.POST(scenario.getScheme() + "://localhost:" + connector.getLocalPort()) .onRequestContent((request, buffer) -> { @@ -429,9 +435,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest buffer.get(bytes); assertEquals(bytes[0], progress.getAndIncrement()); }) - .content(new BytesContentProvider(new byte[]{0}, new byte[]{1}, new byte[]{ - 2 - }, new byte[]{3}, new byte[]{4})) + .content(new BytesContentProvider(new byte[]{0}, new byte[]{1}, new byte[]{2}, new byte[]{3}, new byte[]{4})) .timeout(5, TimeUnit.SECONDS) .send(); @@ -442,14 +446,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_QueuedRequest_IsSent_WhenPreviousRequestSucceeded(Scenario scenario) throws Exception + public void testQueuedRequestIsSentWhenPreviousRequestSucceeded(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); client.setMaxConnectionsPerDestination(1); - final CountDownLatch latch = new CountDownLatch(1); - final CountDownLatch successLatch = new CountDownLatch(2); + CountDownLatch latch = new CountDownLatch(1); + CountDownLatch successLatch = new CountDownLatch(2); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) .onRequestBegin(request -> @@ -491,7 +495,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_QueuedRequest_IsSent_WhenPreviousRequestClosedConnection(Scenario scenario) throws Exception + public void testQueuedRequestIsSentWhenPreviousRequestClosedConnection(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @@ -509,7 +513,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest try (StacklessLogging stackless = new StacklessLogging(org.eclipse.jetty.server.HttpChannel.class)) { - final CountDownLatch latch = new CountDownLatch(2); + CountDownLatch latch = new CountDownLatch(2); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) .path("/one") @@ -532,12 +536,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ExchangeIsComplete_OnlyWhenBothRequestAndResponseAreComplete(Scenario scenario) throws Exception + public void testExchangeIsCompleteOnlyWhenBothRequestAndResponseAreComplete(Scenario scenario) throws Exception { - start(scenario, new AbstractHandler.ErrorDispatchHandler() + start(scenario, new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); response.setContentLength(0); @@ -568,10 +572,10 @@ public class HttpClientTest extends AbstractHttpClientServerTest } } - final CountDownLatch latch = new CountDownLatch(3); - final AtomicLong exchangeTime = new AtomicLong(); - final AtomicLong requestTime = new AtomicLong(); - final AtomicLong responseTime = new AtomicLong(); + CountDownLatch latch = new CountDownLatch(3); + AtomicLong exchangeTime = new AtomicLong(); + AtomicLong requestTime = new AtomicLong(); + AtomicLong responseTime = new AtomicLong(); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) .file(file) @@ -611,7 +615,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ExchangeIsComplete_WhenRequestFailsMidway_WithResponse(Scenario scenario) throws Exception + public void testExchangeIsCompleteWhenRequestFailsMidwayWithResponse(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @@ -623,7 +627,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) // The second ByteBuffer set to null will throw an exception @@ -674,18 +678,18 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ExchangeIsComplete_WhenRequestFails_WithNoResponse(Scenario scenario) throws Exception + public void testExchangeIsCompleteWhenRequestFailsWithNoResponse(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); - final CountDownLatch latch = new CountDownLatch(1); - final String host = "localhost"; - final int port = connector.getLocalPort(); + CountDownLatch latch = new CountDownLatch(1); + String host = "localhost"; + int port = connector.getLocalPort(); client.newRequest(host, port) .scheme(scenario.getScheme()) - .onRequestBegin(request -> + .onRequestBegin(r -> { - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + HttpDestination destination = (HttpDestination)client.resolveDestination(r); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); connectionPool.getActiveConnections().iterator().next().close(); }) @@ -704,9 +708,9 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_Request_IdleTimeout(Scenario scenario) throws Exception + public void testRequestIdleTimeout(Scenario scenario) throws Exception { - final long idleTimeout = 1000; + long idleTimeout = 1000; start(scenario, new AbstractHandler() { @Override @@ -724,8 +728,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final String host = "localhost"; - final int port = connector.getLocalPort(); + String host = "localhost"; + int port = connector.getLocalPort(); assertThrows(TimeoutException.class, () -> client.newRequest(host, port) .scheme(scenario.getScheme()) @@ -763,7 +767,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testHeaderProcessing(Scenario scenario) throws Exception { - final String headerName = "X-Header-Test"; + String headerName = "X-Header-Test"; start(scenario, new AbstractHandler() { @Override @@ -792,7 +796,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler()); int count = 10; - final CountDownLatch latch = new CountDownLatch(count); + CountDownLatch latch = new CountDownLatch(count); for (int i = 0; i < count; ++i) { client.newRequest("localhost", connector.getLocalPort()) @@ -819,9 +823,9 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_HEAD_With_ResponseContentLength(Scenario scenario) throws Exception + public void testHEADWithResponseContentLength(Scenario scenario) throws Exception { - final int length = 1024; + int length = 1024; start(scenario, new AbstractHandler() { @Override @@ -870,7 +874,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler()); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); client.newRequest(host, port) .send(result -> { @@ -926,7 +930,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testCustomUserAgent(Scenario scenario) throws Exception { - final String userAgent = "Test/1.0"; + String userAgent = "Test/1.0"; start(scenario, new AbstractHandler() { @Override @@ -1009,7 +1013,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest { start(scenario, new EmptyServerHandler()); - final AtomicInteger counter = new AtomicInteger(); + AtomicInteger counter = new AtomicInteger(); Request.Listener listener = new Request.Listener() { @Override @@ -1081,8 +1085,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest { start(scenario, new EmptyServerHandler()); - final AtomicInteger counter = new AtomicInteger(); - final CountDownLatch latch = new CountDownLatch(1); + AtomicInteger counter = new AtomicInteger(); + CountDownLatch latch = new CountDownLatch(1); Response.Listener listener = new Response.Listener() { @Override @@ -1118,6 +1122,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest counter.incrementAndGet(); } + @Override + public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback) + { + // Should not be invoked + counter.incrementAndGet(); + } + @Override public void onSuccess(Response response) { @@ -1161,7 +1172,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void setOnCompleteCallbackWithBlockingSend(Scenario scenario) throws Exception { - final byte[] content = new byte[512]; + byte[] content = new byte[512]; new Random().nextBytes(content); start(scenario, new AbstractHandler() { @@ -1173,7 +1184,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final Exchanger ex = new Exchanger<>(); + Exchanger ex = new Exchanger<>(); BufferingResponseListener listener = new BufferingResponseListener() { @Override @@ -1204,7 +1215,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testCustomHostHeader(Scenario scenario) throws Exception { - final String host = "localhost"; + String host = "localhost"; start(scenario, new AbstractHandler() { @Override @@ -1266,18 +1277,17 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); + long timeout = 5000; + Request request = client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .version(HttpVersion.HTTP_1_0) + .header(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString()) + .timeout(timeout, TimeUnit.MILLISECONDS); FuturePromise promise = new FuturePromise<>(); - Destination destination = client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + Destination destination = client.resolveDestination(request); destination.newConnection(promise); try (Connection connection = promise.get(5, TimeUnit.SECONDS)) { - long timeout = 5000; - Request request = client.newRequest(destination.getHost(), destination.getPort()) - .scheme(destination.getScheme()) - .version(HttpVersion.HTTP_1_0) - .header(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString()) - .timeout(timeout, TimeUnit.MILLISECONDS); - FutureResponseListener listener = new FutureResponseListener(request); connection.send(request, listener); ContentResponse response = listener.get(2 * timeout, TimeUnit.MILLISECONDS); @@ -1312,7 +1322,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testLongPollIsAbortedWhenClientIsStopped(Scenario scenario) throws Exception { - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); start(scenario, new AbstractHandler() { @Override @@ -1324,7 +1334,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final CountDownLatch completeLatch = new CountDownLatch(1); + CountDownLatch completeLatch = new CountDownLatch(1); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) .send(result -> @@ -1343,7 +1353,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void testSmallContentDelimitedByEOFWithSlowRequestHTTP10(Scenario scenario) throws Exception + public void testSmallContentDelimitedByEOFWithSlowRequestHTTP10(Scenario scenario) { Assumptions.assumeTrue(HttpScheme.HTTP.is(scenario.getScheme())); @@ -1356,7 +1366,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(NonSslScenarioProvider.class) - public void testBigContentDelimitedByEOFWithSlowRequestHTTP10(Scenario scenario) throws Exception + public void testBigContentDelimitedByEOFWithSlowRequestHTTP10(Scenario scenario) { ExecutionException e = assertThrows(ExecutionException.class, () -> testContentDelimitedByEOFWithSlowRequest(scenario, HttpVersion.HTTP_1_0, 128 * 1024)); @@ -1379,7 +1389,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest testContentDelimitedByEOFWithSlowRequest(scenario, HttpVersion.HTTP_1_1, 128 * 1024); } - private void testContentDelimitedByEOFWithSlowRequest(final Scenario scenario, final HttpVersion version, int length) throws Exception + private void testContentDelimitedByEOFWithSlowRequest(Scenario scenario, HttpVersion version, int length) throws Exception { // This test is crafted in a way that the response completes before the request is fully written. // With SSL, the response coming down will close the SSLEngine so it would not be possible to @@ -1388,7 +1398,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest // This is a limit of Java's SSL implementation that does not allow half closes. Assumptions.assumeTrue(HttpScheme.HTTP.is(scenario.getScheme())); - final byte[] data = new byte[length]; + byte[] data = new byte[length]; new Random().nextBytes(data); start(scenario, new AbstractHandler() { @@ -1424,8 +1434,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testRequestRetries(Scenario scenario) throws Exception { - final int maxRetries = 3; - final AtomicInteger requests = new AtomicInteger(); + int maxRetries = 3; + AtomicInteger requests = new AtomicInteger(); start(scenario, new AbstractHandler() { @Override @@ -1438,7 +1448,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); new RetryListener(client, scenario.getScheme(), "localhost", connector.getLocalPort(), maxRetries) { @Override @@ -1466,9 +1476,9 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final AtomicReference callbackRef = new AtomicReference<>(); - final CountDownLatch contentLatch = new CountDownLatch(1); - final CountDownLatch completeLatch = new CountDownLatch(1); + AtomicReference callbackRef = new AtomicReference<>(); + CountDownLatch contentLatch = new CountDownLatch(1); + CountDownLatch completeLatch = new CountDownLatch(1); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) .send(new Response.Listener.Adapter() @@ -1514,15 +1524,15 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }); - final AtomicBoolean open = new AtomicBoolean(); + AtomicBoolean open = new AtomicBoolean(); ClientConnector clientConnector = new ClientConnector(); clientConnector.setSslContextFactory(scenario.newClientSslContextFactory()); client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector) { @Override - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { - return new HttpConnectionOverHTTP(endPoint, destination, promise) + return new HttpConnectionOverHTTP(endPoint, context) { @Override public void onOpen() @@ -1535,7 +1545,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest }); client.start(); - final CountDownLatch latch = new CountDownLatch(2); + CountDownLatch latch = new CountDownLatch(2); client.newRequest("localhost", connector.getLocalPort()) .scheme(scenario.getScheme()) .onRequestBegin(request -> @@ -1567,7 +1577,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest .method(HttpMethod.CONNECT) .version(HttpVersion.HTTP_1_0); FuturePromise promise = new FuturePromise<>(); - client.getDestination("http", host, port).newConnection(promise); + client.resolveDestination(request).newConnection(promise); Connection connection = promise.get(5, TimeUnit.SECONDS); FutureResponseListener listener = new FutureResponseListener(request); connection.send(request, listener); @@ -1614,7 +1624,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_IPv6_Host(Scenario scenario) throws Exception + public void testIPv6Host(Scenario scenario) throws Exception { Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable()); start(scenario, new AbstractHandler() @@ -1778,6 +1788,57 @@ public class HttpClientTest extends AbstractHttpClientServerTest } } + @ParameterizedTest + @ArgumentsSource(ScenarioProvider.class) + public void testContentListenerAsCompleteListener(Scenario scenario) throws Exception + { + byte[] bytes = new byte[1024]; + new Random().nextBytes(bytes); + start(scenario, new AbstractHandler() + { + @Override + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + ServletOutputStream output = response.getOutputStream(); + output.write(bytes); + } + }); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CountDownLatch latch = new CountDownLatch(1); + class L implements Response.ContentListener, Response.CompleteListener + { + @Override + public void onContent(Response response, ByteBuffer content) + { + try + { + BufferUtil.writeTo(content, baos); + } + catch (IOException x) + { + baos.reset(); + x.printStackTrace(); + } + } + + @Override + public void onComplete(Result result) + { + if (result.isSucceeded()) + latch.countDown(); + } + } + + client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .send(new L()); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + assertArrayEquals(bytes, baos.toByteArray()); + } + private void assertCopyRequest(Request original) { Request copy = client.copyRequest((HttpRequest)original, original.getURI()); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java index 15d62f1b6bb..c178ec2a338 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -59,6 +59,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpClientURITest extends AbstractHttpClientServerTest { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) public void testIPv6Host(Scenario scenario) throws Exception diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdown.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java similarity index 83% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdown.java rename to jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java index 5af26fcd6a6..7572259e681 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdown.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; import java.io.IOException; import java.io.InputStream; +import java.util.Map; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -28,7 +29,6 @@ import java.util.concurrent.atomic.AtomicReference; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.http.HttpChannelOverHTTP; import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; @@ -38,14 +38,13 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -public class HttpClientUploadDuringServerShutdown +public class HttpClientUploadDuringServerShutdownTest { /** * A server used in conjunction with {@link ClientSide}. @@ -117,8 +116,8 @@ public class HttpClientUploadDuringServerShutdown { int length = 16 * 1024 * 1024 + random.nextInt(16 * 1024 * 1024); client.newRequest("localhost", 8888) - .content(new BytesContentProvider(new byte[length])) - .send(result -> latch.countDown()); + .content(new BytesContentProvider(new byte[length])) + .send(result -> latch.countDown()); long sleep = 1 + random.nextInt(10); TimeUnit.MILLISECONDS.sleep(sleep); } @@ -158,9 +157,9 @@ public class HttpClientUploadDuringServerShutdown HttpClient client = new HttpClient(new HttpClientTransportOverHTTP(1) { @Override - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) { - return new HttpConnectionOverHTTP(endPoint, destination, promise) + return new HttpConnectionOverHTTP(endPoint, context) { @Override protected HttpChannelOverHTTP newHttpChannel() @@ -229,10 +228,10 @@ public class HttpClientUploadDuringServerShutdown // is being closed is used to send the request. assertTrue(sendLatch.await(5, TimeUnit.SECONDS)); - final CountDownLatch completeLatch = new CountDownLatch(1); - client.newRequest("localhost", connector.getLocalPort()) + CountDownLatch completeLatch = new CountDownLatch(1); + var request = client.newRequest("localhost", connector.getLocalPort()) .timeout(10, TimeUnit.SECONDS) - .onRequestBegin(request -> + .onRequestBegin(r -> { try { @@ -243,12 +242,12 @@ public class HttpClientUploadDuringServerShutdown { x.printStackTrace(); } - }) - .send(result -> completeLatch.countDown()); + }); + request.send(result -> completeLatch.countDown()); assertTrue(completeLatch.await(5, TimeUnit.SECONDS)); - HttpDestination destination = (HttpDestination)client.getDestination("http", "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool pool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, pool.getConnectionCount()); assertEquals(0, pool.getIdleConnections().size()); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java index 5089df3d728..26b58540a99 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java @@ -1,31 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; -import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Collection; import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -37,13 +35,14 @@ import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.util.ByteBufferContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -51,6 +50,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest { + private static final Logger LOG = LoggerFactory.getLogger(HttpConnectionLifecycleTest.class); + @Override public HttpClient newHttpClient(HttpClientTransport transport) { @@ -61,26 +62,25 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SuccessfulRequest_ReturnsConnection(Scenario scenario) throws Exception + public void testSuccessfulRequestReturnsConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + CountDownLatch headersLatch = new CountDownLatch(1); + CountDownLatch successLatch = new CountDownLatch(3); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - final CountDownLatch headersLatch = new CountDownLatch(1); - final CountDownLatch successLatch = new CountDownLatch(3); - client.newRequest(host, port) - .scheme(scenario.getScheme()) - .onRequestSuccess(request -> successLatch.countDown()) + request.onRequestSuccess(r -> successLatch.countDown()) .onResponseHeaders(response -> { assertEquals(0, idleConnections.size()); @@ -112,24 +112,25 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_FailedRequest_RemovesConnection(Scenario scenario) throws Exception + public void testFailedRequestRemovesConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + CountDownLatch beginLatch = new CountDownLatch(1); + CountDownLatch failureLatch = new CountDownLatch(2); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - final CountDownLatch beginLatch = new CountDownLatch(1); - final CountDownLatch failureLatch = new CountDownLatch(2); - client.newRequest(host, port).scheme(scenario.getScheme()).listener(new Request.Listener.Adapter() + request.listener(new Request.Listener.Adapter() { @Override public void onBegin(Request request) @@ -143,17 +144,18 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest { failureLatch.countDown(); } - }).send(new Response.Listener.Adapter() - { - @Override - public void onComplete(Result result) + }) + .send(new Response.Listener.Adapter() { - assertTrue(result.isFailed()); - assertEquals(0, idleConnections.size()); - assertEquals(0, activeConnections.size()); - failureLatch.countDown(); - } - }); + @Override + public void onComplete(Result result) + { + assertTrue(result.isFailed()); + assertEquals(0, idleConnections.size()); + assertEquals(0, activeConnections.size()); + failureLatch.countDown(); + } + }); assertTrue(beginLatch.await(30, TimeUnit.SECONDS)); assertTrue(failureLatch.await(30, TimeUnit.SECONDS)); @@ -164,39 +166,38 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BadRequest_RemovesConnection(Scenario scenario) throws Exception + public void testBadRequestRemovesConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + CountDownLatch successLatch = new CountDownLatch(3); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Queue idleConnections = connectionPool.getIdleConnections(); + Queue idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - final CountDownLatch successLatch = new CountDownLatch(3); - client.newRequest(host, port) - .scheme(scenario.getScheme()) - .listener(new Request.Listener.Adapter() + request.listener(new Request.Listener.Adapter() + { + @Override + public void onBegin(Request request) { - @Override - public void onBegin(Request request) - { - // Remove the host header, this will make the request invalid - request.header(HttpHeader.HOST, null); - } + // Remove the host header, this will make the request invalid + request.header(HttpHeader.HOST, null); + } - @Override - public void onSuccess(Request request) - { - successLatch.countDown(); - } - }) + @Override + public void onSuccess(Request request) + { + successLatch.countDown(); + } + }) .send(new Response.Listener.Adapter() { @Override @@ -226,53 +227,52 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) @Tag("Slow") @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_BadRequest_WithSlowRequest_RemovesConnection(Scenario scenario) throws Exception + public void testBadRequestWithSlowRequestRemovesConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + CountDownLatch successLatch = new CountDownLatch(3); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - final long delay = 1000; - final CountDownLatch successLatch = new CountDownLatch(3); - client.newRequest(host, port) - .scheme(scenario.getScheme()) - .listener(new Request.Listener.Adapter() + long delay = 1000; + request.listener(new Request.Listener.Adapter() + { + @Override + public void onBegin(Request request) { - @Override - public void onBegin(Request request) - { - // Remove the host header, this will make the request invalid - request.header(HttpHeader.HOST, null); - } + // Remove the host header, this will make the request invalid + request.header(HttpHeader.HOST, null); + } - @Override - public void onHeaders(Request request) + @Override + public void onHeaders(Request request) + { + try { - try - { - TimeUnit.MILLISECONDS.sleep(delay); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } + TimeUnit.MILLISECONDS.sleep(delay); } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } - @Override - public void onSuccess(Request request) - { - successLatch.countDown(); - } - }) + @Override + public void onSuccess(Request request) + { + successLatch.countDown(); + } + }) .send(new Response.Listener.Adapter() { @Override @@ -300,27 +300,26 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ConnectionFailure_RemovesConnection(Scenario scenario) throws Exception + public void testConnectionFailureRemovesConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); server.stop(); - final CountDownLatch failureLatch = new CountDownLatch(2); - client.newRequest(host, port) - .scheme(scenario.getScheme()) - .onRequestFailure((request, failure) -> failureLatch.countDown()) + CountDownLatch failureLatch = new CountDownLatch(2); + request.onRequestFailure((r, x) -> failureLatch.countDown()) .send(result -> { assertTrue(result.isFailed()); @@ -335,12 +334,12 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_ResponseWithConnectionCloseHeader_RemovesConnection(Scenario scenario) throws Exception + public void testResponseWithConnectionCloseHeaderRemovesConnection(Scenario scenario) throws Exception { start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) { response.setHeader("Connection", "close"); baseRequest.setHandled(true); @@ -349,29 +348,28 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - final CountDownLatch latch = new CountDownLatch(1); - client.newRequest(host, port) - .scheme(scenario.getScheme()) - .send(new Response.Listener.Adapter() + CountDownLatch latch = new CountDownLatch(1); + request.send(new Response.Listener.Adapter() + { + @Override + public void onComplete(Result result) { - @Override - public void onComplete(Result result) - { - assertFalse(result.isFailed()); - assertEquals(0, idleConnections.size()); - assertEquals(0, activeConnections.size()); - latch.countDown(); - } - }); + assertFalse(result.isFailed()); + assertEquals(0, idleConnections.size()); + assertEquals(0, activeConnections.size()); + latch.countDown(); + } + }); assertTrue(latch.await(30, TimeUnit.SECONDS)); @@ -381,14 +379,14 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_BigRequestContent_ResponseWithConnectionCloseHeader_RemovesConnection(Scenario scenario) throws Exception + public void testBigRequestContentResponseWithConnectionCloseHeaderRemovesConnection(Scenario scenario) throws Exception { try (StacklessLogging ignore = new StacklessLogging(HttpConnection.class)) { start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) { response.setHeader("Connection", "close"); baseRequest.setHandled(true); @@ -398,23 +396,22 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - Log.getLogger(HttpConnection.class).info("Expecting java.lang.IllegalStateException: HttpParser{s=CLOSED,..."); + LOG.info("Expecting java.lang.IllegalStateException: HttpParser{s=CLOSED,..."); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); ByteBuffer buffer = ByteBuffer.allocate(16 * 1024 * 1024); Arrays.fill(buffer.array(), (byte)'x'); - client.newRequest(host, port) - .scheme(scenario.getScheme()) - .content(new ByteBufferContentProvider(buffer)) + request.content(new ByteBufferContentProvider(buffer)) .send(new Response.Listener.Adapter() { @Override @@ -440,25 +437,23 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) @Tag("Slow") @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_IdleConnection_IsClosed_OnRemoteClose(Scenario scenario) throws Exception + public void testIdleConnectionIsClosedOnRemoteClose(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); - ContentResponse response = client.newRequest(host, port) - .scheme(scenario.getScheme()) - .timeout(30, TimeUnit.SECONDS) - .send(); + ContentResponse response = request.timeout(30, TimeUnit.SECONDS).send(); assertEquals(200, response.getStatus()); @@ -479,21 +474,21 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), host, port); + Request request = client.newRequest(host, port).scheme(scenario.getScheme()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); - final Collection idleConnections = connectionPool.getIdleConnections(); + Collection idleConnections = connectionPool.getIdleConnections(); assertEquals(0, idleConnections.size()); - final Collection activeConnections = connectionPool.getActiveConnections(); + Collection activeConnections = connectionPool.getActiveConnections(); assertEquals(0, activeConnections.size()); client.setStrictEventOrdering(false); - ContentResponse response = client.newRequest(host, port) - .scheme(scenario.getScheme()) + ContentResponse response = request .onResponseBegin(response1 -> { - // Simulate a HTTP 1.0 response has been received. + // Simulate an HTTP 1.0 response has been received. ((HttpResponse)response1).version(HttpVersion.HTTP_1_0); }) .send(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java index c90c821a70e..6699c7cb336 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java @@ -1,24 +1,23 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; -import java.io.IOException; import java.net.HttpCookie; import java.net.URI; import java.util.Arrays; @@ -27,7 +26,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -52,14 +50,14 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_CookieIsStored(Scenario scenario) throws Exception + public void testCookieIsStored(Scenario scenario) throws Exception { final String name = "foo"; final String value = "bar"; start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { response.addCookie(new Cookie(name, value)); } @@ -82,14 +80,14 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_CookieIsSent(Scenario scenario) throws Exception + public void testCookieIsSent(Scenario scenario) throws Exception { final String name = "foo"; final String value = "bar"; start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { Cookie[] cookies = request.getCookies(); assertNotNull(cookies); @@ -113,12 +111,12 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_CookieWithoutValue(Scenario scenario) throws Exception + public void testCookieWithoutValue(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { response.addHeader("Set-Cookie", ""); } @@ -133,14 +131,14 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_PerRequestCookieIsSent(Scenario scenario) throws Exception + public void testPerRequestCookieIsSent(Scenario scenario) throws Exception { final String name = "foo"; final String value = "bar"; start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { Cookie[] cookies = request.getCookies(); assertNotNull(cookies); @@ -161,7 +159,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SetCookieWithoutPath_RequestURIWithOneSegment(Scenario scenario) throws Exception + public void testSetCookieWithoutPathRequestURIWithOneSegment(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -169,7 +167,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo".equals(target) && r == 0) @@ -217,7 +215,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SetCookieWithoutPath_RequestURIWithTwoSegments(Scenario scenario) throws Exception + public void testSetCookieWithoutPathRequestURIWithTwoSegments(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -225,7 +223,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo/bar".equals(target) && r == 0) @@ -278,7 +276,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SetCookieWithLongerPath(Scenario scenario) throws Exception + public void testSetCookieWithLongerPath(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -286,7 +284,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo".equals(target) && r == 0) @@ -339,7 +337,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SetCookieWithShorterPath(Scenario scenario) throws Exception + public void testSetCookieWithShorterPath(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -347,7 +345,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo/bar".equals(target) && r == 0) @@ -400,7 +398,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_TwoSetCookieWithSameNameSamePath(Scenario scenario) throws Exception + public void testTwoSetCookieWithSameNameSamePath(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -409,7 +407,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo".equals(target) && r == 0) @@ -463,7 +461,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_TwoSetCookieWithSameNameDifferentPath(Scenario scenario) throws Exception + public void testTwoSetCookieWithSameNameDifferentPath(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -472,7 +470,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo".equals(target) && r == 0) @@ -533,7 +531,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_TwoSetCookieWithSameNamePath1PrefixOfPath2(Scenario scenario) throws Exception + public void testTwoSetCookieWithSameNamePath1PrefixOfPath2(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -542,7 +540,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo".equals(target) && r == 0) @@ -606,7 +604,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_CookiePathWithTrailingSlash(Scenario scenario) throws Exception + public void testCookiePathWithTrailingSlash(Scenario scenario) throws Exception { String headerName = "X-Request"; String cookieName = "a"; @@ -614,7 +612,7 @@ public class HttpCookieTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { int r = request.getIntHeader(headerName); if ("/foo/bar".equals(target) && r == 0) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java index 199e4cb003e..aca7bb99461 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -33,9 +33,9 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.util.ByteBufferContentProvider; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -55,18 +55,17 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest Exception failure = new Exception("oops"); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - Request request = client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .timeout(5, TimeUnit.SECONDS); + request.timeout(5, TimeUnit.SECONDS); request.abort(failure); request.send(); }); assertSame(failure, x.getCause()); // Make sure the pool is in a sane state. - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(1, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -79,32 +78,29 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest { start(scenario, new EmptyServerHandler()); - final Throwable cause = new Exception(); - final AtomicBoolean aborted = new AtomicBoolean(); - final CountDownLatch latch = new CountDownLatch(1); - final AtomicBoolean begin = new AtomicBoolean(); + Throwable cause = new Exception(); + AtomicBoolean aborted = new AtomicBoolean(); + CountDownLatch latch = new CountDownLatch(1); + AtomicBoolean begin = new AtomicBoolean(); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .listener(new Request.Listener.Adapter() + request.listener(new Request.Listener.Adapter() + { + @Override + public void onQueued(Request request) { - @Override - public void onQueued(Request request) - { - aborted.set(request.abort(cause)); - latch.countDown(); - } + aborted.set(request.abort(cause)); + latch.countDown(); + } - @Override - public void onBegin(Request request) - { - begin.set(true); - } - }) - .timeout(5, TimeUnit.SECONDS) - .send(); + @Override + public void onBegin(Request request) + { + begin.set(true); + } + }).timeout(5, TimeUnit.SECONDS).send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); @@ -112,7 +108,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest assertSame(cause, x.getCause()); assertFalse(begin.get()); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -130,34 +126,31 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch committed = new CountDownLatch(1); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .listener(new Request.Listener.Adapter() + request.listener(new Request.Listener.Adapter() + { + @Override + public void onBegin(Request request) { - @Override - public void onBegin(Request request) - { - aborted.set(request.abort(cause)); - latch.countDown(); - } + aborted.set(request.abort(cause)); + latch.countDown(); + } - @Override - public void onCommit(Request request) - { - committed.countDown(); - } - }) - .timeout(5, TimeUnit.SECONDS) - .send(); + @Override + public void onCommit(Request request) + { + committed.countDown(); + } + }).timeout(5, TimeUnit.SECONDS).send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); if (aborted.get()) assertSame(cause, x.getCause()); assertFalse(committed.await(1, TimeUnit.SECONDS)); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -175,34 +168,31 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch committed = new CountDownLatch(1); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .listener(new Request.Listener.Adapter() + request.listener(new Request.Listener.Adapter() + { + @Override + public void onHeaders(Request request) { - @Override - public void onHeaders(Request request) - { - aborted.set(request.abort(cause)); - latch.countDown(); - } + aborted.set(request.abort(cause)); + latch.countDown(); + } - @Override - public void onCommit(Request request) - { - committed.countDown(); - } - }) - .timeout(5, TimeUnit.SECONDS) - .send(); + @Override + public void onCommit(Request request) + { + committed.countDown(); + } + }).timeout(5, TimeUnit.SECONDS).send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); if (aborted.get()) assertSame(cause, x.getCause()); assertFalse(committed.await(1, TimeUnit.SECONDS)); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -219,26 +209,24 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest // A) the request is failed before the response arrived // B) the request is failed after the response arrived - final Throwable cause = new Exception(); - final AtomicBoolean aborted = new AtomicBoolean(); - final CountDownLatch latch = new CountDownLatch(1); + Throwable cause = new Exception(); + AtomicBoolean aborted = new AtomicBoolean(); + CountDownLatch latch = new CountDownLatch(1); + + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .onRequestCommit(request -> - { - aborted.set(request.abort(cause)); - latch.countDown(); - }) - .timeout(5, TimeUnit.SECONDS) - .send(); + request.onRequestCommit(r -> + { + aborted.set(r.abort(cause)); + latch.countDown(); + }).timeout(5, TimeUnit.SECONDS).send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); if (aborted.get()) assertSame(cause, x.getCause()); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -249,11 +237,11 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testAbortOnCommitWithContent(Scenario scenario) throws Exception { - final AtomicReference failure = new AtomicReference<>(); + AtomicReference failure = new AtomicReference<>(); start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { try { @@ -269,35 +257,31 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest } }); - final Throwable cause = new Exception(); - final AtomicBoolean aborted = new AtomicBoolean(); - final CountDownLatch latch = new CountDownLatch(1); + Throwable cause = new Exception(); + AtomicBoolean aborted = new AtomicBoolean(); + CountDownLatch latch = new CountDownLatch(1); + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .onRequestCommit(request -> + request.onRequestCommit(r -> + { + aborted.set(r.abort(cause)); + latch.countDown(); + }).content(new ByteBufferContentProvider(ByteBuffer.wrap(new byte[]{0}), ByteBuffer.wrap(new byte[]{1})) + { + @Override + public long getLength() { - aborted.set(request.abort(cause)); - latch.countDown(); - }) - .content(new ByteBufferContentProvider(ByteBuffer.wrap(new byte[]{0}), ByteBuffer.wrap(new byte[]{1})) - { - @Override - public long getLength() - { - return -1; - } - }) - .timeout(5, TimeUnit.SECONDS) - .send(); + return -1; + } + }).timeout(5, TimeUnit.SECONDS).send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); if (aborted.get()) assertSame(cause, x.getCause()); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -314,7 +298,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest start(scenario, new EmptyServerHandler() { @Override - protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { try { @@ -328,28 +312,25 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest } }); - final Throwable cause = new Exception(); - final AtomicBoolean aborted = new AtomicBoolean(); - final CountDownLatch latch = new CountDownLatch(1); + Throwable cause = new Exception(); + AtomicBoolean aborted = new AtomicBoolean(); + CountDownLatch latch = new CountDownLatch(1); + + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scenario.getScheme()); ExecutionException x = assertThrows(ExecutionException.class, () -> { - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .onRequestContent((request, content) -> + request.onRequestContent((r, c) -> + { + aborted.set(r.abort(cause)); + latch.countDown(); + }).content(new ByteBufferContentProvider(ByteBuffer.wrap(new byte[]{0}), ByteBuffer.wrap(new byte[]{1})) + { + @Override + public long getLength() { - aborted.set(request.abort(cause)); - latch.countDown(); - }) - .content(new ByteBufferContentProvider(ByteBuffer.wrap(new byte[]{0}), ByteBuffer.wrap(new byte[]{1})) - { - @Override - public long getLength() - { - return -1; - } - }) - .timeout(5, TimeUnit.SECONDS) - .send(); + return -1; + } + }).timeout(5, TimeUnit.SECONDS).send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); if (aborted.get()) @@ -357,7 +338,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -369,11 +350,11 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest @ArgumentsSource(ScenarioProvider.class) public void testInterrupt(Scenario scenario) throws Exception { - final long delay = 1000; + long delay = 1000; start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException { try { @@ -389,10 +370,10 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest }); Request request = client.newRequest("localhost", connector.getLocalPort()) - .timeout(3 * delay, TimeUnit.MILLISECONDS) - .scheme(scenario.getScheme()); + .timeout(3 * delay, TimeUnit.MILLISECONDS) + .scheme(scenario.getScheme()); - final Thread thread = Thread.currentThread(); + Thread thread = Thread.currentThread(); new Thread(() -> { try @@ -406,7 +387,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest } }).start(); - assertThrows(InterruptedException.class, () -> request.send()); + assertThrows(InterruptedException.class, request::send); } @ParameterizedTest @@ -417,7 +398,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException { try { @@ -432,13 +413,13 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest } }); - final Request request = client.newRequest("localhost", connector.getLocalPort()) - .timeout(3 * delay, TimeUnit.MILLISECONDS) - .scheme(scenario.getScheme()); + Request request = client.newRequest("localhost", connector.getLocalPort()) + .timeout(3 * delay, TimeUnit.MILLISECONDS) + .scheme(scenario.getScheme()); - final Throwable cause = new Exception(); - final AtomicBoolean aborted = new AtomicBoolean(); - final CountDownLatch latch = new CountDownLatch(1); + Throwable cause = new Exception(); + AtomicBoolean aborted = new AtomicBoolean(); + CountDownLatch latch = new CountDownLatch(1); new Thread(() -> { try @@ -464,7 +445,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest assertSame(cause, x.getCause()); } - HttpDestination destination = (HttpDestination)client.getDestination(scenario.getScheme(), "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getActiveConnections().size()); @@ -479,7 +460,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException { try { @@ -497,8 +478,8 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest final Throwable cause = new Exception(); final CountDownLatch latch = new CountDownLatch(1); Request request = client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .timeout(3 * delay, TimeUnit.MILLISECONDS); + .scheme(scenario.getScheme()) + .timeout(3 * delay, TimeUnit.MILLISECONDS); request.send(result -> { assertTrue(result.isFailed()); @@ -520,7 +501,7 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest start(scenario, new AbstractHandler() { @Override - public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); if (!"/done".equals(request.getRequestURI())) @@ -555,10 +536,10 @@ public class HttpRequestAbortTest extends AbstractHttpClientServerTest ExecutionException e = assertThrows(ExecutionException.class, () -> { client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .path("/redirect") - .timeout(5, TimeUnit.SECONDS) - .send(); + .scheme(scenario.getScheme()) + .path("/redirect") + .timeout(5, TimeUnit.SECONDS) + .send(); }); assertTrue(latch.await(5, TimeUnit.SECONDS)); if (aborted.get()) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java index 9689576f38c..191a60dafd1 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java index d74f919ae83..0e3bdb5b6f4 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/InsufficientThreadsDetectionTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/InsufficientThreadsDetectionTest.java index 2d396121628..4d42af9850b 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/InsufficientThreadsDetectionTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/InsufficientThreadsDetectionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java index ff4caaa6fc1..af999682754 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -31,14 +31,14 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.SocketAddressResolver; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -120,7 +120,7 @@ public class LivelockTest int requestRate = 5; long pause = 1000 / requestRate; - Logger clientLog = Log.getLogger("TESTClient"); + Logger clientLog = LoggerFactory.getLogger("TESTClient"); CountDownLatch latch = new CountDownLatch(count); for (int i = 0; i < count; ++i) { @@ -133,9 +133,9 @@ public class LivelockTest else { if (result.getRequestFailure() != null) - clientLog.warn(result.getRequestFailure()); + clientLog.warn("Request Failure on {}", result, result.getRequestFailure()); if (result.getResponseFailure() != null) - clientLog.warn(result.getResponseFailure()); + clientLog.warn("Response Failure on {}", result, result.getResponseFailure()); } }); sleep(pause); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java index 87632761d7b..1702001b013 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java index 7a4b646fc4e..6fbde71b762 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -147,7 +147,7 @@ public class ServerConnectionCloseTest Thread.sleep(1000); // Connection should have been removed from pool. - HttpDestination destination = (HttpDestination)client.getDestination("http", "localhost", port); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getIdleConnectionCount()); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java index df56547514c..78be4ced56d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java @@ -1,23 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; +import java.io.InputStream; +import java.io.OutputStream; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; @@ -25,7 +27,14 @@ import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -44,7 +53,13 @@ public class Socks4ProxyTest server = ServerSocketChannel.open(); server.bind(new InetSocketAddress("localhost", 0)); - client = new HttpClient(); + ClientConnector connector = new ClientConnector(); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + connector.setExecutor(clientThreads); + connector.setSslContextFactory(new SslContextFactory.Client()); + client = new HttpClient(new HttpClientTransportOverHTTP(connector)); + client.setExecutor(clientThreads); client.start(); } @@ -61,7 +76,7 @@ public class Socks4ProxyTest int proxyPort = server.socket().getLocalPort(); client.getProxyConfiguration().getProxies().add(new Socks4Proxy("localhost", proxyPort)); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); byte ip1 = 127; byte ip2 = 0; @@ -111,7 +126,7 @@ public class Socks4ProxyTest "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; - channel.write(ByteBuffer.wrap(response.getBytes("UTF-8"))); + channel.write(ByteBuffer.wrap(response.getBytes(StandardCharsets.UTF_8))); assertTrue(latch.await(5, TimeUnit.SECONDS)); } @@ -123,7 +138,7 @@ public class Socks4ProxyTest int proxyPort = server.socket().getLocalPort(); client.getProxyConfiguration().getProxies().add(new Socks4Proxy("localhost", proxyPort)); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); String serverHost = "127.0.0.13"; // Test expects an IP address. int serverPort = proxyPort + 1; // Any port will do @@ -169,7 +184,92 @@ public class Socks4ProxyTest "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; - channel.write(ByteBuffer.wrap(response.getBytes("UTF-8"))); + channel.write(ByteBuffer.wrap(response.getBytes(StandardCharsets.UTF_8))); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + } + + @Test + public void testSocks4ProxyWithTLSServer() throws Exception + { + String proxyHost = "localhost"; + int proxyPort = server.socket().getLocalPort(); + + String serverHost = "127.0.0.13"; // Server host different from proxy host. + int serverPort = proxyPort + 1; // Any port will do. + + SslContextFactory clientTLS = client.getSslContextFactory(); + clientTLS.reload(ssl -> + { + // The client keystore contains the trustedCertEntry for the + // self-signed server certificate, so it acts as a truststore. + ssl.setTrustStorePath("src/test/resources/client_keystore.p12"); + ssl.setTrustStorePassword("storepwd"); + // Disable TLS hostname verification, but + // enable application hostname verification. + ssl.setEndpointIdentificationAlgorithm(null); + // The hostname must be that of the server, not of the proxy. + ssl.setHostnameVerifier((hostname, session) -> serverHost.equals(hostname)); + }); + client.getProxyConfiguration().getProxies().add(new Socks4Proxy(proxyHost, proxyPort)); + + CountDownLatch latch = new CountDownLatch(1); + client.newRequest(serverHost, serverPort) + .scheme(HttpScheme.HTTPS.asString()) + .path("/path") + .send(result -> + { + if (result.isSucceeded()) + latch.countDown(); + else + result.getFailure().printStackTrace(); + }); + + try (SocketChannel channel = server.accept()) + { + int socks4MessageLength = 9; + ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength); + int read = channel.read(buffer); + assertEquals(socks4MessageLength, read); + + // Socks4 response. + channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0})); + + // Wrap the socket with TLS. + SslContextFactory.Server serverTLS = new SslContextFactory.Server(); + serverTLS.setKeyStorePath("src/test/resources/keystore.p12"); + serverTLS.setKeyStorePassword("storepwd"); + serverTLS.start(); + SSLContext sslContext = serverTLS.getSslContext(); + SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(channel.socket(), serverHost, serverPort, false); + sslSocket.setUseClientMode(false); + + // Read the request. + int crlfs = 0; + InputStream input = sslSocket.getInputStream(); + while (true) + { + read = input.read(); + if (read < 0) + break; + if (read == '\r' || read == '\n') + ++crlfs; + else + crlfs = 0; + if (crlfs == 4) + break; + } + + // Send the response. + String response = + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"; + OutputStream output = sslSocket.getOutputStream(); + output.write(response.getBytes(StandardCharsets.UTF_8)); + output.flush(); assertTrue(latch.await(5, TimeUnit.SECONDS)); } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java index 18cfa42cf07..88da321d718 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; @@ -52,7 +52,7 @@ public class TLSServerConnectionCloseTest SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); sslContextFactory.setEndpointIdentificationAlgorithm(null); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); clientConnector.setSslContextFactory(sslContextFactory); @@ -172,7 +172,7 @@ public class TLSServerConnectionCloseTest Thread.sleep(1000); // Connection should have been removed from pool. - HttpDestination destination = (HttpDestination)client.getDestination("http", "localhost", port); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool(); assertEquals(0, connectionPool.getConnectionCount()); assertEquals(0, connectionPool.getIdleConnectionCount()); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java index d187de8a521..51927196594 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/api/Usage.java b/jetty-client/src/test/java/org/eclipse/jetty/client/api/Usage.java index 30030887a32..1d6d86a792d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/api/Usage.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/api/Usage.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.api; @@ -49,10 +49,11 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @Disabled +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck public class Usage { @Test - public void testGETBlocking_ShortAPI() throws Exception + public void testGETBlockingShortAPI() throws Exception { HttpClient client = new HttpClient(); client.start(); @@ -120,7 +121,7 @@ public class Usage } @Test - public void testPOSTWithParams_ShortAPI() throws Exception + public void testPOSTWithParamsShortAPI() throws Exception { HttpClient client = new HttpClient(); client.start(); @@ -153,13 +154,13 @@ public class Usage HttpClient client = new HttpClient(); client.start(); + Request request = client.newRequest("localhost", 8080); + // Create an explicit connection, and use try-with-resources to manage it FuturePromise futureConnection = new FuturePromise<>(); - client.getDestination("http", "localhost", 8080).newConnection(futureConnection); + client.resolveDestination(request).newConnection(futureConnection); try (Connection connection = futureConnection.get(5, TimeUnit.SECONDS)) { - Request request = client.newRequest("localhost", 8080); - // Asynchronous send but using FutureResponseListener FutureResponseListener listener = new FutureResponseListener(request); connection.send(request, listener); @@ -293,15 +294,8 @@ public class Usage try (OutputStream output = content.getOutputStream()) { client.newRequest("localhost", 8080) - .content(content) - .send(new Response.CompleteListener() - { - @Override - public void onComplete(Result result) - { - assertEquals(200, result.getResponse().getStatus()); - } - }); + .content(content) + .send(result -> assertEquals(200, result.getResponse().getStatus())); output.write(new byte[1024]); output.write(new byte[512]); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpDestinationOverHTTPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpDestinationOverHTTPTest.java index e146ea90056..49e8c0c46a3 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpDestinationOverHTTPTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpDestinationOverHTTPTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; @@ -47,14 +47,14 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest { @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_FirstAcquire_WithEmptyQueue(Scenario scenario) throws Exception + public void testFirstAcquireWithEmptyQueue(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); @@ -74,7 +74,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SecondAcquire_AfterFirstAcquire_WithEmptyQueue_ReturnsSameConnection(Scenario scenario) throws Exception + public void testSecondAcquireAfterFirstAcquireWithEmptyQueueReturnsSameConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); @@ -98,7 +98,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_SecondAcquire_ConcurrentWithFirstAcquire_WithEmptyQueue_CreatesTwoConnections(Scenario scenario) throws Exception + public void testSecondAcquireConcurrentWithFirstAcquireWithEmptyQueueCreatesTwoConnections(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); @@ -155,7 +155,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_Acquire_Process_Release_Acquire_ReturnsSameConnection(Scenario scenario) throws Exception + public void testAcquireProcessReleaseAcquireReturnsSameConnection(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); @@ -182,7 +182,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_IdleConnection_IdleTimeout(Scenario scenario) throws Exception + public void testIdleConnectionIdleTimeout(Scenario scenario) throws Exception { startServer(scenario, new EmptyServerHandler()); long idleTimeout = 1000; @@ -209,7 +209,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) - public void test_Request_Failed_If_MaxRequestsQueuedPerDestination_Exceeded(Scenario scenario) throws Exception + public void testRequestFailedIfMaxRequestsQueuedPerDestinationExceeded(Scenario scenario) throws Exception { start(scenario, new EmptyServerHandler()); String scheme = scenario.getScheme(); @@ -260,28 +260,27 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest String host = "localhost"; int port = connector.getLocalPort(); - Destination destinationBefore = client.getDestination(scenario.getScheme(), host, port); - - ContentResponse response = client.newRequest(host, port) - .scheme(scenario.getScheme()) - .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) - .send(); + Request request = client.newRequest(host, port) + .scheme(scenario.getScheme()) + .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); + Destination destinationBefore = client.resolveDestination(request); + ContentResponse response = request.send(); assertEquals(200, response.getStatus()); - Destination destinationAfter = client.getDestination(scenario.getScheme(), host, port); + Destination destinationAfter = client.resolveDestination(request); assertSame(destinationBefore, destinationAfter); client.setRemoveIdleDestinations(true); - response = client.newRequest(host, port) + request = client.newRequest(host, port) .scheme(scenario.getScheme()) - .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) - .send(); + .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); + response = request.send(); assertEquals(200, response.getStatus()); - destinationAfter = client.getDestination(scenario.getScheme(), host, port); + destinationAfter = client.resolveDestination(request); assertNotSame(destinationBefore, destinationAfter); } @@ -298,14 +297,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest server.stop(); Request request = client.newRequest(host, port).scheme(scenario.getScheme()); - try - { - request.send(); - fail("Request to a closed port must fail"); - } - catch (Exception expected) - { - } + assertThrows(Exception.class, () -> request.send()); long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(1); while (!client.getDestinations().isEmpty() && System.nanoTime() < deadline) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java index 60f788e0482..551f1e61c73 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java @@ -1,26 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; import java.io.EOFException; import java.nio.charset.StandardCharsets; -import java.util.Collections; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -63,7 +63,7 @@ public class HttpReceiverOverHTTPTest private ByteArrayEndPoint endPoint; private HttpConnectionOverHTTP connection; - public static Stream complianceModes() throws Exception + public static Stream complianceModes() { return Stream.of( HttpCompliance.RFC7230, @@ -96,7 +96,7 @@ public class HttpReceiverOverHTTPTest { HttpRequest request = (HttpRequest)client.newRequest("http://localhost"); FutureResponseListener listener = new FutureResponseListener(request); - HttpExchange exchange = new HttpExchange(destination, request, Collections.singletonList(listener)); + HttpExchange exchange = new HttpExchange(destination, request, List.of(listener)); boolean associated = connection.getHttpChannel().associate(exchange); assertTrue(associated); exchange.requestComplete(null); @@ -106,7 +106,7 @@ public class HttpReceiverOverHTTPTest @ParameterizedTest @MethodSource("complianceModes") - public void test_Receive_NoResponseContent(HttpCompliance compliance) throws Exception + public void testReceiveNoResponseContent(HttpCompliance compliance) throws Exception { init(compliance); endPoint.addInput( @@ -130,7 +130,7 @@ public class HttpReceiverOverHTTPTest @ParameterizedTest @MethodSource("complianceModes") - public void test_Receive_ResponseContent(HttpCompliance compliance) throws Exception + public void testReceiveResponseContent(HttpCompliance compliance) throws Exception { init(compliance); String content = "0123456789ABCDEF"; @@ -158,7 +158,7 @@ public class HttpReceiverOverHTTPTest @ParameterizedTest @MethodSource("complianceModes") - public void test_Receive_ResponseContent_EarlyEOF(HttpCompliance compliance) throws Exception + public void testReceiveResponseContentEarlyEOF(HttpCompliance compliance) throws Exception { init(compliance); String content1 = "0123456789"; @@ -180,7 +180,7 @@ public class HttpReceiverOverHTTPTest @ParameterizedTest @MethodSource("complianceModes") - public void test_Receive_ResponseContent_IdleTimeout(HttpCompliance compliance) throws Exception + public void testReceiveResponseContentIdleTimeout(HttpCompliance compliance) throws Exception { init(compliance); endPoint.addInput( @@ -201,7 +201,7 @@ public class HttpReceiverOverHTTPTest @ParameterizedTest @MethodSource("complianceModes") - public void test_Receive_BadResponse(HttpCompliance compliance) throws Exception + public void testReceiveBadResponse(HttpCompliance compliance) throws Exception { init(compliance); endPoint.addInput( @@ -220,7 +220,7 @@ public class HttpReceiverOverHTTPTest @ParameterizedTest @MethodSource("complianceModes") - public void test_FillInterested_RacingWith_BufferRelease(HttpCompliance compliance) throws Exception + public void testFillInterestedRacingWithBufferRelease(HttpCompliance compliance) throws Exception { init(compliance); connection = new HttpConnectionOverHTTP(endPoint, destination, new Promise.Adapter<>()) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpSenderOverHTTPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpSenderOverHTTPTest.java index 3707264edc4..374fa8eda0b 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpSenderOverHTTPTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpSenderOverHTTPTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.http; @@ -63,7 +63,7 @@ public class HttpSenderOverHTTPTest } @Test - public void test_Send_NoRequestContent() throws Exception + public void testSendNoRequestContent() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080)); @@ -97,7 +97,7 @@ public class HttpSenderOverHTTPTest @Test @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_Send_NoRequestContent_IncompleteFlush() throws Exception + public void testSendNoRequestContentIncompleteFlush() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint("", 16); HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080)); @@ -125,7 +125,7 @@ public class HttpSenderOverHTTPTest } @Test - public void test_Send_NoRequestContent_Exception() throws Exception + public void testSendNoRequestContentException() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); // Shutdown output to trigger the exception on write @@ -157,7 +157,7 @@ public class HttpSenderOverHTTPTest } @Test - public void test_Send_NoRequestContent_IncompleteFlush_Exception() throws Exception + public void testSendNoRequestContentIncompleteFlushException() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint("", 16); HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080)); @@ -193,7 +193,7 @@ public class HttpSenderOverHTTPTest } @Test - public void test_Send_SmallRequestContent_InOneBuffer() throws Exception + public void testSendSmallRequestContentInOneBuffer() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080)); @@ -228,7 +228,7 @@ public class HttpSenderOverHTTPTest } @Test - public void test_Send_SmallRequestContent_InTwoBuffers() throws Exception + public void testSendSmallRequestContentInTwoBuffers() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080)); @@ -264,7 +264,7 @@ public class HttpSenderOverHTTPTest } @Test - public void test_Send_SmallRequestContent_Chunked_InTwoChunks() throws Exception + public void testSendSmallRequestContentChunkedInTwoChunks() throws Exception { ByteArrayEndPoint endPoint = new ByteArrayEndPoint(); HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", 8080)); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/jmx/HttpClientJMXTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/jmx/HttpClientJMXTest.java index c5d254cc3c3..d3d815d9387 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/jmx/HttpClientJMXTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/jmx/HttpClientJMXTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.jmx; @@ -39,7 +39,6 @@ public class HttpClientJMXTest String name = "foo"; HttpClient httpClient = new HttpClient(); httpClient.setName(name); - httpClient.start(); try { @@ -47,6 +46,7 @@ public class HttpClientJMXTest MBeanContainer mbeanContainer = new MBeanContainer(mbeanServer); // Adding MBeanContainer as a bean will trigger the registration of MBeans. httpClient.addBean(mbeanContainer); + httpClient.start(); String domain = HttpClient.class.getPackage().getName(); ObjectName pattern = new ObjectName(domain + ":type=" + HttpClient.class.getSimpleName().toLowerCase(Locale.ENGLISH) + ",*"); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java index d65f030d581..9f74d7c9a39 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.ssl; @@ -87,7 +87,7 @@ public class NeedWantClientAuthTest private SslContextFactory.Server createServerSslContextFactory() { SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); return sslContextFactory; } @@ -146,7 +146,7 @@ public class NeedWantClientAuthTest }); SslContextFactory.Client clientSSL = new SslContextFactory.Client(true); - clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks"); + clientSSL.setKeyStorePath("src/test/resources/client_keystore.p12"); clientSSL.setKeyStorePassword("storepwd"); startClient(clientSSL); @@ -237,7 +237,7 @@ public class NeedWantClientAuthTest }); SslContextFactory.Client clientSSL = new SslContextFactory.Client(true); - clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks"); + clientSSL.setKeyStorePath("src/test/resources/client_keystore.p12"); clientSSL.setKeyStorePassword("storepwd"); startClient(clientSSL); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java index f055df1e0e3..defbb6bb7b2 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.ssl; @@ -77,7 +77,7 @@ public class SslBytesClientTest extends SslBytesTest clientConnector.setSslContextFactory(sslContextFactory); client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); client.setMaxConnectionsPerDestination(1); - File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks"); + File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12"); sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath()); sslContextFactory.setKeyStorePassword("storepwd"); client.start(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java index 01b4c7b801a..c961343c3c5 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.ssl; @@ -117,7 +117,7 @@ public class SslBytesServerTest extends SslBytesTest httpParses.set(0); serverEndPoint.set(null); - File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks"); + File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12"); sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath()); sslContextFactory.setKeyStorePassword("storepwd"); @@ -1397,6 +1397,7 @@ public class SslBytesServerTest extends SslBytesTest { case APPLICATION: fail("application data not allows after renegotiate"); + return; // this is just to avoid checkstyle warning case ALERT: break loop; default: @@ -1802,7 +1803,7 @@ public class SslBytesServerTest extends SslBytesTest assertTrue(latch.await(idleTimeout * 2, TimeUnit.MILLISECONDS)); - // Be sure that the server sent a SSL close alert + // Be sure that the server sent an SSL close alert TLSRecord record = proxy.readFromServer(); assertNotNull(record); assertEquals(TLSRecord.Type.ALERT, record.getType()); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java index d3c94429527..72748ffded6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.ssl; @@ -33,14 +33,14 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertTrue; public abstract class SslBytesTest { - protected final Logger logger = Log.getLogger(getClass()); + protected final Logger logger = LoggerFactory.getLogger(getClass()); public static class TLSRecord { @@ -146,10 +146,7 @@ public abstract class SslBytesTest } catch (IOException x) { - logger.info(x.getClass() + ": " + x.getMessage()); - - if (logger.isDebugEnabled()) - logger.debug(x); + logger.warn("Unable to accept from {}", serverSocket, x); } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java index 9fa25956d48..48b6dd6c6b2 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.ssl; @@ -42,7 +42,7 @@ public class SslConnectionTest @Test public void testSslConnectionClosedBeforeFill() throws Exception { - File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks"); + File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12"); SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath()); sslContextFactory.setKeyStorePassword("storepwd"); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/DeferredContentProviderTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/DeferredContentProviderTest.java index b8e26dd99b9..88304c9f249 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/DeferredContentProviderTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/DeferredContentProviderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentProviderTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentProviderTest.java index 727edc85687..97f0ba0fe6c 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentProviderTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentProviderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java index e2c34af15ef..f84ca04d5df 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -31,10 +32,12 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -59,6 +62,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck public class MultiPartContentProviderTest extends AbstractHttpClientServerTest { @ParameterizedTest @@ -288,6 +292,7 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest MultiPartContentProvider multiPart = new MultiPartContentProvider(); PathContentProvider content = new PathContentProvider(contentType, tmpPath); content.setByteBufferPool(client.getByteBufferPool()); + content.setUseDirectByteBuffers(client.isUseOutputDirectByteBuffers()); multiPart.addFilePart(name, tmpPath.getFileName().toString(), content, null); multiPart.close(); ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) @@ -435,6 +440,46 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); } + @ParameterizedTest + @ArgumentsSource(ScenarioProvider.class) + public void testEachPartIsClosed(Scenario scenario) throws Exception + { + String name1 = "field1"; + String value1 = "value1"; + String name2 = "field2"; + String value2 = "value2"; + start(scenario, new AbstractMultiPartHandler() + { + @Override + protected void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + Collection parts = request.getParts(); + assertEquals(2, parts.size()); + Iterator iterator = parts.iterator(); + Part part1 = iterator.next(); + assertEquals(name1, part1.getName()); + assertEquals(value1, IO.toString(part1.getInputStream())); + Part part2 = iterator.next(); + assertEquals(name2, part2.getName()); + assertEquals(value2, IO.toString(part2.getInputStream())); + } + }); + + AtomicInteger closeCount = new AtomicInteger(); + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart(name1, new CloseableStringContentProvider(value1, closeCount::incrementAndGet), null); + multiPart.addFieldPart(name2, new CloseableStringContentProvider(value2, closeCount::incrementAndGet), null); + multiPart.close(); + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .method(HttpMethod.POST) + .content(multiPart) + .send(); + + assertEquals(200, response.getStatus()); + assertEquals(2, closeCount.get()); + } + private abstract static class AbstractMultiPartHandler extends AbstractHandler { @Override @@ -448,4 +493,49 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest protected abstract void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; } + + private static class CloseableStringContentProvider extends StringContentProvider + { + private final Runnable closeFn; + + private CloseableStringContentProvider(String content, Runnable closeFn) + { + super(content); + this.closeFn = closeFn; + } + + @Override + public Iterator iterator() + { + return new CloseableIterator<>(super.iterator()); + } + + private class CloseableIterator implements Iterator, Closeable + { + private final Iterator iterator; + + public CloseableIterator(Iterator iterator) + { + this.iterator = iterator; + } + + @Override + public boolean hasNext() + { + return iterator.hasNext(); + } + + @Override + public T next() + { + return iterator.next(); + } + + @Override + public void close() + { + closeFn.run(); + } + } + } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java index d4899900ba8..dfd157edf18 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -51,8 +51,6 @@ import org.eclipse.jetty.server.session.DefaultSessionIdManager; import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -60,6 +58,8 @@ import org.junit.jupiter.api.condition.DisabledOnJre; import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -71,7 +71,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; @DisabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10}) public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest { - private static final Logger LOG = Log.getLogger(SPNEGOAuthenticationTest.class); + private static final Logger LOG = LoggerFactory.getLogger(SPNEGOAuthenticationTest.class); static { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java index f25ba5fdc00..0a512bd6bf4 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.client.util; @@ -51,6 +51,7 @@ public class TypedContentProviderTest extends AbstractHttpClientServerTest final String value1 = "1"; final String name2 = "b"; final String value2 = "2"; + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck final String value3 = "\u20AC"; start(scenario, new AbstractHandler() diff --git a/jetty-client/src/test/resources/client_keystore.jks b/jetty-client/src/test/resources/client_keystore.jks deleted file mode 100644 index 9c31ff30c63..00000000000 Binary files a/jetty-client/src/test/resources/client_keystore.jks and /dev/null differ diff --git a/jetty-client/src/test/resources/client_keystore.p12 b/jetty-client/src/test/resources/client_keystore.p12 new file mode 100644 index 00000000000..429720049b8 Binary files /dev/null and b/jetty-client/src/test/resources/client_keystore.p12 differ diff --git a/jetty-client/src/test/resources/jetty-logging.properties b/jetty-client/src/test/resources/jetty-logging.properties index f74a4da98d1..e6bbf9a6ca0 100644 --- a/jetty-client/src/test/resources/jetty-logging.properties +++ b/jetty-client/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.client.LEVEL=DEBUG #org.eclipse.jetty.io.ChannelEndPoint.LEVEL=DEBUG diff --git a/jetty-client/src/test/resources/keystore.jks b/jetty-client/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-client/src/test/resources/keystore.jks and /dev/null differ diff --git a/jetty-client/src/test/resources/keystore.p12 b/jetty-client/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..70d68ea7f44 Binary files /dev/null and b/jetty-client/src/test/resources/keystore.p12 differ diff --git a/jetty-client/src/test/resources/readme_keystores.txt b/jetty-client/src/test/resources/readme_keystores.txt new file mode 100644 index 00000000000..9d4d40e2eb5 --- /dev/null +++ b/jetty-client/src/test/resources/readme_keystores.txt @@ -0,0 +1,27 @@ +Since OpenJDK 13.0.2/11.0.6 it is required that CA certificates have the extension CA=true. + +The keystores are generated in the following way: + +# Generates the server keystore. Note the BasicConstraint=CA:true extension. +$ keytool -v -genkeypair -validity 36500 -keyalg RSA -keysize 2048 -keystore keystore.p12 -storetype pkcs12 -dname "CN=server, OU=Jetty, O=Webtide, L=Omaha, S=NE, C=US" -ext BC=CA:true + +# Export the server certificate. +$ keytool -v -export -keystore keystore.p12 -rfc -file server.crt + +# Export the server private key. +$ openssl pkcs12 -in keystore.p12 -nodes -nocerts -out server.key + +# Generate the client keystore. +$ keytool -v -genkeypair -validity 36500 -keyalg RSA -keysize 2048 -keystore client_keystore.p12 -storetype pkcs12 -dname "CN=client, OU=Jetty, O=Webtide, L=Omaha, S=NE, C=US" + +# Generate the Certificate Signing Request. +$ keytool -certreq -file client.csr -keystore client_keystore.p12 + +# Sign the CSR. +$ openssl x509 -req -days 36500 -in client.csr -CA server.crt -CAkey server.key -CAcreateserial -sha256 -out signed.crt + +# Import the server certificate into the client keystore. +$ keytool -v -import -alias ca -file server.crt -keystore client_keystore.p12 + +# Import the signed CSR. +$ keytool -import -file signed.crt -keystore client_keystore.p12 diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 45376093155..3ca358458f1 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -45,13 +45,21 @@ jetty-xml ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty jetty-jmx ${project.version} true - + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-deploy/src/main/config/etc/jetty-decorate.xml b/jetty-deploy/src/main/config/etc/jetty-decorate.xml new file mode 100644 index 00000000000..3abfb16941b --- /dev/null +++ b/jetty-deploy/src/main/config/etc/jetty-decorate.xml @@ -0,0 +1,15 @@ + + + + + + + + + /etc/jetty-web-decorate.xml + + + + + + diff --git a/jetty-deploy/src/main/config/etc/jetty-deploy.xml b/jetty-deploy/src/main/config/etc/jetty-deploy.xml index c279a388389..d244576c146 100644 --- a/jetty-deploy/src/main/config/etc/jetty-deploy.xml +++ b/jetty-deploy/src/main/config/etc/jetty-deploy.xml @@ -36,9 +36,9 @@ --> - + - + jetty.deploy.monitoredPath diff --git a/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml b/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml new file mode 100644 index 00000000000..f91048c4b73 --- /dev/null +++ b/jetty-deploy/src/main/config/etc/jetty-web-decorate.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/jetty-deploy/src/main/config/modules/decorate.mod b/jetty-deploy/src/main/config/modules/decorate.mod new file mode 100644 index 00000000000..85bc367b981 --- /dev/null +++ b/jetty-deploy/src/main/config/modules/decorate.mod @@ -0,0 +1,14 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Jetty setup to support Decoration of Listeners, Filters and Servlets within a deployed webapp. +This module uses the DecoratingListener to register an object set as a context attribute +as a dynamic decorator. This module sets the "org.eclipse.jetty.webapp.DecoratingListener" +context attribute with the name of the context attribute that will be listened to. +By default the attribute is "org.eclipse.jetty.webapp.decorator". + +[depend] +deploy + +[xml] +etc/jetty-decorate.xml diff --git a/jetty-deploy/src/main/java/module-info.java b/jetty-deploy/src/main/java/module-info.java index 629683276b7..783914725a3 100644 --- a/jetty-deploy/src/main/java/module-info.java +++ b/jetty-deploy/src/main/java/module-info.java @@ -1,33 +1,33 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.deploy { exports org.eclipse.jetty.deploy; exports org.eclipse.jetty.deploy.bindings; + exports org.eclipse.jetty.deploy.graph; exports org.eclipse.jetty.deploy.jmx to org.eclipse.jetty.jmx; exports org.eclipse.jetty.deploy.providers; requires java.xml; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.webapp; + requires transitive org.eclipse.jetty.webapp; requires org.eclipse.jetty.xml; + requires org.slf4j; // Only required if using JMX. requires static org.eclipse.jetty.jmx; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java index 186c1100ce8..1258b54c4bd 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java index 0b93aceaf21..22e7840098c 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; @@ -27,8 +27,8 @@ import java.util.Set; import org.eclipse.jetty.deploy.graph.Graph; import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The lifecycle of an App in the {@link DeploymentManager}. @@ -40,7 +40,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class AppLifeCycle extends Graph { - private static final Logger LOG = Log.getLogger(AppLifeCycle.class); + private static final Logger LOG = LoggerFactory.getLogger(AppLifeCycle.class); private static final String ALL_NODES = "*"; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java index 2f186c29579..e85da207c7e 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ConfigurationManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ConfigurationManager.java index 758e6f66f2a..5e8970a5624 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ConfigurationManager.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/ConfigurationManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java index 64de4a6444e..3793d99f7b6 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; @@ -46,10 +46,10 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The Deployment Manager. @@ -68,7 +68,7 @@ import org.eclipse.jetty.xml.XmlConfiguration; @ManagedObject("Deployment Manager") public class DeploymentManager extends ContainerLifeCycle { - private static final Logger LOG = Log.getLogger(DeploymentManager.class); + private static final Logger LOG = LoggerFactory.getLogger(DeploymentManager.class); private MultiException onStartupErrors; /** @@ -172,7 +172,7 @@ public class DeploymentManager extends ContainerLifeCycle for (AppProvider provider : providers) { if (_providers.add(provider)) - addBean(provider); + addBean(provider, true); } } @@ -186,7 +186,7 @@ public class DeploymentManager extends ContainerLifeCycle if (isRunning()) throw new IllegalStateException(); _providers.add(provider); - addBean(provider); + addBean(provider, true); } public void setLifeCycleBindings(Collection bindings) @@ -523,6 +523,7 @@ public class DeploymentManager extends ContainerLifeCycle catch (Throwable t) { LOG.warn("Unable to reach node goal: " + nodeName, t); + // migrate to FAILED node Node failed = _lifecycle.getNodeByName(AppLifeCycle.FAILED); appentry.setLifeCycleNode(failed); @@ -533,7 +534,7 @@ public class DeploymentManager extends ContainerLifeCycle catch (Throwable ignore) { // The runBindings failed for 'failed' node - LOG.ignore(ignore); + LOG.trace("IGNORED", ignore); } if (isStarting()) diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/PropertiesConfigurationManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/PropertiesConfigurationManager.java index e7708db5b08..14424b416db 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/PropertiesConfigurationManager.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/PropertiesConfigurationManager.java @@ -1,26 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; import java.io.FileNotFoundException; import java.io.IOException; -import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -29,6 +28,7 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.annotation.Name; +import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.resource.Resource; /** @@ -37,21 +37,33 @@ import org.eclipse.jetty.util.resource.Resource; * Supplies properties defined in a file. */ @ManagedObject("Configure deployed webapps via properties") -public class PropertiesConfigurationManager implements ConfigurationManager +public class PropertiesConfigurationManager implements ConfigurationManager, Dumpable { private String _properties; - private final Map _map = new HashMap(); + private final Map _map = new HashMap<>(); public PropertiesConfigurationManager(String properties) { + if (properties != null) + { + try + { + setFile(properties); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } } public PropertiesConfigurationManager() { + this(null); } @ManagedAttribute("A file or URL of properties") - public void setFile(String resource) throws MalformedURLException, IOException + public void setFile(String resource) throws IOException { _properties = resource; _map.clear(); @@ -69,13 +81,10 @@ public class PropertiesConfigurationManager implements ConfigurationManager _map.put(name, value); } - /** - * @see org.eclipse.jetty.deploy.ConfigurationManager#getProperties() - */ @Override public Map getProperties() { - return new HashMap<>(_map); + return _map; } private void loadProperties(String resource) throws FileNotFoundException, IOException @@ -86,9 +95,25 @@ public class PropertiesConfigurationManager implements ConfigurationManager Properties properties = new Properties(); properties.load(file.getInputStream()); for (Map.Entry entry : properties.entrySet()) - { _map.put(entry.getKey().toString(), String.valueOf(entry.getValue())); - } } } + + @Override + public String toString() + { + return String.format("%s@%x{%s}", this.getClass(), hashCode(), _properties); + } + + @Override + public String dump() + { + return Dumpable.dump(this); + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + Dumpable.dumpObjects(out, indent, toString(), _map); + } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugBinding.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugBinding.java index 8f29bc38f65..4930596d94a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugBinding.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugBinding.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; @@ -21,12 +21,12 @@ package org.eclipse.jetty.deploy.bindings; import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppLifeCycle; import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DebugBinding implements AppLifeCycle.Binding { - private static final Logger LOG = Log.getLogger(DebugBinding.class); + private static final Logger LOG = LoggerFactory.getLogger(DebugBinding.class); final String[] _targets; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugListenerBinding.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugListenerBinding.java index 1a6b237fa54..e468cddfdc4 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugListenerBinding.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugListenerBinding.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java index 17f8353a26a..1b69c90e40a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.java @@ -1,33 +1,35 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppLifeCycle; +import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.graph.Node; +import org.eclipse.jetty.deploy.providers.WebAppProvider; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Provides a way of globally setting various aspects of webapp contexts. @@ -44,7 +46,7 @@ import org.eclipse.jetty.xml.XmlConfiguration; */ public class GlobalWebappConfigBinding implements AppLifeCycle.Binding { - private static final Logger LOG = Log.getLogger(GlobalWebappConfigBinding.class); + private static final Logger LOG = LoggerFactory.getLogger(GlobalWebappConfigBinding.class); private String _jettyXml; @@ -63,7 +65,7 @@ public class GlobalWebappConfigBinding implements AppLifeCycle.Binding { return new String[]{"deploying"}; } - + @Override public void processBinding(Node node, App app) throws Exception { @@ -94,6 +96,13 @@ public class GlobalWebappConfigBinding implements AppLifeCycle.Binding XmlConfiguration jettyXmlConfig = new XmlConfiguration(globalContextSettings); Resource resource = Resource.newResource(app.getOriginId()); app.getDeploymentManager().scope(jettyXmlConfig, resource); + AppProvider appProvider = app.getAppProvider(); + if (appProvider instanceof WebAppProvider) + { + WebAppProvider webAppProvider = ((WebAppProvider)appProvider); + if (webAppProvider.getConfigurationManager() != null) + jettyXmlConfig.getProperties().putAll(webAppProvider.getConfigurationManager().getProperties()); + } WebAppClassLoader.runWithServerClassAccess(() -> { jettyXmlConfig.configure(context); diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/OrderedGroupBinding.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/OrderedGroupBinding.java index 8881bb62fc9..75d237a20c7 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/OrderedGroupBinding.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/OrderedGroupBinding.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java index c914dd275de..b14fc9352d0 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java index 9edf79a3aba..38a9c05ba5a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStopper.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStopper.java index 1d75b829907..c9b54475c5e 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStopper.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStopper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java index 2653d4b6f16..e65cac9cf5a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java index db37dd12056..4d1ab505ac2 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java index f1ecb4267fe..cb2323779d3 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.graph; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java index 6c59f8a7b0e..8c569b1c194 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.graph; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/GraphOutputDot.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/GraphOutputDot.java index f462d5b400f..f000b355294 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/GraphOutputDot.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/GraphOutputDot.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.graph; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Node.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Node.java index ee214141086..9552677ed9a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Node.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Node.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.graph; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Path.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Path.java index 2e2c5d5b12c..8316a228c0d 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Path.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Path.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.graph; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java index 0b9feab60e8..728ab29075b 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java index 30f9b7cb87d..9b40babadb9 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.jmx; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java index 1e7beb0e2b6..6a30089c58d 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java index 5df065738a2..5452c096952 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java index 0507816c76b..32dd02b1393 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.providers; @@ -36,18 +36,18 @@ import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * */ @ManagedObject("Abstract Provider for loading webapps") -public abstract class ScanningAppProvider extends AbstractLifeCycle implements AppProvider +public abstract class ScanningAppProvider extends ContainerLifeCycle implements AppProvider { - private static final Logger LOG = Log.getLogger(ScanningAppProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(ScanningAppProvider.class); private Map _appMap = new HashMap(); @@ -81,11 +81,13 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A protected ScanningAppProvider() { + this(null); } protected ScanningAppProvider(FilenameFilter filter) { _filenameFilter = filter; + addBean(_appMap); } protected void setFilenameFilter(FilenameFilter filter) @@ -141,16 +143,21 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A _scanner.setRecursive(_recursive); _scanner.setFilenameFilter(_filenameFilter); _scanner.setReportDirs(true); + _scanner.setScanDepth(1); //consider direct dir children of monitored dir _scanner.addListener(_scannerListener); - _scanner.start(); + + addBean(_scanner); + + super.doStart(); } @Override protected void doStop() throws Exception { + super.doStop(); if (_scanner != null) { - _scanner.stop(); + removeBean(_scanner); _scanner.removeListener(_scannerListener); _scanner = null; } @@ -307,4 +314,10 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A ); _scanner.scan(); } + + @Override + public String toString() + { + return String.format("%s@%x%s", this.getClass(), hashCode(), _monitored); + } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java index 5217e862ce9..1b98f7822ec 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.providers; @@ -81,6 +81,11 @@ public class WebAppProvider extends ScanningAppProvider String lowername = name.toLowerCase(Locale.ENGLISH); File file = new File(dir, name); + Resource r = Resource.newResource(file); + if (getMonitoredResources().contains(r) && r.isDirectory()) + { + return false; + } // ignore hidden files if (lowername.startsWith(".")) @@ -206,6 +211,7 @@ public class WebAppProvider extends ScanningAppProvider */ public void setConfigurationManager(ConfigurationManager configurationManager) { + updateBean(_configurationManager, configurationManager); _configurationManager = configurationManager; } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/jmx/WebAppProviderMBean.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/jmx/WebAppProviderMBean.java index 6200f1a8c4b..329e91e2036 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/jmx/WebAppProviderMBean.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/jmx/WebAppProviderMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.providers.jmx; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java index dabea2eaa3f..022f3355ba0 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/FileID.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/FileID.java index 4bd620aba16..3bc7208329d 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/FileID.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/FileID.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.util; diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java index 81856ab941b..681835e6a9a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/util/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/AppLifeCycle.svg b/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/AppLifeCycle.svg index 43841b1fb64..7e62945425c 100644 --- a/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/AppLifeCycle.svg +++ b/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/AppLifeCycle.svg @@ -4,34 +4,12 @@ - - + + - + image/svg+xml - + diff --git a/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DefaultAppLifeCycleBindings.svg b/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DefaultAppLifeCycleBindings.svg index 969021da7fa..a74d356d80a 100644 --- a/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DefaultAppLifeCycleBindings.svg +++ b/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DefaultAppLifeCycleBindings.svg @@ -4,46 +4,8 @@ - - + - - + + - + image/svg+xml - + diff --git a/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DeploymentManager_Roles.svg b/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DeploymentManager_Roles.svg index f208563ffa8..fe849872f5c 100644 --- a/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DeploymentManager_Roles.svg +++ b/jetty-deploy/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DeploymentManager_Roles.svg @@ -4,34 +4,12 @@ - - + + - + image/svg+xml - + diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCyclePathCollector.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCyclePathCollector.java index 454a24296e3..954e1f5e0f7 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCyclePathCollector.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCyclePathCollector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java index 8008425d5ae..5ae5d2fc6c8 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; @@ -86,13 +86,13 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Deployed_Deployed() + public void testFindPathDeployedDeployed() { assertNoPath("deployed", "deployed"); } @Test - public void testFindPath_Deployed_Started() + public void testFindPathDeployedStarted() { List expected = new ArrayList(); expected.add("deployed"); @@ -102,7 +102,7 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Deployed_Undeployed() + public void testFindPathDeployedUndeployed() { List expected = new ArrayList(); expected.add("deployed"); @@ -112,7 +112,7 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Started_Deployed() + public void testFindPathStartedDeployed() { List expected = new ArrayList(); expected.add("started"); @@ -122,13 +122,13 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Started_Started() + public void testFindPathStartedStarted() { assertNoPath("started", "started"); } @Test - public void testFindPath_Started_Undeployed() + public void testFindPathStartedUndeployed() { List expected = new ArrayList(); expected.add("started"); @@ -140,7 +140,7 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Undeployed_Deployed() + public void testFindPathUndeployedDeployed() { List expected = new ArrayList(); expected.add("undeployed"); @@ -150,7 +150,7 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Undeployed_Started() + public void testFindPathUndeployedStarted() { List expected = new ArrayList(); expected.add("undeployed"); @@ -162,7 +162,7 @@ public class AppLifeCycleTest } @Test - public void testFindPath_Undeployed_Uavailable() + public void testFindPathUndeployedUnavailable() { assertNoPath("undeployed", "undeployed"); } diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/BadAppDeployTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/BadAppDeployTest.java index b939781fdaa..0c99e06d673 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/BadAppDeployTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/BadAppDeployTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; @@ -24,6 +24,7 @@ import java.nio.file.Path; import javax.servlet.ServletException; import org.eclipse.jetty.deploy.providers.WebAppProvider; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandlerCollection; @@ -33,12 +34,11 @@ import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.webapp.WebAppContext; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.LoggerFactory; import static java.time.Duration.ofSeconds; import static org.hamcrest.MatcherAssert.assertThat; @@ -63,7 +63,7 @@ public class BadAppDeployTest } @Test - public void testBadApp_ThrowOnUnavailableTrue_XmlOrder() throws Exception + public void testBadAppThrowOnUnavailableTrueXmlOrder() throws Exception { /* Non-working Bean Order as reported in Issue #3620 It is important that this Order be maintained for an accurate test case. @@ -103,10 +103,9 @@ public class BadAppDeployTest assertTimeoutPreemptively(ofSeconds(10), () -> { - - try (StacklessLogging ignore = new StacklessLogging(Log.getLogger(WebAppContext.class), - Log.getLogger(DeploymentManager.class), - Log.getLogger("org.eclipse.jetty.server.handler.ContextHandler.badapp"))) + try (StacklessLogging ignore = new StacklessLogging(LoggerFactory.getLogger(WebAppContext.class), + LoggerFactory.getLogger(DeploymentManager.class), + LoggerFactory.getLogger("org.eclipse.jetty.server.handler.ContextHandler.badapp"))) { ServletException cause = assertThrows(ServletException.class, () -> server.start()); assertThat(cause.getMessage(), containsString("intentionally")); @@ -116,7 +115,7 @@ public class BadAppDeployTest } @Test - public void testBadApp_ThrowOnUnavailableTrue_EmbeddedOrder() throws Exception + public void testBadAppThrowOnUnavailableTrueEmbeddedOrder() throws Exception { /* Working Bean Order ### BEAN: QueuedThreadPool[qtp1530388690]@5b37e0d2{STOPPED,8<=0<=200,i=0,r=-1,q=0}[NO_TRY] @@ -157,9 +156,9 @@ public class BadAppDeployTest assertTimeoutPreemptively(ofSeconds(10), () -> { - try (StacklessLogging ignore = new StacklessLogging(Log.getLogger(WebAppContext.class), - Log.getLogger(DeploymentManager.class), - Log.getLogger("org.eclipse.jetty.server.handler.ContextHandler.badapp"))) + try (StacklessLogging ignore = new StacklessLogging(LoggerFactory.getLogger(WebAppContext.class), + LoggerFactory.getLogger(DeploymentManager.class), + LoggerFactory.getLogger("org.eclipse.jetty.server.handler.ContextHandler.badapp"))) { ServletException cause = assertThrows(ServletException.class, () -> server.start()); assertThat(cause.getMessage(), containsString("intentionally")); diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerLifeCyclePathTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerLifeCyclePathTest.java index ba920b73a1e..1ab2780a900 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerLifeCyclePathTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerLifeCyclePathTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; public class DeploymentManagerLifeCyclePathTest { @Test - public void testStateTransition_NewToDeployed() throws Exception + public void testStateTransitionNewToDeployed() throws Exception { DeploymentManager depman = new DeploymentManager(); depman.setContexts(new ContextHandlerCollection()); @@ -64,7 +64,7 @@ public class DeploymentManagerLifeCyclePathTest } @Test - public void testStateTransition_Receive() throws Exception + public void testStateTransitionReceive() throws Exception { DeploymentManager depman = new DeploymentManager(); depman.setContexts(new ContextHandlerCollection()); @@ -90,7 +90,7 @@ public class DeploymentManagerLifeCyclePathTest } @Test - public void testStateTransition_DeployedToUndeployed() throws Exception + public void testStateTransitionDeployedToUndeployed() throws Exception { DeploymentManager depman = new DeploymentManager(); depman.setDefaultLifeCycleGoal(null); // no default diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java index 694fdb02a55..9ec4ff63584 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/JmxServiceConnection.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/JmxServiceConnection.java index 30c5cc67b47..e828c7f502c 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/JmxServiceConnection.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/JmxServiceConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java index ac78211d2f9..03ab19d3f1f 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java index 0567c4c6087..52faa4ae9c4 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBindingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.bindings; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java index f8d4525857f..9e6d238e7ae 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.graph; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java index 82bd338ca45..5a8c294fcc3 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderRuntimeUpdatesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.providers; @@ -27,14 +27,14 @@ import org.eclipse.jetty.deploy.test.XmlConfiguredJetty; 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.log.Log; -import org.eclipse.jetty.util.log.Logger; 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; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.condition.OS.WINDOWS; @@ -45,7 +45,7 @@ import static org.junit.jupiter.api.condition.OS.WINDOWS; @ExtendWith(WorkDirExtension.class) public class ScanningAppProviderRuntimeUpdatesTest { - private static final Logger LOG = Log.getLogger(ScanningAppProviderRuntimeUpdatesTest.class); + private static final Logger LOG = LoggerFactory.getLogger(ScanningAppProviderRuntimeUpdatesTest.class); public WorkDir testdir; private static XmlConfiguredJetty jetty; @@ -106,7 +106,7 @@ public class ScanningAppProviderRuntimeUpdatesTest } catch (InterruptedException e) { - LOG.warn(e); + LOG.warn("Sleep failed", e); } } while (_scans.get() < scan); diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java index 7e31d39424b..9d5ff015394 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ScanningAppProviderStartupTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.providers; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java index dab9119bc42..e5098e3b6c1 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/WebAppProviderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.providers; diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java index e593ceedbf1..a917a411d1a 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.deploy.test; @@ -366,7 +366,6 @@ public class XmlConfiguredJetty assertEquals(1, serverCount, "Server load count"); this._server = foundServer; - this._server.setStopTimeout(10); } public void removeWebapp(String name) diff --git a/jetty-deploy/src/test/resources/context-binding-test-1.xml b/jetty-deploy/src/test/resources/context-binding-test-1.xml index 360955997e2..9e5215df02a 100644 --- a/jetty-deploy/src/test/resources/context-binding-test-1.xml +++ b/jetty-deploy/src/test/resources/context-binding-test-1.xml @@ -1,7 +1,9 @@ + + org.eclipse.foo. - ` + diff --git a/jetty-deploy/src/test/resources/jetty-http.xml b/jetty-deploy/src/test/resources/jetty-http.xml index 9526b56890a..137da33293f 100644 --- a/jetty-deploy/src/test/resources/jetty-http.xml +++ b/jetty-deploy/src/test/resources/jetty-http.xml @@ -3,13 +3,13 @@ - + - + diff --git a/jetty-deploy/src/test/resources/jetty-logging.properties b/jetty-deploy/src/test/resources/jetty-logging.properties index 0a15aa423f2..363b21c3fb0 100644 --- a/jetty-deploy/src/test/resources/jetty-logging.properties +++ b/jetty-deploy/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl org.eclipse.jetty.deploy.LEVEL=WARN org.eclipse.jetty.util.Scanner=WARN #org.eclipse.jetty.webapp.LEVEL=DEBUG diff --git a/jetty-deploy/src/test/resources/jetty.xml b/jetty-deploy/src/test/resources/jetty.xml index 35810226482..7901921d362 100644 --- a/jetty-deploy/src/test/resources/jetty.xml +++ b/jetty-deploy/src/test/resources/jetty.xml @@ -84,7 +84,7 @@ 8192 true false - 4096 + 1024 + org.eclipse.jetty @@ -100,8 +120,8 @@ https://github.com/eclipse/jetty.project/tree/jetty-10.0.x-doc-refactor/jetty-documentation/src/main/asciidoc ../distribution-guide/index.html ../embedded-guide/index.html - ../quickstart-guideindex.html - ../contribution-guideindex.html + ../quickstart-guide/index.html + ../contribution-guide/index.html http://central.maven.org/maven2 ${project.version} ${maven.build.timestamp} diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/1-introduction.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/1-introduction.adoc index bcf8a644236..6cf9535e860 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/1-introduction.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/1-introduction.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - [[cg-introduction]] == Welcome! diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/2-community.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/2-community.adoc index be9564da82a..7cbdf1b364b 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/2-community.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/2-community.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - [[cg-community]] == Participate in the Community diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/3-source.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/3-source.adoc index 441835bf54f..c3e0c14d07c 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/3-source.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/3-source.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - [[cg-source]] == Participate in the Code diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/4-documentation.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/4-documentation.adoc index 8cdb44e4a52..fdc122b92ba 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/4-documentation.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/4-documentation.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - [[cg-documentation]] == Participate in the Documentation @@ -160,22 +159,23 @@ license blocks:: .... // -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // + .... Some admonition examples: diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/5-security.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/5-security.adoc index 027fe18c422..52648950adb 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/5-security.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/5-security.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - [[cg-security]] == Security diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/6-conclusion.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/6-conclusion.adoc index faf452014a9..b4108994d8f 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/6-conclusion.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/6-conclusion.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - [[cg-conclusion]] == Thank you! diff --git a/jetty-documentation/src/main/asciidoc/contribution-guide/index.adoc b/jetty-documentation/src/main/asciidoc/contribution-guide/index.adoc index 6a95fc38930..98e27818725 100644 --- a/jetty-documentation/src/main/asciidoc/contribution-guide/index.adoc +++ b/jetty-documentation/src/main/asciidoc/contribution-guide/index.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // :doctitle: Eclipse Jetty: Contribution Guide diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/alpn.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/alpn.adoc index 6fcce081245..6a3995d5ec8 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/alpn.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/alpn.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[alpn]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/chapter.adoc index fbb80ba6e18..3a17ed7e530 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/alpn/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[alpn-chapter]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/chapter.adoc index 088f4c730d6..3300b957ed5 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[annotations]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/quick-annotations-setup.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/quick-annotations-setup.adoc index 302cbff1756..f3ad072ba1c 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/quick-annotations-setup.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/quick-annotations-setup.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[annotations-quick-setup]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations-embedded.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations-embedded.adoc index dca6e528b35..34eefbfa136 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations-embedded.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations-embedded.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[using-annotations-embedded]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations.adoc index 43e070094a2..93eb15c82ef 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/annotations/using-annotations.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[using-annotations]] @@ -139,7 +139,7 @@ Here is an example, setting the context attribute in code (although you can also ---- WebAppContext context = new WebAppContext(); context.setAttribute("org.eclipse.jetty.containerInitializerOrder", - "org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer, com.acme.Foo.MySCI, *"); + "org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer, com.acme.Foo.MySCI, *"); ---- In this example, we ensure that the `WebSocketServerContainerInitializer` is the very first `ServletContainerInitializer` that is called, followed by MySCI and then any other `ServletContainerInitializer` instances that were discovered but not yet called. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/chapter.adoc index 61d75a6e0f9..3ec96a46951 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-connectors]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-connectors.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-connectors.adoc index f0adcb24ecd..5315f94759d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-connectors.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-connectors.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-connectors]] @@ -214,7 +214,7 @@ At this point the server has been configured with connectors for both HTTP and H .... [mybase] java -jar $JETTY_HOME/start.jar 2017-08-31 10:19:58.855:INFO::main: Logging initialized @372ms to org.eclipse.jetty.util.log.StdErrLog -2017-08-31 10:19:59.076:INFO:oejs.Server:main: jetty-9.4.6.v20170531 +2017-08-31 10:19:59.076:INFO:oejs.Server:main: jetty-{VERSION} 2017-08-31 10:19:59.125:INFO:oejs.AbstractConnector:main: Started ServerConnector@421e98e0{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 2017-08-31 10:19:59.150:INFO:oejus.SslContextFactory:main: x509=X509@5315b42e(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore) 2017-08-31 10:19:59.151:INFO:oejus.SslContextFactory:main: x509=X509@5d624da6(mykey,h=[],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore) @@ -280,7 +280,7 @@ Now when the server is started, HTTP connections will enter on port 5231: .... [mybase] java -jar ../start.jar 2017-08-31 10:31:32.955:INFO::main: Logging initialized @366ms to org.eclipse.jetty.util.log.StdErrLog -2017-08-31 10:31:33.109:INFO:oejs.Server:main: jetty-9.4.6.v20170531 +2017-08-31 10:31:33.109:INFO:oejs.Server:main: jetty-{VERSION} 2017-08-31 10:31:33.146:INFO:oejs.AbstractConnector:main: Started ServerConnector@2ef9b8bc{HTTP/1.1,[http/1.1]}{0.0.0.0:5231} ... 2017-08-31 10:31:33.263:INFO:oejs.Server:main: Started @675ms diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl-distribution.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl-distribution.adoc index d2725e63756..7e9ede2a76c 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl-distribution.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl-distribution.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-ssl-distribution]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl.adoc index f673c9ce369..c98f63e231b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/connectors/configuring-ssl.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-ssl]] @@ -386,9 +386,9 @@ ____ [source%nowrap,plain,linenums] ---- $ cd $JETTY_BASE -$ keytool -list -keystore etc/keystore -storetype jks -storepass '' -v +$ keytool -v -list -keystore etc/keystore -Keystore type: JKS +Keystore type: PKCS12 Keystore provider: SUN Your keystore contains 3 entries diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/chapter.adoc index 4b7d276ce13..d171d12fb5d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-contexts]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/configuring-virtual-hosts.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/configuring-virtual-hosts.adoc index 99ddb9dd20b..5dca037769d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/configuring-virtual-hosts.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/configuring-virtual-hosts.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-virtual-hosts]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/custom-error-pages.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/custom-error-pages.adoc index 95234c4a06d..ec71b83153a 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/custom-error-pages.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/custom-error-pages.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[custom-error-pages]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/serving-webapp-from-particular-port.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/serving-webapp-from-particular-port.adoc index 2551e96fb04..4c1c353527d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/serving-webapp-from-particular-port.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/serving-webapp-from-particular-port.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[serving-webapp-from-particular-port]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-context-path.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-context-path.adoc index 74606e81494..95ab908265f 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-context-path.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-context-path.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[setting-context-path]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-form-size.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-form-size.adoc index 9ffc5f8ce3f..d988e0d695e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-form-size.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/setting-form-size.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[setting-form-size]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/temporary-directories.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/temporary-directories.adoc index 671109941f4..090a444193a 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/temporary-directories.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/contexts/temporary-directories.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[ref-temporary-directories]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/anatomy-of-a-webapp.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/anatomy-of-a-webapp.adoc index 77b86f49d1b..ed84a54481b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/anatomy-of-a-webapp.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/anatomy-of-a-webapp.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[anatomy-of-a-webapp]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/automatic-webapp-deployment.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/automatic-webapp-deployment.adoc index f639d619a98..ccb00c4a639 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/automatic-webapp-deployment.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/automatic-webapp-deployment.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[automatic-webapp-deployment]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/chapter.adoc index 7bdd70ab2d5..209727a8430 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-deployment]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/configuring-specific-webapp-deployment.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/configuring-specific-webapp-deployment.adoc index ff95e52693a..44880099f8b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/configuring-specific-webapp-deployment.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/configuring-specific-webapp-deployment.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-specific-webapp-deployment]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-architecture.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-architecture.adoc index 7be1adc7f3b..ab12cd21c52 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-architecture.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-architecture.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[deployment-architecture]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-processing-webapps.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-processing-webapps.adoc index 52045e1d819..eef3c84c4b6 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-processing-webapps.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/deployment-processing-webapps.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-webapps]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/hot-deployment.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/hot-deployment.adoc index 664e5f1f398..66819bb5175 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/hot-deployment.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/hot-deployment.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[hot-deployment]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/overlay-deployer.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/overlay-deployer.adoc index 5395382821d..560e3ea2c80 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/overlay-deployer.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/overlay-deployer.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[overlay-deployer]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/quickstart-webapp.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/quickstart-webapp.adoc index ece12be99c1..028091437e8 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/quickstart-webapp.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/quickstart-webapp.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-webapp]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/static-content-deployment.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/static-content-deployment.adoc index a9f566c10fe..7ab9bec4b74 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/static-content-deployment.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/deploying/static-content-deployment.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[static-content-deployment]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/balancer-servlet.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/balancer-servlet.adoc index 199f5af55d4..bb4c73d644d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/balancer-servlet.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/balancer-servlet.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[balancer-servlet]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cgi-servlet.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cgi-servlet.adoc index 2b4c07f310a..232d9100eef 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cgi-servlet.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cgi-servlet.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[cgi-servlet]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/chapter.adoc index d03851e6b4e..ab4580e6bf5 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[advanced-extras]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cross-origin-filter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cross-origin-filter.adoc index 50cbf4144a9..a22e7b0d38d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cross-origin-filter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/cross-origin-filter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[cross-origin-filter]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/debug-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/debug-handler.adoc index 67b673dfbae..93faaa6070d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/debug-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/debug-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[debug-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-handler.adoc index 642f24b9388..e126953b1c2 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[default-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-servlet.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-servlet.adoc index 4182ad6ae00..b9ba8c5b7ee 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-servlet.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/default-servlet.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[default-servlet]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/dos-filter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/dos-filter.adoc index 07be5b0cbee..4761238cf7d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/dos-filter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/dos-filter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[dos-filter]] @@ -33,7 +33,6 @@ The Denial of Service (DoS) filter limits exposure to request flooding, whether The DoS filter keeps track of the number of requests from a connection per second. If the requests exceed the limit, Jetty rejects, delays, or throttles the request, and sends a warning message. The filter works on the assumption that the attacker might be written in simple blocking style, so by suspending requests you are hopefully consuming the attacker's resources. -The DoS filter is related to the QoS filter, using Continuations to prioritize requests and avoid thread starvation. [[dos-filter-using]] ==== Using the DoS Filter diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/error-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/error-handler.adoc index 400842899de..69e93d5c3fa 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/error-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/error-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[error-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/gzip-filter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/gzip-filter.adoc index 18bdb5b0236..a05a4e64311 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/gzip-filter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/gzip-filter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[gzip-filter]] @@ -31,7 +31,6 @@ The Jetty `GzipHandler` is a compression handler that you can apply to any dynamic resource (servlet). It fixes many of the bugs in commonly available compression filters: it works with asynchronous servlets; it handles all ways to set content length. -It has been tested with Jetty continuations and suspending requests. Some user-agents might be excluded from compression to avoid common browser bugs (yes, this means IE!). The `GzipHandler` can be added to the entire server by enabling the `gzip.mod` module. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/header-filter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/header-filter.adoc index 8fdbfa489d1..c8ccf4034ea 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/header-filter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/header-filter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[header-filter]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/inetaccess-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/inetaccess-handler.adoc index 97652bd403d..5223326c5ab 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/inetaccess-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/inetaccess-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[inetaccess-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/ipaccess-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/ipaccess-handler.adoc index 45811f9b063..bf6fefd2942 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/ipaccess-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/ipaccess-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[ipaccess-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/moved-context-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/moved-context-handler.adoc index 76252848f88..43e14006aa3 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/moved-context-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/moved-context-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[moved-context-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/proxy-servlet.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/proxy-servlet.adoc index 38c01bbfe25..2bca9568bac 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/proxy-servlet.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/proxy-servlet.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[proxy-servlet]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/qos-filter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/qos-filter.adoc index 7b4504204b8..2d5d927cdca 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/qos-filter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/qos-filter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[qos-filter]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/resource-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/resource-handler.adoc index f3aec28d3b7..d2d58961beb 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/resource-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/resource-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[resource-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/rewrite-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/rewrite-handler.adoc index 41c8d6f3d08..d1cfadc3464 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/rewrite-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/rewrite-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[rewrite-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/shutdown-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/shutdown-handler.adoc index f2eea737872..d6e497db431 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/shutdown-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/shutdown-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[shutdown-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/statistics-handler.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/statistics-handler.adoc index e4af9941430..b605a0656ef 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/extras/statistics-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/extras/statistics-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[statistics-handler]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/chapter.adoc index afe2a6861f7..19c3b9feb2e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[fastcgi]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/configuring-fastcgi.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/configuring-fastcgi.adoc index 7409d9b91e3..ec455d9a231 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/configuring-fastcgi.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/configuring-fastcgi.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-fastcgi]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/fastcgi-intro.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/fastcgi-intro.adoc index e84c3ca25dd..aae6eef6782 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/fastcgi-intro.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/fastcgi/fastcgi-intro.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[fastcgi-intro]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/chapter.adoc index 5c8b7460c2e..09ca1ed7e88 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http2]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-haproxy.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-haproxy.adoc index ffa0b6c1463..f12fcf8942e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-haproxy.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-haproxy.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http2-configuring-haproxy]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-http2.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-http2.adoc index ea676126d33..49db2c5c90e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-http2.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-http2.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http2-configuring]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-push.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-push.adoc index 24b27955274..b628792060a 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-push.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/configuring-push.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http2-configuring-push]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc index 9eaefadc53f..ebde323405d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http2-enabling]] @@ -27,11 +27,12 @@ A demo Jetty base that supports HTTP/1, HTTPS/1 and deployment from a webapps di $ JETTY_BASE=http2-demo $ mkdir $JETTY_BASE $ cd $JETTY_BASE -$ java -jar $JETTY_HOME/start.jar --add-to-start=http,https,deploy +$ java -jar $JETTY_HOME/start.jar --add-to-start=http,https,deploy,test-keystore .... The commands above create a `$JETTY_BASE` directory called `http2-demo`, and initializes the `http,` `https` and `deploy` modules (and their dependencies) to run a typical Jetty Server on port 8080 (for HTTP/1) and 8443 (for HTTPS/1). -Note that the HTTPS module downloads a demo keystore file with a self signed certificate, which needs to be replaced by a Certificate Authority issued certificate for real deployment. +Note that the `test-keystore` module downloads a demo keystore file with a self signed certificate, which needs to be replaced by a Certificate Authority issued certificate for real deployment. +A keystore can also be added by enabling and configuring the `ssl` module. To add HTTP/2 to this demo base, it is just a matter of enabling the `http2` module with the following command: diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/introduction.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/introduction.adoc index 6f3d7b17e9c..92fa37c7e8c 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/introduction.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/introduction.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http2-introduction]] @@ -26,11 +26,21 @@ The requirements for running HTTP/2 are JDK 8 or greater, and typically also ALP A server deployed over TLS (SSL) normally advertises the HTTP/2 protocol via the TLS extension Application Layer Protocol Negotiation link:#alpn[(ALPN)]. ____ -[IMPORTANT] +[NOTE] To use HTTP/2 in Jetty via a TLS connector you need to add the link:#alpn-starting[ALPN boot jar] in the boot classpath. This is done automatically when using the Jetty distribution's start.jar link:#startup-modules[module system], but must be configured directly otherwise. ____ +[[http2-security-update]] +==== Jetty HTTP/2 Security Update + +In mid-2019, there were a link:#security-reports[number of CVEs] were issued warning against vulnerable HTTP/2 implementations. These CVEs (CVE-2019-9511 thru CVE-2019-9518) generally centered around attackers manipulating and flooding HTTP/2 servers and creating a denial of service (DOS). These vulnerabilities were patched with Jetty 9.4.21. + +As a result of these CVEs, Jetty introduced a new, configurable denial of service (DOS) protection feature in Jetty 9.4.22. + +Jetty’s HTTP/2 implementation now features a new Rate Control parameter, `jetty.http2.rateControl.maxEventsPerSecond`, that defaults to 20 events per second, per connection for all pings, bad frames, settings frames, priority changes etc. + + [[http2-modules]] ==== Jetty HTTP/2 Sub Projects diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/index.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/index.adoc index 4f51b1936c4..20a8c1a9022 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/index.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/index.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - :doctitle: Eclipse Jetty: Distribution Guide :author: Jetty Developers :email: jetty-dev@eclipse.org diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/chapter.adoc index caaf3883408..bcd3f177a3d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jmx-chapter]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jconsole.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jconsole.adoc index cf923380e14..1216327fdac 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jconsole.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jconsole.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-jconsole]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jmx-annotations.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jmx-annotations.adoc index 7c19b124d63..d2e478d8dc5 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jmx-annotations.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/jetty-jmx-annotations.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-jmx-annotations]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/using-jmx.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/using-jmx.adoc index 3a6756935a9..df5a1727902 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/using-jmx.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jmx/using-jmx.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[using-jmx]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/chapter.adoc index 2f47039cd95..f6be3a1c138 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jndi]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-configuration.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-configuration.adoc index f62aa9713b9..3f943f8ed49 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-configuration.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-configuration.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jndi-configuration]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-datasources.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-datasources.adoc index 9b660052a36..69be0c99b44 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-datasources.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-datasources.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jndi-datasource-examples]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-embedded.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-embedded.adoc index e77490bab82..7e9315849bf 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-embedded.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/jndi-embedded.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jndi-embedded]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/quick-jndi-setup.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/quick-jndi-setup.adoc index dec37697215..4478008cbd8 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/quick-jndi-setup.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/quick-jndi-setup.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jndi-quick-setup]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/using-jndi.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/using-jndi.adoc index 7344090b589..bab9112aa4e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/using-jndi.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jndi/using-jndi.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[using-jetty-jndi]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/chapter.adoc index c9476bf21bd..4d5c4ad5a45 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-jsp]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc index 705a03ec1e8..f4647e6619b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jsp-support]] @@ -36,6 +36,12 @@ include::{SRCDIR}/jetty-home/src/main/resources/modules/jsp.mod[] Note that the availability of some JSP features may depend on which JSP container implementation you are using. Note also that it may not be possible to precompile your JSPs with one container and deploy to the other. +===== Logging + +The Apache Jasper logging system is bridged to the jetty logging system. +Thus, you can enable logging for jsps in the same way you have setup for your webapp. +For example, assuming you are using Jetty's default StdErr logger, you would enable DEBUG level logging for jsps by adding the system property `-Dorg.apache.jasper.LEVEL=DEBUG` to the command line. + ===== JSPs and Embedding If you have an embedded setup for your webapp and wish to use JSPs, you will need to ensure that a JSP engine is correctly initialized. @@ -79,89 +85,91 @@ If you wish to use a different compiler, you will need to configure the `compile [cols=",,,",options="header",] |======================================================================= |init param |Description |Default |`webdefault.xml` -|classpath |`Classpath used for jsp compilation. Only used if - org.apache.catalina.jsp_classpath context attribute is not - set, which it is in Jetty.` |- |– + +|checkInterval |If non-zero and `development` is `false`, background jsp recompilation is enabled. This value is the interval in seconds between background recompile checks. + |0 |– +|classpath |The classpath is dynamically generated if the context has a URL classloader. The `org.apache.catalina.jsp_classpath` +context attribute is used to add to the classpath, but if this is not set, this `classpath` configuration item is added to the classpath instead.` |- |– |classdebuginfo |Include debugging info in class file. |TRUE |– -|checkInterval |Interval in seconds between background recompile checks. -Only relevant if ` - development=false`. |0 |– +|compilerClassName |If not set, defaults to the Eclipse jdt compiler. |- |– -|development |`development=true`, recompilation checks occur on each -request. See also ` - modificationTestInterval`. |TRUE |– +|compiler |Used if the Eclipse jdt compiler cannot be found on the +classpath. It is the classname of a compiler that Ant should invoke. |– +|– + +|compilerTargetVM |Target vm to compile for. |1.8 |1.8 + +|compilerSourceVM |Sets source compliance level for the jdt compiler. +|1.8 |1.8 + +|development |If `true` recompilation checks occur at the frequency governed by `modificationTestInterval`. |TRUE |– |displaySourceFragment |Should a source fragment be included in exception messages |TRUE |– +|dumpSmap |Dump SMAP JSR45 info to a file. |FALSE |– + +|enablePooling |Determines whether tag handler pooling is enabled. |TRUE |– + +|engineOptionsClass |Allows specifying the Options class used to +configure Jasper. If not present, the default EmbeddedServletOptions +will be used. |- |– + |errorOnUseBeanInvalidClassAttribute |Should Jasper issue an error when the value of the class attribute in an useBean action is not a valid bean class |TRUE |– -|fork |Should Ant fork its Java compiles of JSP pages? |TRUE |FALSE +|fork |Only relevant if you use Ant to compile jsps: by default Jetty will use the Eclipse jdt compiler.|TRUE |- + +|genStrAsCharArray |Option for generating Strings as char arrays. |FALSE |– + +|ieClassId |The class-id value to be sent to Internet Explorer when +using tags. |clsid:8AD9C840-044E-11D1-B3E9-00805F499D93 |– + +|javaEncoding |Pass through the encoding to use for the compilation. +|UTF8 |– + +|jspIdleTimeout |The amount of time in seconds a JSP can be idle before +it is unloaded. A value of zero or less indicates never unload. |-1 |– |keepgenerated |Do you want to keep the generated Java files around? |TRUE |– -|trimSpaces |Should white spaces between directives or actions be -trimmed? |FALSE |– - -|enablePooling |Determines whether tag handler pooling is enabled. |TRUE -|– - -|engineOptionsClass |Allows specifying the Options class used to -configure Jasper. If not present, the default EmbeddedServletOptions -will be used. |– - |mappedFile |Support for mapped Files. Generates a servlet that has a print statement per line of the JSP file  |TRUE |– -|suppressSmap |Generation of SMAP info for JSR45 debugging. |FALSE |– - -|dumpSmap |Dump SMAP JSR45 info to a file. |FALSE |– - -|genStrAsCharArray |Option for generating Strings. |FALSE |– - -|ieClassId |The class-id value to be sent to Internet Explorer when -using tags. |clsid:8AD9C840-044E-11D1-B3E9-00805F499D93 |– - |maxLoadedJsps |The maximum number of JSPs that will be loaded for a web application. If more than this number of JSPs are loaded, the least recently used JSPs will be unloaded so that the number of JSPs loaded at any one time does not exceed this limit. A value of zero or less indicates no limit. |-1 |– -|jspIdleTimeout |The amount of time in seconds a JSP can be idle before -it is unloaded. A value of zero or less indicates never unload. |-1 |– - -|scratchDir |Directory where servlets are generated. See |– |– - -|compilerClassName |If not set, defaults to the Eclipse jdt compiler. |– - -|compiler |Used if the Eclipse jdt compiler cannot be found on the -classpath. It is the classname of a compiler that Ant should invoke. |– -|– - -|compilerTargetVM |Target vm to compile for. |1.7 |– - -|compilerSourceVM |Sets source compliance level for the jdt compiler. -|1.7 |– - -|javaEncoding |Pass through the encoding to use for the compilation. -|UTF8 |– - |modificationTestInterval |If `development=true`, interval between recompilation checks, triggered by a request. |4 |– -|xpoweredBy |Generate an X-Powered-By response header. |FALSE |FALSE +|quoteAttributeEL | When EL is used in an attribute value on a JSP page, should the rules for quoting of attributes described in JSP.1.6 be applied to the expression + |TRUE |- |recompileOnFail |If a JSP compilation fails should the modificationTestInterval be ignored and the next access trigger a re-compilation attempt? Used in development mode only and is disabled by default as compilation may be expensive and could lead to excessive -resource usage. |- |– +resource usage. |FALSE |– + +|scratchDir |Directory where servlets are generated. The default is the value of the context attribute `javax.servlet.context.tempdir`, or the system property `java.io.tmpdir` if the context attribute is not set. |– |– + +|strictQuoteEscaping |Should the quote escaping required by section JSP.1.6 of the JSP specification be applied to scriplet expression. + |TRUE|- + +|suppressSmap |Generation of SMAP info for JSR45 debugging. |FALSE |– + +|trimSpaces |Should template text that consists entirely of whitespace be removed from the output (true), replaced with a single space (single) or left unchanged (false)? Note that if a JSP page or tag file specifies a trimDirectiveWhitespaces value of true, that will take precedence over this configuration setting for that page/tag. +trimmed? |FALSE |– + +|xpoweredBy |Generate an X-Powered-By response header. |FALSE |FALSE + |======================================================================= [[configuring-jsp-for-jetty]] @@ -171,7 +179,7 @@ The JSP engine has many configuration parameters. Some parameters affect only precompilation, and some affect runtime recompilation checking. Parameters also differ among the various versions of the JSP engine. This page lists the configuration parameters, their meanings, and their default settings. -Set all parameters on the `org.apache.jasper.servlet.JspServlet` instance defined in the link:#webdefault-xml[`webdefault.xml`] file. +Set all parameters on the `org.eclipse.jetty.jsp.JettyJspServlet` instance defined in the link:#webdefault-xml[`webdefault.xml`] file. ____ [NOTE] @@ -225,18 +233,10 @@ You can use the entry in link:#webdefault-xml[{$jetty.home}/etc/webdefault.xml] ---- jsp - org.apache.jasper.servlet.JspServlet - - logVerbosityLevel - DEBUG - - - fork - >false - + org.eclipse.jetty.jsp.JettyJspServlet keepgenerated - >true + true ... diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/chapter.adoc index 689537a5137..6ceec15e366 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-logging]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-logging.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-logging.adoc index 13f10c44348..446b83b642e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-logging.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-logging.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-jetty-logging]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-request-logs.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-request-logs.adoc index bee4f26d0e4..cb6b645d83b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-request-logs.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-jetty-request-logs.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-jetty-request-logs]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-logging-modules.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-logging-modules.adoc index 099e9aa972f..8063feea260 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-logging-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/configuring-logging-modules.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-logging-modules]] @@ -479,7 +479,7 @@ As an example, here is the output from Logback before using the `console-capture .... [my-base]$ java -jar ../start.jar 419 [main] INFO org.eclipse.jetty.util.log - Logging initialized @508ms to org.eclipse.jetty.util.log.Slf4jLog -540 [main] INFO org.eclipse.jetty.server.Server - jetty-9.4.0-SNAPSHOT +540 [main] INFO org.eclipse.jetty.server.Server - jetty-{VERSION} 575 [main] INFO o.e.jetty.server.AbstractConnector - Started ServerConnector@3c0ecd4b{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 575 [main] INFO org.eclipse.jetty.server.Server - Started @668ms .... diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/default-logging-with-stderrlog.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/default-logging-with-stderrlog.adoc index ef98aa966ad..8250d05a646 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/default-logging-with-stderrlog.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/default-logging-with-stderrlog.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[default-logging-with-stderrlog]] @@ -128,7 +128,7 @@ There are a number of properties that can be defined in the configuration that w [source, screen, subs="{sub-order}"] .... 2016-10-21 15:31:01.248:INFO::main: Logging initialized @332ms to org.eclipse.jetty.util.log.StdErrLog -2016-10-21 15:31:01.370:INFO:oejs.Server:main: jetty-9.4.0-SNAPSHOT +2016-10-21 15:31:01.370:INFO:oejs.Server:main: jetty-{VERSION} 2016-10-21 15:31:01.400:INFO:oejs.AbstractConnector:main: Started ServerConnector@2c330fbc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 2016-10-21 15:31:01.400:INFO:oejs.Server:main: Started @485ms .... @@ -138,7 +138,7 @@ There are a number of properties that can be defined in the configuration that w [source, screen, subs="{sub-order}"] .... 2016-10-21 15:31:35.020:INFO::main: Logging initialized @340ms to org.eclipse.jetty.util.log.StdErrLog -2016-10-21 15:31:35.144:INFO:org.eclipse.jetty.server.Server:main: jetty-9.4.0-SNAPSHOT +2016-10-21 15:31:35.144:INFO:org.eclipse.jetty.server.Server:main: jetty-{VERSION} 2016-10-21 15:31:35.174:INFO:org.eclipse.jetty.server.AbstractConnector:main: Started ServerConnector@edf4efb{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 2016-10-21 15:31:35.175:INFO:org.eclipse.jetty.server.Server:main: Started @495ms .... diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/dump-tool.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/dump-tool.adoc index adc31d3a6e4..e2de8e785ad 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/dump-tool.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/dump-tool.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-dump-tool]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-apache-log4j.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-apache-log4j.adoc index 391e9728e2c..fe8d05ef32b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-apache-log4j.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-apache-log4j.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // === Example: Logging with Apache Log4j diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging-native.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging-native.adoc index c59be6b6086..86e7b07b561 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging-native.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging-native.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // === Example: Logging with Java's java.util.logging via JavaUtilLog diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging.adoc index bf23ce9456c..9f4b87ca701 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-java-util-logging.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // === Example: Logging with Java's java.util.logging via Slf4j diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-centralized-logging.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-centralized-logging.adoc index 648fe58c827..70ef0d7ea16 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-centralized-logging.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-centralized-logging.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[example-logging-logback-centralized]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-sifting.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-sifting.adoc index 4f58b0adf7a..9ebcaddaed1 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-sifting.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback-sifting.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[example-logging-logback-sifting]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback.adoc index 51e909cbc38..4326e635976 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-logback.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // === Example: Logging with Logback diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-slf4j-multiple-loggers.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-slf4j-multiple-loggers.adoc index 66bf99d6f6b..3700b2df5ae 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-slf4j-multiple-loggers.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/logging/example-slf4j-multiple-loggers.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[example-slf4j-multiple-loggers]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/runner/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/runner/chapter.adoc index b6a857ca7f8..946b526331b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/runner/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/runner/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[runner]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/runner/jetty-runner.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/runner/jetty-runner.adoc index 26bcd73d9a6..e0f36400658 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/runner/jetty-runner.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/runner/jetty-runner.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-runner]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/authentication.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/authentication.adoc index 3e7ab4917ef..b06cfefc7e5 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/authentication.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/authentication.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-security-authentication]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/chapter.adoc index 1c28d1535ce..8f9cdcd34db 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-security]] @@ -26,3 +26,4 @@ include::secure-passwords.adoc[] include::setting-port80-access-for-non-root-user.adoc[] include::jaas-support.adoc[] include::spnego-support.adoc[] +include::openid-support.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/configuring-form-size.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/configuring-form-size.adoc index 066aa482385..8d9b0312a16 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/configuring-form-size.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/configuring-form-size.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-form-size]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/jaas-support.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/jaas-support.adoc index 37f8f7f95ca..8fd11483f71 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/jaas-support.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/jaas-support.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jaas-support]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/jetty-home-and-jetty-base.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/jetty-home-and-jetty-base.adoc index 12ec9298052..35becc06d76 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/jetty-home-and-jetty-base.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/jetty-home-and-jetty-base.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-home-and-jetty-base]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/openid-support.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/openid-support.adoc new file mode 100644 index 00000000000..be5133210a3 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/openid-support.adoc @@ -0,0 +1,139 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[openid-support]] +=== OpenID Support + +==== External Setup + +===== Registering an App with OpenID Provider +You must register the app with an OpenID Provider such as link:https://developers.google.com/identity/protocols/OpenIDConnect#authenticatingtheuser[Google] or link:https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf[Amazon.] +This will give you a Client ID and Client Secret. +Once set up you must also register all the possible URI's for your webapp with the path `/j_security_check` so that the OpenId Provider will allow redirection back to the webapp. + +These may look like + + * `http://localhost:8080/openid-webapp/j_security_check` + + * `https://example.com/j_security_check` + +==== Distribution Configuration + +===== OpenID Provider Configuration +To enable OpenID support, you first need to activate the `openid` module in your implementation. + +[source, screen, subs="{sub-order}"] +---- +java -jar {JETTY_HOME}/start.jar --add-to-start=openid +---- + +To configure OpenID Authentication with Jetty you will need to specify the OpenID Provider's issuer identifier (case sensitive URL using the `https` scheme) and the OAuth 2.0 Client ID and Client Secret. +If the OpenID Provider does not allow metadata discovery you will also need to specify the token endpoint and authorization endpoint of the OpenID Provider. +These can be set as properties in the `start.ini` or `start.d/openid.ini` files. + +===== WebApp Specific Configuration in web.xml + +The `web.xml` file needs some specific configuration to use OpenID. +There must be a `login-config` element with an `auth-method` value of `OPENID`, and a `realm-name` value of the exact URL string used to set the OpenID Provider. + +To set the error page, an init param is set at `"org.eclipse.jetty.security.openid.error_page"`, its value should be a path relative to the webapp where authentication errors should be redirected. + +Example: + +[source, xml, subs="{sub-order}"] +---- + + OPENID + https://accounts.google.com + + + org.eclipse.jetty.security.openid.error_page + /error + +---- + +==== Embedded Configuration + +===== Define the `OpenIdConfiguration` for a specific OpenID Provider. + +If the OpenID Provider allows metadata discovery then you can use. + +[source, java, subs="{sub-order}"] +---- +OpenIdConfiguration openIdConfig = new OpenIdConfiguration(ISSUER, CLIENT_ID, CLIENT_SECRET); +---- + +Otherwise you can manually enter the necessary information: + +[source, java, subs="{sub-order}"] +---- +OpenIdConfiguration openIdConfig = new OpenIdConfiguration(ISSUER, TOKEN_ENDPOINT, AUTH_ENDPOINT, CLIENT_ID, CLIENT_SECRET); +---- + +===== Configuring an `OpenIdLoginService` +[source, java, subs="{sub-order}"] +---- +LoginService loginService = new OpenIdLoginService(openIdConfig); +securityHandler.setLoginService(loginService); +---- + +===== Configuring an `OpenIdAuthenticator` with `OpenIdConfiguration` and Error Page Redirect +[source, java, subs="{sub-order}"] +---- +Authenticator authenticator = new OpenIdAuthenticator(openIdConfig, "/error"); +securityHandler.setAuthenticator(authenticator); +servletContextHandler.setSecurityHandler(securityHandler); +---- + +===== Usage + +====== Claims and Access Token +Claims about the user can be found using attributes on the session attribute `"org.eclipse.jetty.security.openid.claims"`, and the full response containing the OAuth 2.0 Access Token can be found with the session attribute `"org.eclipse.jetty.security.openid.response"`. + +Example: +[source, java, subs="{sub-order}"] +---- +Map claims = (Map)request.getSession().getAttribute("org.eclipse.jetty.security.openid.claims"); +String userId = claims.get("sub"); + +Map response = (Map)request.getSession().getAttribute("org.eclipse.jetty.security.openid.response"); +String accessToken = response.get("access_token"); +---- + +==== Scopes +The OpenID scope is always used but additional scopes can be requested which can give you additional resources or privileges. +For the Google OpenID Provider it can be useful to request the scopes `profile` and `email` which will give you additional user claims. + +Additional scopes can be requested through the `start.ini` or `start.d/openid.ini` files, or with `OpenIdConfiguration.addScopes(...);` in embedded code. + +==== Roles + +If security roles are required they can be configured through a wrapped `LoginService` which is deferred to for role information by the `OpenIdLoginService`. + +This can be configured in XML through `etc/openid-baseloginservice.xml` in the Distribution, or in embedded code using the constructor for the `OpenIdLoginService`. + +[source, java, subs="{sub-order}"] +---- +LoginService wrappedLoginService = ...; // Optional LoginService for Roles +LoginService loginService = new OpenIdLoginService(openIdConfig, wrappedLoginService); +---- + +When using authorization roles, the setting `authenticateNewUsers` becomes significant. +If set to `true` users not found by the wrapped `LoginService` will still be authenticated but will have no roles. +If set to `false` those users will be not be allowed to authenticate and are redirected to the error page. +This setting is configured through the property `jetty.openid.authenticateNewUsers` in the `start.ini` or `start.d/openid.ini` file, or with `OpenIdLoginService.setAuthenticateNewUsers(...);` in embedded code. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/secure-passwords.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/secure-passwords.adoc index 8bbf9b85f90..f0754605e9b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/secure-passwords.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/secure-passwords.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-security-secure-passwords]] @@ -73,7 +73,7 @@ ____ [source, screen, subs="{sub-order}"] .... -$ java -cp ../lib/jetty-util-9.4.7.v20170914.jar org.eclipse.jetty.util.security.Password username username:realm:password +$ java -cp ../lib/jetty-util-{VERSION}.jar org.eclipse.jetty.util.security.Password username username:realm:password 2017-12-13 11:34:33.263:INFO::main: Logging initialized @97ms to org.eclipse.jetty.util.log.StdErrLog username:realm:password OBF:1w281yf41v1x1z7e1xmi1v1p1tvv1v901c3j1x8k1ugo1ri71uh21x8a1c3j1v9m1tv71v2p1xms1z7o1v2h1yf21w1a diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/serving-aliased-files.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/serving-aliased-files.adoc index 290cad1e31d..4d0f98d7fb2 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/serving-aliased-files.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/serving-aliased-files.adoc @@ -1,26 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[serving-aliased-files]] === Aliased Files and Symbolic links -Web applications will often server static content from the file system provided by the operating system running underneath the JVM. -However because file systems often implement multiple aliased names for the same file, then security constraints and other servlet URI space mappings my inadvertently be bypassed by aliases. +Web applications will often serve static content from the file system provided by the operating system running underneath the JVM. +However, because file systems often implement multiple aliased names for the same file, then security constraints and other servlet URI space mappings may inadvertently be bypassed by aliases. A key example of this is case insensitivity and 8.3 filenames implemented by the Windows file system. If a file within a web application called `/mysecretfile.txt` is protected by a security constraint on the URI `/mysecretfile.txt`, then a request to `/MySecretFile.TXT` will not match the URI constraint because URIs are case sensitive, but the Windows file system will report that a file does exist at that name and it will be served despite the security constraint. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/setting-port80-access-for-non-root-user.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/setting-port80-access-for-non-root-user.adoc index 6f64faf2748..20c761836eb 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/setting-port80-access-for-non-root-user.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/setting-port80-access-for-non-root-user.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[setting-port80-access]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/security/spnego-support.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/security/spnego-support.adoc index 3335bdd459c..3e77cc81733 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/security/spnego-support.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/security/spnego-support.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[spnego-support]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/chapter.adoc index 875c8747317..e7597106d60 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-management]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-gcloud-datastore.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-gcloud-datastore.adoc index e67d55ea952..c5061cf191a 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-gcloud-datastore.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-gcloud-datastore.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-clustering-gcloud-datastore]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-infinispan.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-infinispan.adoc index 3e9fe70d94f..6489ee0b5a4 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-infinispan.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-infinispan.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-clustering-infinispan]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-jdbc.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-jdbc.adoc index f154c2b7434..4e5b2a9c4a1 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-jdbc.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-jdbc.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-clustering-jdbc]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-mongodb.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-mongodb.adoc index 9f00ef6a57a..a1d6f1a5a07 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-mongodb.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/session-clustering-mongodb.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-clustering-mongodb]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/setting-session-characteristics.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/setting-session-characteristics.adoc index 60a112e87d8..0545b477711 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/setting-session-characteristics.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/setting-session-characteristics.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[setting-session-characteristics]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/using-persistent-sessions.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/using-persistent-sessions.adoc index d68f34a2cb4..760a941e095 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/using-persistent-sessions.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/legacy/using-persistent-sessions.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[using-persistent-sessions]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-file-system.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-file-system.adoc index a824a8aa866..1c2c65a3208 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-file-system.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-file-system.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-file-system]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-gcloud.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-gcloud.adoc index 0a349212ff9..4009c1a9ace 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-gcloud.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-gcloud.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-gcloud]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-hazelcast.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-hazelcast.adoc index ba8bfd985e5..4e3aeec1b7c 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-hazelcast.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-hazelcast.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-hazelcast]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-housekeeper.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-housekeeper.adoc index 398dd99cbac..1f421ff7e7d 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-housekeeper.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-housekeeper.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-configuration-housekeeper]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-infinispan.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-infinispan.adoc index 18e617b1849..3ba1232b1d2 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-infinispan.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-infinispan.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-infinispan]] @@ -206,9 +206,9 @@ java -jar ../start.jar --add-to-start=infinispan-embedded-query There are no configuration properties associated with this module. -==== Converting session format for jetty-9.4.13 +==== Converting Session Format for Jetty-9.4.13 -From jetty-9.4.13 onwards, we have changed the format of the serialized session when using a remote cache (ie using hotrod). +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. @@ -222,7 +222,7 @@ How to use the converter: [source, screen, subs="{sub-order}"] ---- -java -cp jetty-servlet-api-4.0.2.jar:jetty-util-9.4.13.jar:jetty-server-9.4.13.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-9.4.13.jar:[other classpath] org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter +java -cp jetty-servlet-api-4.0.2.jar:jetty-util-{VERSION}.jar:jetty-server-{VERSION}.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-{VERSION}.jar:[other classpath] org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter Usage: InfinispanSessionLegacyConverter [-Dhost=127.0.0.1] [-Dverbose=true|false] [check] ---- @@ -242,7 +242,7 @@ The following command will attempt to convert all sessions in the cached named ` [source, screen, subs="{sub-order}"] ---- -java -cp jetty-servlet-api-4.0.2.jar:jetty-util-9.4.13.jar:jetty-server-9.4.13.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-9.4.13.jar:/my/custom/classes org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter -Dhost=myhost my-remote-cache +java -cp jetty-servlet-api-4.0.2.jar:jetty-util-{VERSION}.jar:jetty-server-{VERSION}.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-{VERSION}.jar:/my/custom/classes org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter -Dhost=myhost my-remote-cache ---- If the converter fails to convert a session, an error message and stacktrace will be printed and the conversion will abort. The failed session should be untouched, however _it is prudent to take a backup of your cache before attempting the conversion_. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-jdbc.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-jdbc.adoc index 7fd85eb66b3..a93320d3411 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-jdbc.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-jdbc.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-jdbc]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memcachedsessiondatastore.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memcachedsessiondatastore.adoc index e03141b40b4..b86ef194907 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memcachedsessiondatastore.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memcachedsessiondatastore.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-configuration-memcachedsessiondatastore]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memory.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memory.adoc index 0c854251e81..4804a16d0ed 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memory.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-memory.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-memory]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-mongodb.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-mongodb.adoc index 418328c0760..f0b7b4da522 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-mongodb.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-mongodb.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[configuring-sessions-mongo]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-sessioncache.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-sessioncache.adoc index d06c0f74f28..afca111bdfd 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-sessioncache.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-configuration-sessioncache.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[session-configuration-sessioncache]] @@ -34,6 +34,7 @@ Once the `session-cache-hash` module has been enabled, you can view a list of al #jetty.session.saveOnInactiveEvict=false #jetty.session.saveOnCreate=false #jetty.session.removeUnloadableSessions=false +#jetty.session.flushOnResponseCommit=false ---- jetty.session.evictionPolicy:: @@ -63,6 +64,12 @@ jetty.session.removeUnloadableSessions:: Boolean, default `false`. Controls whether a session that cannot be restored - for example because it is corrupted - from the `SessionDataStore` is deleted by the `SessionDataStore`. +jetty.session.flushOnResponseCommit:: +Boolean, default `false`. +If true, if a session is "dirty" - ie its attributes have changed - it will be written to the backing store as the response is about to commit. +This ensures that all subsequent requests whether to the same or different node will see the updated session data. +If false, a dirty session will only be written to the backing store when the last simultaneous request for it leaves the session. + For more general information on the uses of these configuration properties, see link:#sessions-details[Session Components]. @@ -72,4 +79,21 @@ The `NullSessionCache` is a trivial implementation of the `SessionCache` that do You may need to use it if your clustering setup does not have a sticky load balancer, or if you want absolutely minimal support for sessions. If you use this in conjunction with the `NullSessionDataStore`, then sessions will neither be retained in memory nor persisted. -To enable the `NullSessionCache`, enable the `sesssion-cache-null` link:#startup-modules[module]. +To enable the `NullSessionCache`, enable the `sesssion-cache-null` link:#startup-modules[module]. +Configuration options are: + +jetty.session.saveOnCreate:: +Boolean, default `false`. +Controls whether a session that is newly created will be immediately saved to the `SessionDataStore` or lazily saved as the last request for the session exits. + +jetty.session.removeUnloadableSessions:: +Boolean, default `false`. +Controls whether a session that cannot be restored - for example because it is corrupted - from the `SessionDataStore` is deleted by the `SessionDataStore`. + +jetty.session.flushOnResponseCommit:: +Boolean, default `false`. +If true, if a session is "dirty" - ie its attributes have changed - it will be written to the backing store as the response is about to commit. +This ensures that all subsequent requests whether to the same or different node will see the updated session data. +If false, a dirty session will only be written to the backing store when the last simultaneous request for it leaves the session. + +For more general information on the uses of these configuration properties, see link:#sessions-details[Session Components]. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-hierarchy.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-hierarchy.adoc index 015c15e2b91..7d6f95f1a5a 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-hierarchy.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/session-hierarchy.adoc @@ -1,39 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-sessions-architecture]] === Session Architecture -// TODO: Remove in Jetty 9.5/10 - This paragraph is dated and only really useful for upgrading into 9.4 from prior versions. -==== Changes in Session Architecture -The architecture of Session Management Jetty changed significantly in Jetty 9.4. -These changes have resulted in Sessions not only being easier to configure but making them much more pluggable for various technologies. - -In previous versions of Jetty, users were required to configure a separate `SessionIdManager` for each kind of session clustering technology being implemented (JDBC, MongoDB..etc.). -In Jetty 9.4, there is now a single `SessionIdManager` implementation which works across all types of session clustering technologies. -Likewise, prior to Jetty 9.4 there were several different instances of the `SessionManager` class. -Instead of a single `SessionManager` though, it has been done away with entirely, with most of it's functionality moved to the `SesssionHandler` class. -Additionally, Jetty 9.4 introduced the concepts of a `SessionCache` and an associated `SessionDataStore` (both explained below). - -Finally, Session scavenging has been re-worked. -Where previously each `SessionManager` instance would periodically scan the in-memory (or clustered) sessions for expired sessions, there is now a single generic scavenger thread which instructs the `SessionHandler` to clean up expired sessions. -Session expiration has been changed to use a much more efficient timer-based mechanism that avoids constant iteration over all current sessions in memory by the scavenger. - ==== Session Architecture Hierarchy Each Jetty instance has a singular `SessionIdManager` to handle all session requests, regardless of clustering technology. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-details.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-details.adoc index 7e89e729039..cc586d95dbc 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-details.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-details.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[sessions-details]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-usecases.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-usecases.adoc index 9e6c43e8047..8192a56b066 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-usecases.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/sessions/sessions-usecases.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[sessions-usecases]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/chapter.adoc index 50a635f1544..3b93af019f9 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/custom-modules.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/custom-modules.adoc index 8664c8dcc92..5792be01571 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/custom-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/custom-modules.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[custom-modules]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base-listconfig.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base-listconfig.adoc index 1ed43bfbfd1..e0773c2afad 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base-listconfig.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base-listconfig.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [source, screen, subs="{sub-order}"] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base.adoc index d22e0bf36ff..e67535e09c4 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-empty-base.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [source, screen, subs="{sub-order}"] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy-listconfig.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy-listconfig.adoc index e9e40f333b4..039bfe5cf9e 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy-listconfig.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy-listconfig.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [source, screen, subs="{sub-order}"] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy.adoc index 7594413b7c1..c0af1033a75 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-http-webapp-deploy.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [source, screen, subs="{sub-order}"] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-logging-modules.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-logging-modules.adoc index ca175842225..740ea932992 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-logging-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-logging-modules.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [source, screen, subs="{sub-order}"] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-modules.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-modules.adoc index 29a901381f3..5030d689441 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/screen-list-modules.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [source, screen, subs="{sub-order}"] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-jar.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-jar.adoc index 2dbd3be34e3..9ca46675cc1 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-jar.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-jar.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[start-jar]] @@ -262,3 +262,16 @@ You might need to escape the slash "\|" to use this on some environments. maven.repo.uri=[url]:: The url to use to download Maven dependencies. Default is https://repo1.maven.org/maven2/. + +==== Shaded Start.jar + +If you have a need for a shaded version of `start.jar` (such as for Gradle), you can achieve this via a Maven dependency. +[source, xml, subs="{sub-order}"] +.... + + org.eclipse.jetty + jetty-start + {VERSION} + shaded + +.... diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-matrix.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-matrix.adoc index 013d80a8b64..3616d2cb416 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-matrix.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/start-matrix.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[advanced-start-matrix]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-base-vs-home.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-base-vs-home.adoc index 8f91ad557f3..3795f3d049b 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-base-vs-home.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-base-vs-home.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-base-and-home]] @@ -145,7 +145,7 @@ Properties: jetty.secure.port = 8443 jetty.truststore = etc/keystore jetty.truststore.password = OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4 - org.eclipse.jetty.websocket.jsr356 = false + org.eclipse.jetty.websocket.javax = false threads.max = 200 threads.min = 10 threads.timeout = 60000 @@ -189,8 +189,8 @@ Note: order presented here is how they would appear on the classpath. 32: 1.2 | ${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar 33: {VERSION} | ${jetty.home}/lib/jetty-deploy-{VERSION}.jar 34: 1.0 | ${jetty.home}/lib/websocket/javax.websocket-api-1.0.jar -35: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-client-{VERSION}.jar -36: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-server-{VERSION}.jar +35: {VERSION} | ${jetty.home}/lib/websocket/websocket-javax-client-{VERSION}.jar +36: {VERSION} | ${jetty.home}/lib/websocket/websocket-javax-server-{VERSION}.jar 37: {VERSION} | ${jetty.home}/lib/websocket/websocket-api-{VERSION}.jar 38: {VERSION} | ${jetty.home}/lib/websocket/websocket-client-{VERSION}.jar 39: {VERSION} | ${jetty.home}/lib/websocket/websocket-common-{VERSION}.jar @@ -235,7 +235,7 @@ etc/demo-rewrite-rules.xml # Websocket chat examples needs websocket enabled # Don't start for all contexts (set to true in test.xml context) -org.eclipse.jetty.websocket.jsr356=false +org.eclipse.jetty.websocket.javax=false --module=websocket # Create and configure the test realm diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-classpath.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-classpath.adoc index 5bfa599f6fa..67e7a3594f3 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-classpath.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-classpath.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-classpath]] @@ -98,8 +98,8 @@ Note: order presented here is how they would appear on the classpath. 32: 1.2 | ${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar 33: {VERSION} | ${jetty.home}/lib/jetty-deploy-{VERSION}.jar 34: 1.0 | ${jetty.home}/lib/websocket/javax.websocket-api-1.0.jar -35: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-client-{VERSION}.jar -36: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-server-{VERSION}.jar +35: {VERSION} | ${jetty.home}/lib/websocket/websocket-javax-client-{VERSION}.jar +36: {VERSION} | ${jetty.home}/lib/websocket/websocket-javax-server-{VERSION}.jar 37: {VERSION} | ${jetty.home}/lib/websocket/websocket-api-{VERSION}.jar 38: {VERSION} | ${jetty.home}/lib/websocket/websocket-client-{VERSION}.jar 39: {VERSION} | ${jetty.home}/lib/websocket/websocket-common-{VERSION}.jar diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-jpms.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-jpms.adoc index 25d5c379f4b..13acfcb6504 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-jpms.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-jpms.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-jpms]] @@ -69,11 +69,11 @@ This will give an output looking something like this (broken in sections for cla [source, screen, subs="{sub-order}"] .... /opt/openjdk-11+28/bin/java ---module-path /opt/jetty/lib/jetty-servlet-api-4.0.2.jar:/opt/jetty/lib/jetty-http-9.4.13-SNAPSHOT.jar:... +--module-path /opt/jetty/lib/jetty-servlet-api-4.0.2.jar:/opt/jetty/lib/jetty-http-{VERSION}.jar:... --module org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration /opt/jetty/etc/jetty-threadpool.xml /opt/jetty/etc/jetty.xml ... .... -The `--module-path` option specifies the list of Jetty jars. +The `--module-path` option specifies the list of Jetty jars. This list depends on the Jetty modules that have been enabled via the link:#startup-modules[`--add-to-start`] command. The `--module` option tells the JVM to run main class `XmlConfiguration` from the `org.eclipse.jetty.xml` module, with the given XML files as program arguments. diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-modules.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-modules.adoc index 014546eea6d..2e62d3158ea 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-modules.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-modules]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-overview.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-overview.adoc index d6835131772..f517464af03 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-overview.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-overview.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-overview]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-troubleshooting.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-troubleshooting.adoc index 58f8027c2a5..137dd08d351 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-troubleshooting.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-troubleshooting.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-troubleshooting]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-unix-service.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-unix-service.adoc index c8b381b9eff..68ee46826be 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-unix-service.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-unix-service.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-unix-service]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-windows-service.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-windows-service.adoc index 703cbd3df31..4f7c224dce9 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-windows-service.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-windows-service.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-windows-service]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-xml-config.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-xml-config.adoc index 1f83416b3cc..efdcfe6baf1 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-xml-config.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/startup/startup-xml-config.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[startup-xml-config]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/chapter.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/chapter.adoc index be0a01ae936..cf45f4bd1eb 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[optimizing]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/garbage-collection.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/garbage-collection.adoc index d774428c9b3..e04325ac987 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/garbage-collection.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/garbage-collection.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[garbage-collection]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/high-load.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/high-load.adoc index 145ff5e6bad..92b8eec52d4 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/high-load.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/high-load.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[high-load]] diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/limit-load.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/limit-load.adoc index e93f7156844..7bd189d8328 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/limit-load.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/tuning/limit-load.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[limit-load]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/client/client-concepts.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/client/client-concepts.adoc index 27b18db4813..bf7dae893b1 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/client/client-concepts.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/client/client-concepts.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[client-concepts]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/client/client.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/client/client.adoc index 4357eed3b27..4673ae1e6b5 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/client/client.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/client/client.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[client]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/client/http/client-http.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/client/http/client-http.adoc index 3ce4b431653..c1f403bd05e 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/client/http/client-http.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/client/http/client-http.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[client-http]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/index.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/index.adoc index 5840f892e72..1dfc4bdaa93 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/index.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/index.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - :doctitle: Eclipse Jetty: Embedded Guide :author: Jetty Developers :email: jetty-dev@eclipse.org diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/io-arch.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/io-arch.adoc index 8fd79a91d3c..e0106e8059b 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/io-arch.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/io-arch.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [appendix] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/chapter.adoc index b006e7a5877..44e0295e3d7 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[ant-and-jetty]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/jetty-ant.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/jetty-ant.adoc index 01b0b77df54..b9bd86e02ff 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/jetty-ant.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/ant/jetty-ant.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-ant]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/1xx-responses.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/1xx-responses.adoc index a4aaf9c4974..e558ab780d6 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/1xx-responses.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/1xx-responses.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-1xx-responses]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/basic-architecture.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/basic-architecture.adoc index af5ed4f42d5..4965ccbdd19 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/basic-architecture.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/basic-architecture.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[basic-architecture]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/chapter.adoc index ace8703b3fb..4c08ba13d69 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[architecture]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/jetty-classloading.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/jetty-classloading.adoc index 0f351429183..0dd5727347c 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/jetty-classloading.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/jetty-classloading.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-classloading]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/server-side-architecture.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/server-side-architecture.adoc index 62df993188f..b22d87e3850 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/server-side-architecture.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/architecture/server-side-architecture.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[creating-custom-protocol]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/chapter.adoc index 1c53cdfcaf3..fe028abc9b0 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-api.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-api.adoc index 8792a6ccdcf..76a2208e05b 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-api.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-api.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client-api]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-authentication.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-authentication.adoc index 7f23e976c20..8b7515f315f 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-authentication.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-authentication.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client-authentication]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-cookie.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-cookie.adoc index 4e3e113ac46..dbe3193b5c8 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-cookie.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-cookie.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client-cookie]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-intro.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-intro.adoc index 429f0444763..3a2f70d9c1b 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-intro.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-intro.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client-intro]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-proxy.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-proxy.adoc index f5f0659510e..1d5acd92475 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-proxy.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-proxy.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client-proxy]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-transport.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-transport.adoc index ae566236c33..21870cc9460 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-transport.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/clients/http/http-client-transport.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[http-client-transport]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/chapter.adoc deleted file mode 100644 index 0dca58b6ce6..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/chapter.adoc +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -[[continuations]] -== Continuations - -include::continuations-intro.adoc[] -include::continuations-using.adoc[] -include::continuations-patterns.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-intro.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-intro.adoc deleted file mode 100644 index 277977bde6a..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-intro.adoc +++ /dev/null @@ -1,129 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -[[continuations-intro]] -=== Introduction - -Continuations are a mechanism to implement Asynchronous servlets similar to asynchronous features in Servlet 3.0, but provides a simpler and portable interface. - -==== Why Asynchronous Servlets ? - -===== Not Asynchronous IO - -The concept of Asynchronous Servlets is often confused with Asynchronous IO or the use of NIO. -However, Asynchronous Servlets are not primarily motivated by asynchronous IO, since: - -* HTTP Requests are mostly small and arrive in a single packet. Servlets rarely block on requests. - -* Many responses are small and fit within the server buffers, so servlets often do not block writing responses. - -* Even if we could expose asynchronous IO in a servlet, it is a hard paradigm to program. For example what would an application do if it read 2 bytes of a 3 byte UTF-8 character? -It would have to buffer and wait for more bytes. -This is best done by the container rather than the application. - -===== Asynchronous Waiting - -The main use-case for asynchronous servlets is waiting for non-IO events or resources. -Many web applications need to wait at some stage during the processing of a HTTP request, for example: - -* Waiting for a resource to be available before processing the request (e.g., thread, JDBC Connection). - -* Waiting for an application event in an AJAX Comet application (e.g., chat message, price change). - -* Waiting for a response from a remote service (e.g., RESTful or SOAP call to a web service). - -The servlet API (pre 2.5) supports only a synchronous call style, so that any waiting that a servlet needs to do must be with blocking. -Unfortunately this means that the thread allocated to the request must be held during that wait along with all its resources: kernel thread, stack memory and often pooled buffers, character converters, EE authentication context, etc. -It is wasteful of system resources to hold these resources while waiting. Significantly better scalability and quality of service can be achieved if waiting is done asynchronously. - -==== Asynchronous Servlet Examples - -===== AJAX Comet Server Push - -Web 2.0 applications can use the http://en.wikipedia.org/wiki/Comet_(programming)[comet] technique (aka AJAX Push, Server Push, Long Polling) to dynamically update a web page without refreshing the entire page. - -Consider a stock portfolio web application. Each browser will send a long poll request to the server asking for any of the user's stock prices that have changed. The server will receive the long poll requests from all its clients, but will not immediately respond. -Instead the server waits until a stock price changes, at which time it will send a response to each of the clients with that stock in their portfolio. -The clients that receive the long poll response will immediately send another long poll request so they may obtain future price changes. - -Thus the server will typically hold a long poll request for every connected user, so if the servlet is not asynchronous, there would need more than 1000 threads available to handle 1000 simultaneous users. -1000 threads can consume over 256MB of memory; that would be better used for the application rather than idly waiting for a price to change. - -If the servlet is asynchronous, then the number of threads needed is governed by the time to generate each response and the frequency of price changes. -If every user receives a price every 10 seconds and the response takes 10ms to generate, then 1000 users can be serviced with just 1 thread, and the 256MB of stack be freed for other purposes. - -For more on comet see the http://cometd.org/[cometd] project that works asynchronously with Jetty. - -===== Asynchronous RESTful Web Service - -Consider a web application that accesses a remote web service (e.g., SOAP service or RESTful service). -Typically a remote web service can take hundreds of milliseconds to produce a response -- eBay's RESTful web service frequently takes 350ms to respond with a list of auctions matching a given keyword -- while only a few 10s of milliseconds of CPU time are needed to locally process a request and generate a response. - -To handle 1000 requests per second, which each perform a 200ms web service call, a webapp would needs 1000*(200+20)/1000 = 220 threads and 110MB of stack memory. -It would also be vulnerable to thread starvation if bursts occurred or the web service became slower. If handled asynchronously, the web application would not need to hold a thread while waiting for web service response. -Even if the asynchronous mechanism cost 10ms (which it doesn't), then this webapp would need 1000*(20+10)/1000 = 30 threads and 15MB of stack memory. -This is a 86% reduction in the resources required and 95MB more memory would be available for the application. -Furthermore, if multiple web services request are required, the asynchronous approach allows these to be made in parallel rather than serially, without allocating additional threads. - -For an example of Jetty's solution, see the https://webtide.com/async-rest-jetty-9/[Asynchronous REST example] - -===== Quality of Service (e.g., JDBC Connection Pool) - -Consider a web application handling on average 400 requests per second, with each request interacting with the database for 50ms. -To handle this load, 400*50/1000 = 20 JDBC connections are need on average. -However, requests do not come at an even rate and there are often bursts and pauses. -To protect a database from bursts, often a JDBC connection pool is applied to limit the simultaneous requests made on the database. -So for this application, it would be reasonable to apply a JDBC pool of 30 connections, to provide for a 50% margin. - -If momentarily the request rate doubled, then the 30 connections would only be able to handle 600 requests per second, and 200 requests per second would join those waiting on the JDBC Connection pool. -Then if the servlet container had a thread pool with 200 threads, that would be entirely consumed by threads waiting for JDBC connections in 1 second of this request rate. -After 1s, the web application would be unable to process any requests at all because no threads would be available. -Even requests that do not use the database would be blocked due to thread starvation. -To double the thread pool would require an additional 100MB of stack memory and would only give the application another 1s of grace under load! - -This thread starvation situation can also occur if the database runs slowly or is momentarily unavailable. -Thread starvation is a very frequently reported problem, and causes the entire web service to lock up and become unresponsive. -If the web container was able to suspend the requests waiting for a JDBC connection without threads, then thread starvation would not occur, as only 30 threads would be consumed by requests accessing the database and the other 470 threads would be available to process the request that do not access the database. - -For an example of Jetty's solution, see the Quality of Service Filter. - -==== Servlet Threading Model - -The scalability issues of Java servlets are caused mainly by the server threading model: - -===== Thread per connection - -The traditional IO model of Java associated a thread with every TCP/IP connection. -If you have a few very active threads, this model can scale to a very high number of requests per second. - -However, the traffic profile typical of many web applications is many persistent HTTP connections that are mostly idle while users read pages or search for the next link to click. With such profiles, the thread-per-connection model can have problems scaling to the thousands of threads required to support thousands of users on large scale deployments. - -===== Thread per request - -The Java NIO libraries support asynchronous IO, so that threads no longer need to be allocated to every connection. -When the connection is idle (between requests), then the connection is added to an NIO select set, which allows one thread to scan many connections for activity. -Only when IO is detected on a connection is a thread allocated to it. -However, the servlet 2.5 API model still requires a thread to be allocated for the duration of the request handling. - -This thread-per-request model allows much greater scaling of connections (users) at the expense of a small reduction to maximum requests per second due to extra scheduling latency. - -===== Asynchronous Request handling - -The Jetty Continuation (and the servlet 3.0 asynchronous) API introduce a change in the servlet API that allows a request to be dispatched multiple times to a servlet. -If the servlet does not have the resources required on a dispatch, then the request is suspended (or put into asynchronous mode), so that the servlet may return from the dispatch without a response being sent. -When the waited-for resources become available, the request is re-dispatched to the servlet, with a new thread, and a response is generated. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-patterns.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-patterns.adoc deleted file mode 100644 index bc96488c566..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-patterns.adoc +++ /dev/null @@ -1,126 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -[[continuations-patterns]] -=== Common Continuation Patterns - -==== Suspend Resume Pattern - -The suspend/resume style is used when a servlet and/or filter is used to generate the response after an asynchronous wait that is terminated by an asynchronous handler. -Typically a request attribute is used to pass results and to indicate if the request has already been suspended. - -[source, java, subs="{sub-order}"] ----- -void doGet(HttpServletRequest request, HttpServletResponse response) -{ - // if we need to get asynchronous results - Object results = request.getAttribute("results"); - if (results==null) - { - final Continuation continuation = ContinuationSupport.getContinuation(request); - - // if this is not a timeout - if (continuation.isExpired()) - { - sendMyTimeoutResponse(response); - return; - } - - // suspend the request - continuation.suspend(); // always suspend before registration - - // register with async service. The code here will depend on the - // the service used (see Jetty HttpClient for example) - myAsyncHandler.register(new MyHandler() - { - public void onMyEvent(Object result) - { - continuation.setAttribute("results",results); - continuation.resume(); - } - }); - return; // or continuation.undispatch(); - } - - // Send the results - sendMyResultResponse(response,results); -} - ----- - -This style is very good when the response needs the facilities of the servlet container (e.g., it uses a web framework) or if one event may resume many requests so the container's thread pool can be used to handle each of them. - -==== Suspend Continue Pattern - -The suspend/complete style is used when an asynchronous handler is used to generate the response: - -[source, java, subs="{sub-order}"] ----- -void doGet(HttpServletRequest request, HttpServletResponse response) -{ - final Continuation continuation = ContinuationSupport.getContinuation(request); - - // if this is not a timeout - if (continuation.isExpired()) - { - sendMyTimeoutResponse(request,response); - return; - } - - // suspend the request - continuation.suspend(); // response may be wrapped. - - // register with async service. The code here will depend on the - // the service used (see Jetty HttpClient for example) - myAsyncHandler.register(new MyHandler() - { - public void onMyEvent(Object result) - { - sendMyResultResponse(continuation.getServletResponse(),results); - continuation.complete(); - } - }); -} - ----- - -This style is very good when the response does not need the facilities of the servlet container (e.g., it does not use a web framework) and if an event will resume only one continuation. -If many responses are to be sent (e.g., a chat room), then writing one response may block and cause a DOS on the other responses. - -==== Examples - -* The https://github.com/eclipse/jetty.project/blob/jetty-8/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java[ChatServlet example] shows how the suspend/resume style can be used to directly code a chat room (See similar https://github.com/eclipse/jetty.project/blob/master/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java[example] using Async Servlets). -The same principles are applied to frameworks like http://cometd.org/[cometd] which provide an richer environment for such applications, based on Continuations. - -* The link:{JDURL}/org/eclipse/jetty/servlets/QoSFilter.html[QoSFilter] uses suspend/resume style to limit the number of requests simultaneously within the filter. -This can be used to protect a JDBC connection pool or other limited resource from too many simultaneous requests. - -+ -If too many requests are received, the extra requests wait for a short time on a semaphore, before being suspended. -As requests within the filter return, they use a priority queue to resume the suspended requests. -This allows your authenticated or priority users to get a better share of your server's resources when the machine is under load. -+ - -* The link:{JDURL}/org/eclipse/jetty/servlets/DoSFilter.html[DosFilter] is similar to the QoSFilter, but protects a web application from a denial of service attack, as much as is possible from within a web application. - -+ -If too many requests are detected coming from one source, then those requests are suspended and a warning generated. -This works on the assumption that the attacker may be written in simple blocking style, so by suspending you are hopefully consuming their resources. True protection from DOS can only be achieved by network devices (or eugenics :)). -+ - -* The link:{JDURL}/org/eclipse/jetty/proxy/ProxyServlet.html[ProxyServlet] uses the suspend/complete style and the Jetty asynchronous HTTP client to implement a scalable Proxy server (or transparent proxy). diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-using.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-using.adoc deleted file mode 100644 index 2e50c27185a..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/continuations/continuations-using.adoc +++ /dev/null @@ -1,116 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -[[continuations-using]] -=== Using Continuations - -Asynchronous servlets were originally introduced with Jetty 6 Continuations, which were a Jetty specific mechanism. -From Jetty 7 onwards, the Continuations API has been extended to be a general purpose API that will work asynchronously on any servlet-3.0 container, as well as on Jetty 6, 7, or 8. -Continuations will also work in blocking mode with any servlet 2.5 container. - -==== Obtaining a Continuation - -The link:{JDURL}/org/eclipse/jetty/continuation/ContinuationSupport.html[ContinuationSupport] factory class can be used to obtain a continuation instance associated with a request: - -`Continuation continuation = ContinuationSupport.getContinuation(request);` - -==== Suspending a Request - -To suspend a request, the suspend method can be called on the continuation: - -[source, java, subs="{sub-order}"] ----- - void doGet(HttpServletRequest request, HttpServletResponse response) - { - ... - // optionally: - // continuation.setTimeout(long); - continuation.suspend(); - ... - } - ----- - -The lifecycle of the request will be extended beyond the return to the container from the `Servlet.service(...)` method and `Filter.doFilter(...)` calls. When these dispatch methods return, the suspended request will not yet be committed and a response will not yet be sent to the HTTP client. - -Once the request has been suspended, the continuation should be registered with an asynchronous service so that it may be used by an asynchronous callback when the waited-for event happens. - -The request will be suspended until either `continuation.resume()` or `continuation.complete()` is called. If neither is called then the continuation will timeout. -The timeout should be set before the suspend, by a call to `continuation.setTimeout(long)` if no timeout is set, then the default period is used. -If no timeout listeners resume or complete the continuation, then the continuation is resumed with `continuation.isExpired()` true. - -Suspension is analogous to the servlet 3.0 `request.startAsync()` method. Unlike jetty 6 continuations, an exception is not thrown by suspend and the method should return normally. -This allows the registration of the continuation to occur after suspension and avoids the need for a mutex. -If an exception is desirable (to bypass code that is unaware of continuations and may try to commit the response), then `continuation.undispatch()` may be called to exit the current thread from the current dispatch by throwing a `ContinuationThrowable`. - -==== Resuming a Request - -Once an asynchronous event has occurred, the continuation can be resumed: - -[source, java, subs="{sub-order}"] ----- - void myAsyncCallback(Object results) - { - continuation.setAttribute("results",results); - continuation.resume(); - } ----- - -When a continuation is resumed, the request is re-dispatched to the servlet container, almost as if the request had been received again. -However during the re-dispatch, the `continuation.isInitial()` method returns false and any attributes set by the asynchronous handler are available. - -Continuation resume is analogous to Servlet 3.0 `AsyncContext.dispatch()`. - -==== Completing a Request - -As an alternative to resuming a request, an asynchronous handler may write the response itself. After writing the response, the handler must indicate the request handling is complete by calling the complete method: - -[source, java, subs="{sub-order}"] ----- - void myAsyncCallback(Object results) - { - writeResults(continuation.getServletResponse(),results); - continuation.complete(); - } ----- - -After complete is called, the container schedules the response to be committed and flushed. Continuation complete is analogous to Servlet 3.0 `AsyncContext.complete()`. - -==== Continuation Listeners - -An application may monitor the status of a continuation by using a ContinuationListener: - -[source, java, subs="{sub-order}"] ----- - void doGet(HttpServletRequest request, HttpServletResponse response) - { - ... - - Continuation continuation = ContinuationSupport.getContinuation(request); - continuation.addContinuationListener(new ContinuationListener() - { - public void onTimeout(Continuation continuation) { ... } - public void onComplete(Continuation continuation) { ... } - }); - - continuation.suspend(); - ... - } ----- - -Continuation listeners are analogous to Servlet 3.0 AsyncListeners. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/bugs.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/bugs.adoc index cfe3477bbc9..90dd07ca005 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/bugs.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/bugs.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[bugs]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/chapter.adoc index fcf4ca49e92..86494d186a4 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[advanced-contributing]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/coding-standards.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/coding-standards.adoc index ae2c7271e31..7ec2f2303e3 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/coding-standards.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/coding-standards.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[coding-standards]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/community.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/community.adoc index f6213ceb156..821ac637d82 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/community.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/community.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[community]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/documentation.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/documentation.adoc index bd295c93a44..7bfeabc1e34 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/documentation.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/documentation.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[contributing-documentation]] @@ -192,22 +192,23 @@ license blocks:: .... // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // + .... Some admonition examples: diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/patches.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/patches.adoc index cee213520bf..6b3712c8ac6 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/patches.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/patches.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[contributing-patches]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/release-testing.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/release-testing.adoc index 60516d75be1..2b26631ff76 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/release-testing.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/release-testing.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[release-testing]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/releasing-jetty.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/releasing-jetty.adoc index bbdecffd8ce..2fb7117a9aa 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/releasing-jetty.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/releasing-jetty.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[releasing-jetty]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/security.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/security.adoc index 87634a2e2cd..b8eb4bef1cc 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/security.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/security.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[security-reporting]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/source-build.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/source-build.adoc index dd3179a9f64..5283c8bab1a 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/source-build.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/contributing/source-build.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[contributing-source-build]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/chapter.adoc index 2fde923a99a..7cc7f41bee6 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[advanced-debugging]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-eclipse.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-eclipse.adoc index c4a125f4894..48a7621b371 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-eclipse.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-eclipse.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[debugging-with-eclipse]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-intellij.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-intellij.adoc index 2210d180e3b..ca583338184 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-intellij.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/debugging-with-intellij.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[debugging-with-intellij]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/enable-remote-debugging.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/enable-remote-debugging.adoc index 9edcb39bf63..85cb4ec9010 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/enable-remote-debugging.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/debugging/enable-remote-debugging.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[enable-remote-debugging]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/chapter.adoc index 56350930eef..5f8b140df8a 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[advanced-embedding]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedded-examples.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedded-examples.adoc index 8a7507f5307..ea9c922caa5 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedded-examples.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedded-examples.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-examples]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedding-jetty.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedding-jetty.adoc index 8790ef996fa..469e119dc66 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedding-jetty.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/embedding-jetty.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedding-jetty]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-file-server.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-file-server.adoc index d4a6d5c2f2c..9ec0a2c163a 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-file-server.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-file-server.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-file-server]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-many-connectors.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-many-connectors.adoc index 8ee42831a4c..48f74a17f39 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-many-connectors.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-many-connectors.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-many-connectors]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-minimal-servlet.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-minimal-servlet.adoc index a799bf5c3e5..6d440c591fd 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-minimal-servlet.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-minimal-servlet.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-minimal-servlet]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-one-webapp.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-one-webapp.adoc index f81651079e0..048d5ddd4d3 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-one-webapp.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-one-webapp.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-one-webapp]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-secured-hello-handler.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-secured-hello-handler.adoc index 8171e5c5219..1cea7c6d9b2 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-secured-hello-handler.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-secured-hello-handler.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-secured-hello-handler]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-split-file-server.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-split-file-server.adoc index ee7a6e29009..7aa6631c9b3 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-split-file-server.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/examples/embedded-split-file-server.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[embedded-split-file-server]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/jetty-helloworld.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/jetty-helloworld.adoc index 4acd12f6ac5..8ff53ec770d 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/jetty-helloworld.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/embedding/jetty-helloworld.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-helloworld]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/faq/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/faq/chapter.adoc index fb7d8c6a8a6..54e6237ac98 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/faq/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/faq/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[faq]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/chapter.adoc index 3acc2011a22..4b5a2cb12ce 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[frameworks]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/metro.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/metro.adoc index e4fd98e0ce1..6ddf1ae3f69 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/metro.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/metro.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[framework-metro]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/osgi.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/osgi.adoc index 8b5d7b0812e..dc0493dabee 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/osgi.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/osgi.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[framework-jetty-osgi]] @@ -1104,22 +1104,22 @@ You should see output similar to this on the console, using the `felix:lb` comma 6|Active | 1|javax.mail bundle from Glassfish (1.4.1.v201005082020) 7|Active | 1|Java Server Pages Standard Tag Library API Bundle (1.2.0.v201105211821) 8|Active | 1|JavaServer Pages (TM) TagLib Implementation (1.2.2) - 9|Active | 1|Jetty :: Servlet Annotations (9.4.14) - 10|Active | 1|Jetty :: Deployers (9.4.14) - 11|Active | 1|Jetty :: Http Utility (9.4.14) - 12|Active | 1|Jetty :: IO Utility (9.4.14) - 13|Active | 1|Jetty :: JNDI Naming (9.4.14) - 14|Active | 1|Jetty :: OSGi :: Boot (9.4.14) - 15|Resolved | 1|Jetty-OSGi-Jasper Integration (9.4.14) + 9|Active | 1|Jetty :: Servlet Annotations ({VERSION}) + 10|Active | 1|Jetty :: Deployers ({VERSION}) + 11|Active | 1|Jetty :: Http Utility ({VERSION}) + 12|Active | 1|Jetty :: IO Utility ({VERSION}) + 13|Active | 1|Jetty :: JNDI Naming ({VERSION}) + 14|Active | 1|Jetty :: OSGi :: Boot ({VERSION}) + 15|Resolved | 1|Jetty-OSGi-Jasper Integration ({VERSION}) 16|Active | 1|Jetty Servlet API and Schemas for OSGi (3.1.0) - 17|Active | 1|Jetty :: Plus (9.4.14) - 18|Active | 1|Jetty :: Security (9.4.14) - 19|Active | 1|Jetty :: Server Core (9.4.14) - 20|Active | 1|Jetty :: Servlet Handling (9.4.14) - 21|Active | 1|Jetty :: Utility Servlets and Filters (9.4.14) - 22|Active | 1|Jetty :: Utilities (9.4.14) - 23|Active | 1|Jetty :: Webapp Application Support (9.4.14) - 24|Active | 1|Jetty :: XML utilities (9.4.14) + 17|Active | 1|Jetty :: Plus ({VERSION}) + 18|Active | 1|Jetty :: Security ({VERSION}) + 19|Active | 1|Jetty :: Server Core ({VERSION}) + 20|Active | 1|Jetty :: Servlet Handling ({VERSION}) + 21|Active | 1|Jetty :: Utility Servlets and Filters ({VERSION}) + 22|Active | 1|Jetty :: Utilities ({VERSION}) + 23|Active | 1|Jetty :: Webapp Application Support ({VERSION}) + 24|Active | 1|Jetty :: XML utilities ({VERSION}) 25|Active | 1|Apache Aries SPI Fly Dynamic Weaving Bundle (1.2) 27|Active | 1|Apache Felix Bundle Repository (2.0.2) 28|Active | 1|Apache Felix Configuration Admin Service (1.8.0) @@ -1128,7 +1128,7 @@ You should see output similar to this on the console, using the `felix:lb` comma 31|Active | 1|Apache Felix Gogo Runtime (0.12.1) 32|Active | 1|Apache Felix Gogo Shell (0.10.0) 33|Active | 1|Apache Felix Log Service (1.0.1) - 34|Active | 1|Jetty :: Apache JSP (9.4.14) + 34|Active | 1|Jetty :: Apache JSP ({VERSION}) 35|Active | 1|Eclipse Compiler for Java(TM) (3.8.2.v20130121-145325) 36|Active | 1|Mortbay EL API and Implementation (8.5.33.1) 37|Active | 1|Mortbay Jasper (8.5.33.1) diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/spring-usage.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/spring-usage.adoc index 2139690edf8..2888c22a6b7 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/spring-usage.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/spring-usage.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[framework-jetty-spring]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/weld.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/weld.adoc index 7c42e138663..dd48cc34531 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/weld.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/frameworks/weld.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[framework-weld]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/chapter.adoc index c44a65977ff..ec0b8bba510 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-handlers]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/writing-custom-handlers.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/writing-custom-handlers.adoc index 21730437c2b..026007fe3ee 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/writing-custom-handlers.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/handlers/writing-custom-handlers.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[writing-custom-handlers]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/chapter.adoc index 81e05bea2a5..d51cf3a282e 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[reference-section]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-env-xml.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-env-xml.adoc index a89c2669e0c..42568639b3c 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-env-xml.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-env-xml.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-env-xml]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-web-xml-config.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-web-xml-config.adoc index 4f3673774de..c36cfd33340 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-web-xml-config.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-web-xml-config.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-web-xml-config]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-config.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-config.adoc index d25bdf3c426..d76a289a552 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-config.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-config.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-xml-config]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-syntax.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-syntax.adoc index 609b60c198c..f909db9992c 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-syntax.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-syntax.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-xml-syntax]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-usage.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-usage.adoc index 93e0947c96b..92ed0dda309 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-usage.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/jetty-xml-usage.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-xml-usage]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/override-web-xml.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/override-web-xml.adoc index e77435c6ad3..e6566ba4086 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/override-web-xml.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/override-web-xml.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[override-web-xml]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/webdefault-xml.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/webdefault-xml.adoc index f2f83c7e8e4..84aead936cb 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/webdefault-xml.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/jetty-xml/webdefault-xml.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[webdefault-xml]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/chapter.adoc index 42925cd1c5b..b596cbb81c7 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[maven-and-jetty]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-jspc-maven-plugin.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-jspc-maven-plugin.adoc index c715177cc18..edd351d6642 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-jspc-maven-plugin.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-jspc-maven-plugin.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-jspc-maven-plugin]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-helloworld.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-helloworld.adoc index 90cbe9e14ed..641991ba9fe 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-helloworld.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-helloworld.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-maven-helloworld]] @@ -29,7 +29,7 @@ ____ [NOTE] Use of Maven and the jetty-maven-plugin is *not* required. Using Maven for Jetty implementations is a popular choice, but users encouraged to manage their projects in whatever way suits their needs. -Other popular tools include Ant and Gradle. +Other popular tools include Ant and Gradle. ____ First we'll have a look at a very simple HelloWorld java application that embeds Jetty, then a simple webapp which makes use of the link:#jetty-maven-plugin[jetty-maven-plugin] to speed up the development cycle. @@ -117,7 +117,7 @@ Use an editor to create the file `pom.xml` in the `JettyMavenHelloWorld` directo - 9.3.9.v20160517 + {VERSION} diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-plugin.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-plugin.adoc index 53c58194222..a2a4421e4f5 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-plugin.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-plugin.adoc @@ -1,37 +1,63 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-maven-plugin]] === Configuring the Jetty Maven Plugin The Jetty Maven plugin is useful for rapid development and testing. -You can add it to any webapp project that is structured according to the Maven defaults. -The plugin can then periodically scan your project for changes and automatically redeploy the webapp if any are found. +It can optionally periodically scan your project for changes and automatically redeploy the webapp if any are found. This makes the development cycle more productive by eliminating the build and deploy steps: you use your IDE to make changes to the project, and the running web container automatically picks them up, allowing you to test them straight away. +The plugin has been substantially re-architected in jetty-10 to: + +* have less goals +* make deployment modes (embedded, forked or to a jetty distribution) apply uniformly across all goals +* simplify configuration options +* make the purpose and operation of each goal clearer +* rearchitect with composition rather than inheritance to make future extensions easier + +There are now only 4 goals to run a webapp in jetty: + +* link:#jetty-run-goal[jetty:run] +* link:#jetty-run-war-goal[jetty:run-war] +* link:#jetty-start-goal[jetty:start] +* link:#jetty-start-war-goal[jetty:start-war] + +Plus two utility goals: + +* link:#jetty-stop-goal[jetty:stop] +* link:#jetty-effective-web-xml-goal[jetty:effective-web-xml] + +`jetty:run` and `jetty:start` are alike in that they both run an unassembled webapp in jetty,however `jetty:run` is designed to be used at the command line, whereas `jetty:start` is specifically designed to be bound to execution phases in the build lifecycle. +`jetty:run` will pause maven while jetty is running, echoing all output to the console, and then stop maven when jetty exits. +`jetty:start` will not pause maven, will write all its output to a file, and will not stop maven when jetty exits. + +`jetty:run-war` and `jetty:start-war` are similar in that they both run an _assembled_ war file in jetty. +However, `jetty:run-war` is designed to be run at the command line, whereas `jetty:start-war` is specifically designed to be bound to execution phases in the build lifecycle. +`jetty:run-war` will pause maven while jetty is running, echoing all output to the console, and then stop maven when jetty exits. +`jetty:start-war` will not not pause maven, will write all its output to a file, and will not stop maven when jetty exits. + ____ [IMPORTANT] -You should use Maven 3.3+ for this plugin. -____ - -While the Jetty Maven Plugin can be very useful for development we do not recommend its use in a production capacity. +While the Jetty Maven Plugin can be very useful for development we do not recommend its use in a _production capacity_. In order for the plugin to work it needs to leverage many internal Maven apis and Maven itself it not a production deployment tool. -We recommend either the traditional distribution deployment approach or using link:#advanced-embedding[embedded Jetty.] +We recommend either the traditional link:{DISTGUIDE}[distribution] deployment approach or using link:#advanced-embedding[embedded Jetty]. +____ [[get-up-and-running]] ==== Quick Start: Get Up and Running @@ -57,25 +83,31 @@ mvn jetty:run This starts Jetty and serves up your project on http://localhost:8080/. Jetty will continue to run until you stop it. -While it runs it periodically scans for changes to your project files -If you save changes and recompile your class files, Jetty redeploys your webapp, and you can instantly test the changes that were just made. +By default, it will not automatically restart your webapp: you can force a redeploy by hitting the `Enter` key. +Set a non-zero <scan> value to have jetty scan your webapp for changes and automatically redeploy. You can terminate the plugin with a `ctrl-c` in the terminal window where it is running. ____ [NOTE] The classpath of the running Jetty instance and its deployed webapp are managed by Maven, and may not be exactly what you expect. -For example: a webapp's dependent jars might be referenced via the local repository, not the `WEB-INF/lib` directory. +For example: a webapp's dependent jars might be referenced via the local repository, or other projects in the reactor, not the `WEB-INF/lib` directory. ____ -[[running-and-deploying]] +[[supported-goals]] ==== Supported Goals -The Jetty Maven plugin has a number of distinct Maven goals. -Arguably the most useful is the `run` goal which runs Jetty on an unassembled webapp. -There are other goals which help you accomplish different tasks. -For example, you might need to run your webapp in a forked instance of Jetty rather than within the process running Maven; or you may need finer grained control over the maven lifecycle stage in which you wish to deploy your webapp. -There are different goals to accomplish these tasks, as well as several others. +The goals prefixed with `"run"` are designed to be used at the _command line_. +They first run a maven build on your project to ensure at least the classes are all built. +They then start jetty and pause the maven build process until jetty is manually terminated, at which time the build will also be terminated. +Jetty can scan various files in your project for changes and redeploy the webapp as necessary, or you can choose to manually trigger a redeploy if you prefer. +All output from jetty is echoed to the console. + +The goals prefixed with `"start"` are designed to be used with _build lifecycle bindings in the pom_, and _not_ at the command line. +No part of your project will be rebuilt by invoking these goals - you should ensure that your bind the execution to a build phase where all necessary parts of your project have been built. +Maven will start and terminate jetty at the appropriate points in the build lifecycle, continuing with the build. +Jetty will _not_ scan any files in your project for changes, and your webapp will _not_ be redeployed either automatically or manually. +Output from jetty is directed to a file in the `target` directory. To see a list of all goals supported by the Jetty Maven plugin, do: @@ -91,54 +123,46 @@ To see the detailed list of parameters that can be configured for a particular g mvn jetty:help -Ddetail=true -Dgoal= .... -[[configuring-jetty-container]] -==== Configuring the Jetty Container +[[deployment-modes]] +==== Deployment Modes +All of the `"run"` and `"start"` goals can deploy your webapp either into the running maven process, or forked into a new child process, or forked into a jetty distribution on disk. -These configuration elements set up the Jetty environment in which your webapp executes. -They are common to most goals: +This is controlled by setting the `deployMode` configuration parameter in the pom, but can also be set by defining the maven property 'jetty.deployMode'. + +===== Embedded + +`deployMode` of `EMBED`. +This is the "classic" jetty maven plugin deployment mode, running in-process with maven. +This is the _default_ mode. + +These extra configuration parameters are available: httpConnector:: Optional. +NOTE to configure a https connector, you will need to use xml configuration files instead, setting the `jettyXmls` parameter. +This parameter can only be used to configure a standard http connector. If not specified, Jetty will create a link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector] instance listening on port 8080. You can change this default port number by using the system property `jetty.http.port` on the command line, for example, `mvn -Djetty.http.port=9999 jetty:run`. Alternatively, you can use this configuration element to set up the information for the ServerConnector. The following are the valid configuration sub-elements: -+ -port;; +port::: The port number for the connector to listen on. By default it is 8080. -host;; +host::: The particular interface for the connector to listen on. By default, all interfaces. -name;; +name::: The name of the connector, which is useful for link:#serving-webapp-from-particular-port[configuring contexts to respond only on particular connectors]. -idleTimeout;; +idleTimeout::: Maximum idle time for a connection. -+ You could instead configure the connectors in a standard link:#jetty-xml-config[jetty xml config file] and put its location into the `jettyXml` parameter. Note that since Jetty 9.0 it is no longer possible to configure a link:#maven-config-https[https connector] directly in the pom.xml: you need to link:#maven-config-https[use jetty xml config files to do it]. -jettyXml:: -Optional. -A comma separated list of locations of Jetty xml files to apply in addition to any plugin configuration parameters. -You might use it if you have other webapps, handlers, specific types of connectors etc., to deploy, or if you have other Jetty objects that you cannot configure from the plugin. -scanIntervalSeconds:: -The pause in seconds between sweeps of the webapp to check for changes and automatically hot redeploy if any are detected. -*By default this is 0, which disables hot deployment scanning.* -A number greater than 0 enables it. -reload:: -Default value is "automatic", used in conjunction with a non-zero *_`scanIntervalSeconds`_* causes automatic hot redeploy when changes are detected. -Set to "manual" instead to trigger scanning by typing a linefeed in the console running the plugin. -This might be useful when you are doing a series of changes that you want to ignore until you're done. -In that use, use the `reload` parameter. -dumpOnStart:: -Optional. -Default value is false. -If true, then jetty will dump out the server structure on start. loginServices:: Optional. A list of `org.eclipse.jetty.security.LoginService` implementations. Note that there is no default realm. If you use a realm in your `web.xml` you can specify a corresponding realm here. You could instead configure the login services in a jetty xml file and add its location to the `jettyXml` parameter. +See link:#configuring-security-settings[Configuring Security]. requestLog:: Optional. An implementation of the `org.eclipse.jetty.server.RequestLog` request log interface. @@ -152,99 +176,153 @@ There are three other ways to configure the RequestLog: See link:#configuring-jetty-request-logs[Configuring Request Logs] for more information. server:: Optional as of Jetty 9.3.1. -This would configure an instance of the link:{GITBROWSEURL}/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java[`org.eclipse.jetty.server.Server`] for the plugin to use, however it is usually NOT necessary to configure this, as the plugin will automatically configure one for you. -In particular, if you use the jettyXml element, then you generally DON'T want to define this element, as you are probably using the jettyXml file to configure up a Server with a special constructor argument, such as a custom threadpool. -If you define both a server element AND use a jetty xml element which points to a config file that has a line like `` then the the xml configuration will override what you configure for the server in the `pom.xml`. -stopPort:: +This would configure an instance of the link:{GITBROWSEURL}/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java[`org.eclipse.jetty.server.Server`] for the plugin to use, however it is usually _not_ necessary to configure this, as the plugin will automatically configure one for you. +In particular, if you use the `jettyXmls` element, then you generally _don't_ want to define this element, as you are probably using the `jettyXmls` file/s to configure up a Server with a special constructor argument, such as a custom threadpool. +If you define both a `server` element and use a `jettyXmls` element which points to a config file that has a line like `` then the the xml configuration will override what you configure for the `server` in the `pom.xml`. +useProvidedScope:: +Default value is `false`. +If true, the dependencies with `provided` are placed onto the __container classpath__. +Be aware that this is _not_ the webapp classpath, as `provided` indicates that these dependencies would normally be expected to be provided by the container. +You should very rarely ever need to use this. +See link:#container-classpath[Container Classpath vs WebApp Classpath]. + +===== Forked + +`deployMode` of `FORK`. +This is similar to the old "jetty:run-forked" goal - a separate process is forked to run your webapp embedded into jetty. +These extra configuration parameters are available: + +env:: Optional. -Port to listen on for stop commands. -Useful to use in conjunction with the link:#jetty-stop-goal[stop] or link:#jetty-run-forked-goal[run-forked] goals. -stopKey:: +Map of key/value pairs to pass as environment to the forked JVM. +jvmArgs:: Optional. -Used in conjunction with stopPort for stopping jetty. -Useful when used in conjunction with the stop or run-forked goals. -systemProperties:: +A string representing arbitrary arguments to pass to the forked JVM. +forkWebXml:: Optional. -Allows you to configure System properties for the execution of the plugin. -For more information, see link:#sys_props[Setting System Properties]. -systemPropertiesFile:: -Optional. -A file containing System properties to set for the execution of the plugin. -By default, settings that you make here *do not* override any system properties already set on the command line, by the JVM, or in the POM via `systemProperties`. -Read link:#sys_props[Setting System Properties] for how to force overrides. -skip:: -Default is false. -If true, the execution of the plugin exits. -Same as setting the SystemProperty `-Djetty.skip` on the command line. -This is most useful when configuring Jetty for execution during integration testing and you want to skip the tests. +Defaults to `target/fork-web.xml`. +This is the location of a quickstart web xml file that will be _generated_ during the forking of the jetty process. +You should not need to set this parameter, but it is available if you wish to control the name and location of that file. useProvidedScope:: Default value is `false`. If true, the dependencies with `provided` are placed onto the __container classpath__. Be aware that this is NOT the webapp classpath, as "provided" indicates that these dependencies would normally be expected to be provided by the container. You should very rarely ever need to use this. -Instead, you should copy the provided dependencies as explicit dependencies of the `plugin` instead. +See link:#container-classpath[Container Classpath vs WebApp Classpath]. + +===== In a jetty distribution + +`deployMode` of `DISTRO`. +This is similar to the old "jetty:run-distro" goal - your webapp is deployed into a dynamically downloaded, unpacked and configured jetty distribution. +A separate process is forked to run the distro. +These extra configuration parameters are available: + +jettyBase:: +Optional. +The location of an existing jetty base directory to use to deploy the webapp. +The existing base will be copied to the `target/` directory before the webapp is deployed. +If there is no existing jetty base, a fresh one will be made in `target/jetty-base`. +jettyHome:: +Optional. +The location of an existing unpacked jetty distribution. +If one does not exist, a fresh jetty distribution will be downloaded from maven and installed to the `target` directory. +jvmArgs:: +Optional. +A string representing arguments that should be passed to the jvm of the child process running the distro. +modules:: +Optional. +An array of names of additional jetty modules that the jetty child process will activate. +Use this to change the link:#container-classpath[container classpath] instead of `useProvidedScope`. +These modules are enabled by default: `server,http,webapp,deploy`. + + +[[common-configuration]] +==== Common Configuration + +The following configuration parameters are common to all of the `"run-"` and `"start-"` goals: + +deployMode:: +One of `EMBED`, `FORK` or `DISTRO`. +Default `EMBED`. +Can also be configured by setting the Maven property `jetty.deployMode`. +This parameter determines whether the webapp will run in jetty in-process with Maven, forked into a new process, or deployed into a jetty distribution. +See link:#deployment-modes[Deployment Modes]. +jettyXmls:: +Optional. +A comma separated list of locations of jetty xml files to apply in addition to any plugin configuration parameters. +You might use it if you have other webapps, handlers, specific types of connectors etc., to deploy, or if you have other Jetty objects that you cannot configure from the plugin. +skip:: +Default is false. +If true, the execution of the plugin exits. +Same as setting the SystemProperty `-Djetty.skip` on the command line. +This is most useful when configuring Jetty for execution during integration testing and you want to skip the tests. excludedGoals:: Optional. A list of Jetty plugin goal names that will cause the plugin to print an informative message and exit. Useful if you want to prevent users from executing goals that you know cannot work with your project. +supportedPackagings:: +Optional. +Defaults to `war`. +This is a list of maven <packaging> types that can work with the jetty plugin. +Usually, only `war` projects are suitable, however, you may configure other types. +The plugin will refuse to start if the <packaging> type in the pom is not in list of `supportedPackagings`. +systemProperties:: +Optional. +Allows you to configure System properties for the execution of the plugin. +For more information, see link:#setting-system-properties[Setting System Properties]. +systemPropertiesFile:: +Optional. +A file containing System properties to set for the execution of the plugin. +By default, settings that you make here *do not* override any system properties already set on the command line, by the JVM, or in the POM via `systemProperties`. +Read link:#setting-system-properties[Setting System Properties] for how to force overrides. +jettyProperties:: +Optional. +A map of property name, value pairs. +Allows you to configure standard jetty properties. -[[maven-config-https]] -===== Configuring a Https Connector +[[container-classpath]] +==== Container Classpath vs WebApp Classpath -In order to configure an HTTPS connector, you need to use jetty xml configuration files. -This example uses files copied directly from the jetty distribution etc/ directory, although you can of course make up your own xml file or files. -We will use the following files: +The Servlet Specification makes a strong distinction between the classpath for a webapp, and the classpath of the container. +When running in maven, the plugin's classpath is equivalent to the container classpath. +It will make a classpath for the webapp to be deployed comprised of <dependencies> specified in the pom. -jetty.xml:: -Sets up various characteristics of the link:{GITBROWSEURL}/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java[`org.eclipse.jetty.server.Server`] instance for the plugin to use. -Importantly, it sets up the link:{GITBROWSEURL}/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java[`org.eclipse.jetty.server.HttpConfiguration`] element that we can refer to in subsequent xml files that configure the connectors. -Below is the relevant section taken from link:{GITBROWSEURL}/jetty-server/src/main/config/etc/jetty.xml[jetty.xml]. -+ -[source, xml, subs="{sub-order}"] ----- - - ... - - - - - - - - - - - - - - +If your production environment places specific jars onto the container's classpath, the equivalent way to do this with maven is to define these as <dependencies> for the _plugin_ itself, not the _project_. See http://maven.apache.org/pom.html#Plugins[configuring maven plugins]. +This is suitable if you are using either `EMBED` or `FORK` mode. +If you are using `DISTRO` mode, then you should configure the `modules` parameter with the names of the jetty modules that place these jars onto the container classpath. - - - ... - ----- -jetty-ssl.xml:: -Sets up ssl which will be used by the https connector. -Here's the `jetty-ssl.xml` file from the jetty-distribution: -+ -[source, xml, subs="{sub-order}"] ----- -include::{SRCDIR}/jetty-server/src/main/config/etc/jetty-ssl.xml[] ----- -jetty-https.xml:: -Set up the https connector using the HttpConfiguration from `jetty.xml` and the ssl configuration from `jetty-ssl.xml`: -+ -[source, xml, subs="{sub-order}"] ----- -include::{SRCDIR}/jetty-server/src/main/config/etc/jetty-https.xml[] ----- +Note that in `EMBED` or `FORK` mode, you could also influence the container classpath by setting the `useProvidedScope` parameter to `true`: this will place any dependencies with <scope>provided<scope> onto the plugin's classpath. +Use this very cautiously: as the plugin already automatically places most jetty jars onto the classpath, you could wind up with duplicate jars. -Now you need to let the plugin know to apply the files above: + +[[jetty-run-goal]] +==== jetty:run + +The `run` goal deploys a webapp that is _not_ first built into a WAR. +A virtual webapp is constructed from the project's sources and its dependencies. +It looks for the constituent parts of a webapp in the maven default project locations, although you can override these in the plugin configuration. +For example, by default it looks for: + +* resources in `${project.basedir}/src/main/webapp` +* classes in `${project.build.outputDirectory}` +* `web.xml` in `${project.basedir}/src/main/webapp/WEB-INF/` + +The plugin first runs a maven parallel build to ensure that the classes are built and up-to-date before deployment. +If you change the source of a class and your IDE automatically compiles it in the background, the plugin picks up the changed class (note you need to configure a non-zero `scan` interval for automatic redeployment, otherwise redeployment only occurs if you hit the `Enter` key). + +If the plugin is invoked in a multi-module build, any dependencies that are also in the maven reactor are used from their compiled classes. +Prior to jetty-9.4.7 any dependencies needed to be built first. + +Once invoked, you can configure the plugin to run continuously, scanning for changes in the project and automatically performing a hot redeploy when necessary. +Any changes you make are immediately reflected in the running instance of Jetty, letting you quickly jump from coding to testing, rather than going through the cycle of: code, compile, reassemble, redeploy, test. + +The maven build will be paused until jetty exits, at which time maven will also exit. + +Stopping jetty is accomplished by typing `cntrl-c` at the command line. + +Output from jetty will be logged to the console. + +Here is an example, which turns on scanning for changes every ten seconds, and sets the webapp context path to `/test`: [source, xml, subs="{sub-order}"] ---- @@ -253,62 +331,266 @@ Now you need to let the plugin know to apply the files above: jetty-maven-plugin {VERSION} - jetty.xml,jetty-ssl.xml,jetty-https.xml + 10 + + /test + ---- -____ -[CAUTION] -Just as with an installed distribution of Jetty, the ordering of the xml files is significant. -____ - -You can also use Jetty xml files to configure a http connector for the plugin to use. -Here we use the same `jetty-http.xml` file from the Jetty distribution: - -[source, xml, subs="{sub-order}"] ----- -include::{SRCDIR}/jetty-server/src/main/config/etc/jetty-http.xml[] ----- - -Now we add it to the list of configs for the plugin to apply: - -[source, xml, subs="{sub-order}"] ----- - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - jetty.xml,jetty-http.xml,jetty-ssl.xml,jetty-https.xml - - ----- - -Alternatively, you can use the link:#maven-http-connector[*httpConnector*] configuration element inside the pom instead as described above. - -[[configuring-your-webapp]] -==== Configuring Your WebApp - -These configuration parameters apply to your webapp. -They are common to almost all goals. +===== Configuration webApp:: -This is an instance of link:{JDURL}/org/eclipse/jetty/maven/plugin/JettyWebAppContext.html[org.eclipse.jetty.maven.plugin.JettyWebAppContext], which is an extension to the class link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.webapp.WebAppContext`]. +This is an instance of link:{JDURL}/org/eclipse/jetty/maven/plugin/MavenWebAppContext.html[org.eclipse.jetty.maven.plugin.MavenWebAppContext], which is an extension to the class link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.webapp.WebAppContext`]. You can use any of the setter methods on this object to configure your webapp. Here are a few of the most useful ones: + contextPath;; The context path for your webapp. By default, this is set to `/`. -If using a custom value for this parameter, you probably want to include the leading `/`, example `/mycontext`. +If using a custom value for this parameter, you should include the leading `/`, example `/mycontext`. descriptor;; The path to the `web.xml` file for your webapp. +By default, the plugin will look in `src/main/webapp/WEB-INF/web.xml`. defaultsDescriptor;; The path to a `webdefault.xml` file that will be applied to your webapp before the `web.xml`. If you don't supply one, Jetty uses a default file baked into the `jetty-webapp.jar`. overrideDescriptor;; The path to a `web.xml` file that Jetty applies after reading your `web.xml`. You can use this to replace or add configuration. +jettyEnvXml;; +Optional. +Location of a `jetty-env.xml` file, which allows you to make JNDI bindings that satisfy `env-entry`, `resource-env-ref`, and `resource-ref` linkages in the `web.xml` that are scoped only to the webapp and not shared with other webapps that you might be deploying at the same time (for example, by using a `jettyXml` file). +tempDirectory;; +The path to a dir that Jetty can use to expand or copy jars and jsp compiles when your webapp is running. +The default is `${project.build.outputDirectory}/tmp`. +baseResource;; +The path from which Jetty serves static resources. +Defaults to `src/main/webapp`. +If this location does not exist (because, for example, your project does not use static content), then the plugin will synthesize a virtual static resource location of `target/webapp-synth`. +resourceBases;; +Use instead of `baseResource` if you have multiple directories from which you want to serve static content. +This is an array of directory locations, either as urls or file paths. +baseAppFirst;; +Defaults to "true". +Controls whether any overlaid wars are added before or after the original base resource(s) of the webapp. +See the section on link:#using-overlaid-wars[overlaid wars] for more information. +containerIncludeJarPattern;; +Defaults to `.*/jetty-servlet-api-[^/]*\.jar$|.*javax.servlet.jsp.jstl-[^/]*\.jar|.*taglibs-standard-impl-.*\.jar`. +This is a pattern that is applied to the names of the jars on the container's classpath (ie the classpath of the plugin, not that of the webapp) that should be scanned for fragments, tlds, annotations etc. +This is analogous to the context attribute link:#container-include-jar-pattern[org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern] that is documented link:#container-include-jar-pattern[here]. +You can define extra patterns of jars that will be included in the scan. +webInfIncludeJarPattern;; +Defaults to matching _all_ of the dependency jars for the webapp (ie the equivalent of WEB-INF/lib). +You can make this pattern more restrictive to only match certain jars by using this setter. +This is analogous to the context attribute link:#web-inf-include-jar-pattern[org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern] that is documented link:#web-inf-include-jar-pattern[here]. +contextXml:: +The path to a context xml file that is applied to your webapp AFTER the `webApp` element. +classesDirectory:: +Location of your compiled classes for the webapp. +You should rarely need to set this parameter. +Instead, you should set `` in your `pom.xml`. +testClassesDirectory:: +Location of the compiled test classes for your webapp. By default this is `${project.build.testOutputDirectory}`. +useTestScope:: +If true, the classes from `testClassesDirectory` and dependencies of scope "test" are placed first on the classpath. +By default this is false. +scan:: +The pause in seconds between sweeps of the webapp to check for changes and automatically hot redeploy if any are detected. +*By default this is 0, which disables hot deployment scanning. Redeployment is by hitting `Enter` key.* +A number greater than 0 enables it. +scanTargetPatterns:: +Optional. +List of extra directories with glob-style include/excludes patterns (see http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[javadoc] for http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[FileSystem.getPathMatcher]) to specify other files to periodically scan for changes. +scanClassesPattern:: +Optional. +Include and exclude patterns that can be applied to the classesDirectory for the purposes of scanning, it does *not* affect the classpath. +If a file or directory is excluded by the patterns then a change in that file (or subtree in the case of a directory) is ignored and will not cause the webapp to redeploy. +Patterns are specified as a relative path using a glob-like syntax as described in the http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[javadoc] for http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[FileSystem.getPathMatcher]. +scanTestClassesPattern:: +Optional. +Include and exclude patterns that can be applied to the testClassesDirectory for the purposes of scanning, it does *not* affect the classpath. +If a file or directory is excluded by the patterns then a change in that file (or subtree in the case of a directory) is ignored and will not cause the webapp to redeploy. +Patterns are specified as a relative path using a glob-like syntax as described in the http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[javadoc] for http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[FileSystem.getPathMatcher]. + +See link:#deployment-modes[Deployment Modes] for other configuration parameters available when using the `run` goal in EMBED, FORK or DISTRO modes. + +Here's an example of a pom configuration for the plugin with the `run` goal: + +[source, xml, subs="{sub-order}"] +---- + +... + +... + + org.eclipse.jetty + jetty-maven-plugin + {VERSION} + + + / + ${project.basedir}/src/over/here/web.xml + ${project.basedir}/src/over/here/jetty-env.xml + ${project.basedir}/src/staticfiles + + ${project.basedir}/somewhere/else + + + **/Foo.class + + + + + src/other-resources + + **/*.xml + **/*.properties + + + **/myspecial.xml + **/myspecial.properties + + + + + + +... + +---- + +If, for whatever reason, you cannot run on an unassembled webapp, the goal `run-war` works on assembled webapps. + +[[jetty-run-war-goal]] +==== jetty:run-war + +When invoked at the command line this goal first executes a maven build of your project to the package phase. + +By default it then deploys the resultant war to jetty, but you can use this goal instead to deploy _any_ war file by simply setting the `<webApp><war>` configuration parameter to its location. + +If you set a non-zero `scan`, Jetty watches your `pom.xml` and the WAR file; if either changes, it redeploys the war. +With a zero `scan` interval, redeployment is manual via hitting the `Enter` key. + +The maven build is held up until jetty exits, which is achieved by typing `cntrl-c` at the command line. + +All jetty output is directed to the console. + +===== Configuration + +Configuration parameters are: + +webApp:: +war::: +The location of the built WAR file. This defaults to `${project.build.directory}/${project.build.finalName}.war`. +You can set it to the location of any pre-built war file. +contextPath::: +The context path for your webapp. By default, this is set to `/`. +If using a custom value for this parameter, you should include the leading `/`, example `/mycontext`. +defaultsDescriptor::: +The path to a `webdefault.xml` file that will be applied to your webapp before the `web.xml`. +If you don't supply one, Jetty uses a default file baked into the `jetty-webapp.jar`. +overrideDescriptor::: +The path to a `web.xml` file that Jetty applies after reading your `web.xml`. +You can use this to replace or add configuration. +containerIncludeJarPattern::: +Defaults to `.*/jetty-servlet-api-[^/]*\.jar$|.*javax.servlet.jsp.jstl-[^/]*\.jar|.*taglibs-standard-impl-.*\.jar`. +This is a pattern that is applied to the names of the jars on the container's classpath (ie the classpath of the plugin, not that of the webapp) that should be scanned for fragments, tlds, annotations etc. +This is analogous to the context attribute link:#container-include-jar-pattern[org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern] that is documented link:#container-include-jar-pattern[here]. +You can define extra patterns of jars that will be included in the scan. +webInfIncludeJarPattern::: +Defaults to matching _all_ of the dependency jars for the webapp (ie the equivalent of WEB-INF/lib). +You can make this pattern more restrictive to only match certain jars by using this setter. +This is analogous to the context attribute link:#web-inf-include-jar-pattern[org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern] that is documented link:#web-inf-include-jar-pattern[here]. +tempDirectory::: +The path to a dir that Jetty can use to expand or copy jars and jsp compiles when your webapp is running. +The default is `${project.build.outputDirectory}/tmp`. +contextXml::: +The path to a context xml file that is applied to your webapp AFTER the `webApp` element. +scan:: +The pause in seconds between sweeps of the webapp to check for changes and automatically hot redeploy if any are detected. +*By default this is 0, which disables hot deployment scanning. Redeployment is by hitting `Enter` key.* +A number greater than 0 enables it. +scanTargetPatterns:: +Optional. +List of directories with ant-style include/excludes patterns to specify other files to periodically scan for changes. + +See link:#deployment-modes[Deployment Modes] for other configuration parameters available when using the `run-war` goal in EMBED, FORK or DISTRO modes. + +[[jetty-start-goal]] +==== jetty:start + +This is similar to the `jetty:run` goal, however it is _not_ designed to be run from the command line and does _not_ first execute the build up until the `test-compile` phase to ensure that all necessary classes and files of the webapp have been generated. +It will _not_ scan your project for changes and restart your webapp. +It does _not_ pause maven until jetty is stopped. + +Instead, it is designed to be used with build phase bindings in your pom. +For example to you can have maven start your webapp at the beginning of your tests and stop at the end. + +If the plugin is invoked as part of a multi-module build, any dependencies that are also in the maven reactor are used from their compiled classes. +Prior to jetty-9.4.7 any dependencies needed to be built first. + +Here's an example of using the `pre-integration-test` and `post-integration-test` Maven build phases to trigger the execution and termination of Jetty: + +[source, xml, subs="{sub-order}"] +---- + + org.eclipse.jetty + jetty-maven-plugin + {VERSION} + + 10 + foo + 9999 + + + + start-jetty + pre-integration-test + + start + + + 0 + + + + stop-jetty + post-integration-test + + stop + + + + +---- + +This goal will generate output from jetty into the `target/jetty-start.out` file. + +===== Configuration + +These configuration parameters are available: + +webApp:: +This is an instance of link:{JDURL}/org/eclipse/jetty/maven/plugin/MavenWebAppContext.html[org.eclipse.jetty.maven.plugin.MavenWebAppContext], which is an extension to the class link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.hml[`org.eclipse.jetty.webapp.WebAppContext`]. +You can use any of the setter methods on this object to configure your webapp. +Here are a few of the most useful ones: ++ +contextPath;; +The context path for your webapp. By default, this is set to `/`. +If using a custom value for this parameter, you should include the leading `/`, example `/mycontext`. +descriptor;; +The path to the `web.xml` file for your webapp. +The default is `src/main/webapp/WEB-INF/web.xml`. +defaultsDescriptor;; +The path to a `webdefault.xml` file that will be applied to your webapp before the `web.xml`. +If you don't supply one, Jetty uses a default file baked into the `jetty-webapp.jar`. +overrideDescriptor;; +The path to a `web.xml` file that Jetty applies after reading your `web.xml`. +You can use this to replace or add configuration. +jettyEnvXml;; +Optional. +Location of a `jetty-env.xml` file, which allows you to make JNDI bindings that satisfy `env-entry`, `resource-env-ref`, and `resource-ref` linkages in the `web.xml` that are scoped only to the webapp and not shared with other webapps that you might be deploying at the same time (for example, by using a `jettyXml` file). tempDirectory;; The path to a dir that Jetty can use to expand or copy jars and jsp compiles when your webapp is running. The default is `${project.build.outputDirectory}/tmp`. @@ -333,54 +615,6 @@ You can make this pattern more restrictive to only match certain jars by using t This is analogous to the context attribute link:#web-inf-include-jar-pattern[org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern] that is documented link:#web-inf-include-jar-pattern[here]. contextXml:: The path to a context xml file that is applied to your webapp AFTER the `webApp` element. - -[[jetty-run-goal]] -==== jetty:run - -The `run` goal runs on a webapp that does not have to be built into a WAR. -Instead, Jetty deploys the webapp from its sources. -It looks for the constituent parts of a webapp in the Maven default project locations, although you can override these in the plugin configuration. -For example, by default it looks for: - -* resources in `${project.basedir}/src/main/webapp` -* classes in `${project.build.outputDirectory}` -* `web.xml` in `${project.basedir}/src/main/webapp/WEB-INF/` - -The plugin automatically ensures the classes are rebuilt and up-to-date before deployment. -If you change the source of a class and your IDE automatically compiles it in the background, the plugin picks up the changed class. - -You do not need to assemble the webapp into a WAR, saving time during the development cycle. -Once invoked, you can configure the plugin to run continuously, scanning for changes in the project and automatically performing a hot redeploy when necessary. -Any changes you make are immediately reflected in the running instance of Jetty, letting you quickly jump from coding to testing, rather than going through the cycle of: code, compile, reassemble, redeploy, test. - -____ -[NOTE] -As of Jetty 9.4.7, when using jetty:run in a multi-module build, it is no longer necessary to build each of the modules that form dependencies of the webapp first. -Thus, if your webapp depends on other modules in your project and they are present in the reactor at the same time, jetty will use their compiled classes rather than their jar files from your local maven repository. -____ - -Here is an example, which turns on scanning for changes every ten seconds, and sets the webapp context path to `/test`: - -[source, xml, subs="{sub-order}"] ----- - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - 10 - - /test - - - ----- - -[[configuring-additional-parameters]] -===== Configuration - -In addition to the `webApp` element that is common to most goals, the `jetty:run` goal supports: - classesDirectory:: Location of your compiled classes for the webapp. You should rarely need to set this parameter. @@ -390,475 +624,100 @@ Location of the compiled test classes for your webapp. By default this is `${pro useTestScope:: If true, the classes from `testClassesDirectory` and dependencies of scope "test" are placed first on the classpath. By default this is false. -webAppSourceDirectory:: -By default, this is set to `${project.basedir}/src/main/webapp`. -If your static sources are in a different location, set this parameter accordingly. -jettyEnvXml:: +stopPort:: Optional. -Location of a `jetty-env.xml` file, which allows you to make JNDI bindings that satisfy `env-entry`, `resource-env-ref`, and `resource-ref` linkages in the `web.xml` that are scoped only to the webapp and not shared with other webapps that you might be deploying at the same time (for example, by using a ` jettyConfig` file). -scanTargets:: +Port to listen on for stop commands. +Useful to use in conjunction with the link:#jetty-stop-goal[stop] and link:#jetty-start-goal[start] goals. +stopKey:: Optional. -A list of files and directories to periodically scan in addition to those the plugin automatically scans. -scanTargetPatterns:: -Optional. -If you have a long list of extra files you want scanned, it is more convenient to use pattern matching expressions to specify them instead of enumerating them with the `scanTargetsList` of `scanTargetPatterns`, each consisting of a directory, and including and/or excluding parameters to specify the file matching patterns. -scanClassesPattern:: -Since 9.3.0. -Optional. -Include and exclude patterns that can be applied to the classesDirectory for the purposes of scanning, it does *not* affect the classpath. -If a file or directory is excluded by the patterns then a change in that file (or subtree in the case of a directory) is ignored and will not cause the webapp to redeploy. -Patterns are specified as a relative path using a glob-like syntax as described in the http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[javadoc] for http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[FileSystem.getPathMatcher]. -scanTestClassesPattern:: -Since 9.3.0. -Optional. -Include and exclude patterns that can be applied to the testClassesDirectory for the purposes of scanning, it does *not* affect the classpath. -If a file or directory is excluded by the patterns then a change in that file (or subtree in the case of a directory) is ignored and will not cause the webapp to redeploy. -Patterns are specified as a relative path using a glob-like syntax as described in the http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[javadoc] for http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPathMatcher-java.lang.String-[FileSystem.getPathMatcher]. +Used in conjunction with stopPort for stopping jetty. +Useful to use in conjunction with the link:#jetty-stop-goal[stop] and link:#jetty-start-goal[start] goals. -Here's an example: +These additional configuration parameters are available when running in `FORK` or `DISTRO` mode: -[source, xml, subs="{sub-order}"] ----- - -... - -... - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - ${project.basedir}/src/staticfiles - - / - ${project.basedir}/src/over/here/web.xml - ${project.basedir}/src/over/here/jetty-env.xml - - ${project.basedir}/somewhere/else - - - **/Foo.class - - - - src/mydir - src/myfile.txt - - - - src/other-resources - - **/*.xml - **/*.properties - - - **/myspecial.xml - **/myspecial.properties - - - - - - -... - ----- +maxChildStartChecks:: +Default is `10`. +This is maximum number of times the parent process checks to see if the forked jetty process has started correctly +maxChildStartCheckMs:: +Default is `200`. +This is the time in milliseconds between checks on the startup of the forked jetty process. -If, for whatever reason, you cannot run on an unassembled webapp, the goals `run-war` and `run-exploded` work on unassembled webapps. -[[running-assembled-webapp-as-war]] -==== jetty:run-war +[[jetty-start-war-goal]] +==== jetty:start-war -This goal first packages your webapp as a WAR file and then deploys it to Jetty. -If you set a non-zero `scanInterval`, Jetty watches your `pom.xml` and the WAR file; if either changes, it redeploys the war. +Similarly to the `jetty:start` goal, `jetty:start-war` is designed to be bound to build lifecycle phases in your pom. + +It will _not_ scan your project for changes and restart your webapp. +It does _not_ pause maven until jetty is stopped. + +By default, if your pom is for a webapp project, it will deploy the war file for the project to jetty. +However, like the `jetty:run-war` project, you can nominate any war file to deploy by defining its location in the `<webApp><war>` parameter. + +If the plugin is invoked as part of a multi-module build, any dependencies that are also in the maven reactor are used from their compiled classes. +Prior to jetty-9.4.7 any dependencies needed to be built first. + +This goal will generate output from jetty into the `target/jetty-start-war.out` file. -[[configuring-war]] ===== Configuration -war:: +These configuration parameters are available: + +webApp:: +war::: The location of the built WAR file. This defaults to `${project.build.directory}/${project.build.finalName}.war`. -If this is not sufficient, set it to your custom location. - -Here's how to set it: - -[source, xml, subs="{sub-order}"] ----- - -... - -... - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - ${project.basedir}/target/mycustom.war - - - - ----- - -[[running-assembled-webapp-as-expanded-war]] -==== jetty:run-exploded - -The run-exploded goal first assembles your webapp into an exploded WAR file and then deploys it to Jetty. -If you set a non-zero `scanInterval`, Jetty watches your `pom.xml,`WEB-INF/lib`, `WEB-INF/` and `WEB-INF/web.xml` for changes and redeploys when necessary. - -[[configuring-exploded-war]] -===== Configuration - -war:: -The location of the exploded WAR. -This defaults to `${project.build.directory}/${project.build.finalName}`, but you can override the default by setting this parameter. - -Here's how to set it: - -[source, xml, subs="{sub-order}"] ----- - -... - -... - - org.eclipse.jetty - maven-jetty-plugin - {VERSION} - - ${project.basedir}/target/myfunkywebapp - - - - ----- - -[[deploy-war-running-pre-assembled-war]] -==== jetty:deploy-war - -This is basically the same as `jetty:run-war`, but without assembling the WAR of the current module - you can nominate the location of any war to run. -Unlike `run-war`, the phase in which this plugin executes is not bound to the "package" phase - you may bind it to any phase to use it. - -===== Configuration - -war:: -The location of the WAR file. This defaults to `${project.build.directory}/${project.build.finalName}`, but you can override the default by setting this parameter. -daemon:: -If true, this plugin will start Jetty but let the build continue. -This is useful if you want to start jetty as an execution binding in a particular phase and then stop it in another. -Alternatively, you can set this parameter to false, in which case Jetty will block and you will need to use a ctrl-c to stop it. - -Here's the configuration: - -[source, xml, subs="{sub-order}"] ----- - - -... - -... - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - /opt/special/some-app.war - alpha - 9099 - - - - start-jetty - test-compile - - deploy-war - - - - stop-jetty - test - - stop - - - - - - - - ----- - -[[jetty-run-forked-goal]] -==== jetty:run-forked - -This goal allows you to start the webapp in a new JVM, optionally passing arguments to that new JVM. -This goal supports mostly the same configuration parameters as the `jetty:run` goal with a couple of extras to help configure the forked process. -Unlike the `jetty:run` goal, the `jetty:run-forked` goal will not scan the webapp for changes and redeploy. - -===== Configuration - -The available configuration parameters - in addition to those for the `jetty:run` goal - are: - -jvmArgs:: +You can set it to the location of any pre-built war file. +contextPath::: +The context path for your webapp. By default, this is set to `/`. +If using a custom value for this parameter, you should include the leading `/`, example `/mycontext`. +defaultsDescriptor::: +The path to a `webdefault.xml` file that will be applied to your webapp before the `web.xml`. +If you don't supply one, Jetty uses a default file baked into the `jetty-webapp.jar`. +overrideDescriptor::: +The path to a `web.xml` file that Jetty applies after reading your `web.xml`. +You can use this to replace or add configuration. +containerIncludeJarPattern::: +Defaults to `.*/jetty-servlet-api-[^/]*\.jar$|.*javax.servlet.jsp.jstl-[^/]*\.jar|.*taglibs-standard-impl-.*\.jar`. +This is a pattern that is applied to the names of the jars on the container's classpath (ie the classpath of the plugin, not that of the webapp) that should be scanned for fragments, tlds, annotations etc. +This is analogous to the context attribute link:#container-include-jar-pattern[org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern] that is documented link:#container-include-jar-pattern[here]. +You can define extra patterns of jars that will be included in the scan. +webInfIncludeJarPattern::: +Defaults to matching _all_ of the dependency jars for the webapp (ie the equivalent of WEB-INF/lib). +You can make this pattern more restrictive to only match certain jars by using this setter. +This is analogous to the context attribute link:#web-inf-include-jar-pattern[org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern] that is documented link:#web-inf-include-jar-pattern[here]. +tempDirectory::: +The path to a dir that Jetty can use to expand or copy jars and jsp compiles when your webapp is running. +The default is `${project.build.outputDirectory}/tmp`. +contextXml::: +The path to a context xml file that is applied to your webapp AFTER the `webApp` element. +stopPort:: Optional. -A string representing arbitrary arguments to pass to the forked JVM. -env:: +Port to listen on for stop commands. +Useful to use in conjunction with the link:#jetty-stop-goal[stop]. +stopKey:: Optional. -Map of key/value pairs to pass as environment to the forked JVM. -waitForChild:: -Default is `true`. -This causes the parent process to wait for the forked process to exit. -In this case you can use `ctrl-c` to terminate both processes. -It is more useful to set it to `false`, in which case the parent process terminates whilst leaving the child process running. -You use the `jetty:stop` goal to stop the child process. -In the case where `waitForChild` is `false`, the output from the child process is written to `target/jetty.out`. -maxChildChecks:: -Default is `50`. -This is maximum number of times the parent process checks to see if the child process has started. -Only relevant if `waitForChild` is `false`. -maxChildCheckInterval:: -Default is `100`. -This is the time in milliseconds between checks to see if the child process has started. -Only relevant if `waitForChild` is `false`. -forkWebXml:: -Default is `target/fork-web.xml`. -This is the name of the file into which jetty generates the effective web.xml for use by the child process. -javaPath:: -Default will be your `${java.home}/bin/java` -This the java executable used to start the child process +Used in conjunction with stopPort for stopping jetty. +Useful to use in conjunction with the link:#jetty-stop-goal[stop]. -The following `jetty:run` parameters are NOT applicable: +These additional configuration parameters are available when running in FORK or DISTRO mode: -* *scanTargets* -* *scanTargetPatterns* -* *scanClassesPattern* -* *scanTestClassesPattern* +maxChildStartChecks:: +Default is `10`. +This is maximum number of times the parent process checks to see if the forked jetty process has started correctly +maxChildStartCheckMs:: +Default is `200`. +This is the time in milliseconds between checks on the startup of the forked jetty process. -Some of the container configuration parameters are *NOT* available with this goal: - -scanIntervalSeconds:: -Not supported. -The forked jetty will not monitor and redeploy the webapp. -reload:: -Not supported. -The forked jetty will not redeploy the webapp. -httpConnector:: -Not supported. -To define custom connectors use a jetty xml file instead. -loginServices:: -Not supported. -To define LoginServices use a jetty xml or context xml file instead. -requestLog:: -Not supported. -To define a RequestLog setup, use a jetty xml or context xml file instead. -systemProperties:: -Not supported. -Use the `jvmArgs` parameter to pass system properties to the forked process. - -To deploy your unassembled web app to Jetty running in a new JVM: - -[source, screen, subs="{sub-order}"] -.... -mvn jetty:run-forked -.... - -Jetty continues to execute until you either: - -* Press `ctrl-c` in the terminal window to stop the plugin, which also stops the forked JVM (only if you started with `waitForChild=true`) -* Use `jetty:stop` to stop the forked JVM, which also stops the plugin. - -____ -[NOTE] -If you want to set a custom port for the Jetty connector you need to specify it in a `jetty xml` file rather than setting the connector and port tags. -You can specify the location of the `jetty.xml` using the `jettyXml` parameter. -____ - -[[jetty-run-distro-goal]] -==== jetty:run-distro - -Introduced in Jetty 9.4.8, this goal allows you to execute your unassembled webapp in a local distribution of Jetty. -This can be useful if your webapp requires a highly customized environment in which to run. -If your webapp is designed to run in the jetty distribution in production, then this goal is the closest approximation to that environment. - -Similar to the `jetty:run-forked` goal, this goal will fork a child process in which to execute your webapp in the distro. - -===== Configuration - -The configuration parameters are mostly the same as the `jetty:run` goal (although see below for some exceptions), with the addition of: - -jettyBase:: -Optional. -The location of an existing jetty base directory to use to deploy the webapp. -The existing base will be copied to the `target/` directory before the webapp is deployed. -If there is no existing jetty base, a fresh one will be made in `target/jetty-base`. -jettyHome:: -Optional. -The location of an existing unpacked jetty distribution. -If one does not exist, a fresh jetty distribution will be downloaded from maven and installed to the `target` directory. -jettyProperties:: -Optional. -An array of jetty properties to specify on the command line for the child process. -jvmArgs:: -Optional. -A string representing arguments that should be passed to the jvm of the child process. -modules:: -Optional. -An array of names of jetty modules that the jetty child process will activate. -waitForChild:: -Default is `true`. -Like jetty:run-forked, if `true`, the parent process will wait for the child to exit and echo all of its output to the parent's stdout/stderr. -In that case you can terminate both processes with a `cntrl-c`. -If `false`, the parent does not wait for the child to finish, and the child will write all of its output to `target/jetty.out`. -To stop the asynchronously executing child process you can use `jetty:stop`. -maxChildChecks:: -Default value 10. -This is the maximum number of times the parent will check to see if the child started correctly when `waitForChild` is `false`. -maxChildCheckInterval:: -Default value 100. -This is the interval in milliseconds between checks to see if the child started correctly. -Only applicable if `waitForChild` is `false`. -javaPath:: -Default will be your `${java.home}/bin/java` -This the java executable used to start the child process - -____ -[NOTE] -Use the `modules` parameter to configure the Jetty distribution appropriately rather than using jetty artifacts as `plugin dependencies`. -____ - -The following `jetty:run` parameters are *NOT* applicable to this goal: - -* *scanTargets* -* *scanTargetPatterns* -* *scanClassesPattern* -* *scanTestClassesPattern* - - -The following container configuration options are *NOT* applicable for this goal: - -scanIntervalSeconds:: -Not supported. -This goal will not monitor and redeploy the webapp. -reload:: -Not supported. -This goal will not redeploy the webapp. -httpConnector:: -Not supported. -Use the `modules` parameter to enable appropriate modules, or the `jettyBase` parameter to point to an appropriately configured jetty base. -loginServices:: -Not supported. -Use the `modules` parameter to enable appropriate modules, or the `jettyBase` parameter to point to an appropriately configured jetty base. -requestLog:: -Not supported. -Use the `modules` parameter to enable appropriate modules, or the `jettyBase` parameter to point to an appropriately configured jetty base. -systemProperties:: -Not supported. -Use the `jvmArgs` parameter to pass system properties to the forked process. - -Here's an example of using the configuration parameters: -[source, xml, subs="{sub-order}"] ----- - - -... - -... - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - alpha - 9099 - /my/existing/jetty-base - /some/existing/context.xml - true - - apache-jsp - apache-jstl - jmx - - - jetty.server.dumpAfterStart=true - - -Dorg.eclipse.jetty.webapp.LEVEL=DEBUG - - /mypath - - - -... - - - ----- - -____ -[NOTE] -When defining modules for this goal, use the standard link:#startup-modules[Jetty module] names and not the name of the related Jetty sub-project. -For example, in the configuration above support for JMX is configured by adding the `jmx` Jetty module and not the `jetty-jmx` sub-project. -____ - - -To deploy your unassembled web app to jetty running as a local distribution: - -[source, screen, subs="{sub-order}"] -.... -mvn jetty:run-distro -.... - - -[[jetty-start-goal]] -==== jetty:start - -This goal is for use with an execution binding in your `pom.xml`. -It is similar to the `jetty:run` goal, however it does NOT first execute the build up until the `test-compile` phase to ensure that all necessary classes and files of the webapp have been generated. -This is most useful when you want to control the start and stop of Jetty via execution bindings in your `pom.xml`. - -For example, you can configure the plugin to start your webapp at the beginning of your unit tests and stop at the end. -To do this, you need to set up a couple of `execution` scenarios for the Jetty plugin. -You use the `pre-integration-test` and `post-integration-test` Maven build phases to trigger the execution and termination of Jetty: - -[source, xml, subs="{sub-order}"] ----- - - org.eclipse.jetty - jetty-maven-plugin - {VERSION} - - 10 - foo - 9999 - - - - start-jetty - pre-integration-test - - start - - - 0 - - - - stop-jetty - post-integration-test - - stop - - - - ----- [[jetty-stop-goal]] ==== jetty:stop -The stop goal stops a running instance of Jetty. +The stop goal stops a FORK or DISTRO mode running instance of Jetty. To use it, you need to configure the plugin with a special port number and key. That same port number and key will also be used by the other goals that start jetty. +===== Configuration + stopPort:: A port number for Jetty to listen on to receive a stop command to cause it to shutdown. stopKey:: @@ -896,22 +755,52 @@ mvn jetty:stop The `stopPort` must be free on the machine you are running on. If this is not the case, you will get an "Address already in use" error message after the "Started ServerConnector ..." message. -[[jetty-effective-web-xml]] +[[jetty-effective-web-xml-goal]] ==== jetty:effective-web-xml This goal calculates a synthetic `web.xml` (the "effective web.xml") according to the rules of the Servlet Specification taking into account all sources of discoverable configuration of web components in your application: descriptors (`webdefault.xml`, `web.xml`, `web-fragment.xml`s, `web-override.xml`) and discovered annotations (`@WebServlet`, `@WebFilter`, `@WebListener`). -Note that no programmatic declarations of servlets, filters and listeners can be taken into account. -The effective `web.xml` from these combined sources is generated and displayed as maven log output. +No programmatic declarations of servlets, filters and listeners can be taken into account. + +You can calculate the effective web.xml for any pre-built war file by setting the `<webApp><war>` parameter, or you can calculate it for the unassembled webapp by setting all of the usual `<webApp>` parameters as for `jetty:run`. + Other useful information about your webapp that is produced as part of the analysis is also stored as context parameters in the effective-web.xml. The effective-web.xml can be used in conjunction with the link:#quickstart-webapp[Quickstart] feature to quickly start your webapp (note that Quickstart is not appropriate for the mvn jetty goals). -The following configuration parameters allow you to save the file: +The effective web.xml from these combined sources is generated into a file, which by default is `target/effective-web.xml`, but can be changed by setting the `effectiveWebXml` configuration parameter. + +===== Configuration -deleteOnExit:: -By default this is `true`. -If set to `false`, the effective web.xml is generated into a file called `effective-web.xml` in the build `target` directory. effectiveWebXml:: The full path name of a file into which you would like the effective web xml generated. +webApp:: +war::: +The location of the built WAR file. This defaults to `${project.build.directory}/${project.build.finalName}.war`. +You can set it to the location of any pre-built war file. +Or you can leave it blank and set up the other `webApp` parameters as per link:#jetty-run-goal[jetty:run], as well as the `webAppSourceDirectory`, `classes` and `testClasses` parameters. +contextPath::: +The context path for your webapp. By default, this is set to `/`. +If using a custom value for this parameter, you should include the leading `/`, example `/mycontext`. +defaultsDescriptor::: +The path to a `webdefault.xml` file that will be applied to your webapp before the `web.xml`. +If you don't supply one, Jetty uses a default file baked into the `jetty-webapp.jar`. +overrideDescriptor::: +The path to a `web.xml` file that Jetty applies after reading your `web.xml`. +You can use this to replace or add configuration. +containerIncludeJarPattern::: +Defaults to `.*/jetty-servlet-api-[^/]*\.jar$|.*javax.servlet.jsp.jstl-[^/]*\.jar|.*taglibs-standard-impl-.*\.jar`. +This is a pattern that is applied to the names of the jars on the container's classpath (ie the classpath of the plugin, not that of the webapp) that should be scanned for fragments, tlds, annotations etc. +This is analogous to the context attribute link:#container-include-jar-pattern[org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern] that is documented link:#container-include-jar-pattern[here]. +You can define extra patterns of jars that will be included in the scan. +webInfIncludeJarPattern::: +Defaults to matching _all_ of the dependency jars for the webapp (ie the equivalent of WEB-INF/lib). +You can make this pattern more restrictive to only match certain jars by using this setter. +This is analogous to the context attribute link:#web-inf-include-jar-pattern[org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern] that is documented link:#web-inf-include-jar-pattern[here]. +tempDirectory::: +The path to a dir that Jetty can use to expand or copy jars and jsp compiles when your webapp is running. +The default is `${project.build.outputDirectory}/tmp`. +contextXml::: +The path to a context xml file that is applied to your webapp AFTER the `webApp` element. + You can also generate the origin of each element into the effective web.xml file. The origin is either a descriptor eg web.xml,web-fragment.xml,override-web.xml file, or an annotation eg @WebServlet. @@ -936,13 +825,13 @@ False by default. If true, will force the generation of the originAttribute onto [[using-overlaid-wars]] ==== Using Overlaid wars -If your webapp depends on other war files, the link:#jetty-run-goal[jetty:run] and link:#jetty-run-forked-goal[jetty:run-forked] goals are able to merge resources from all of them. +If your webapp depends on other war files, the link:#jetty-run-goal[jetty:run] and link:#jetty-start-goal[jetty:start] goals are able to merge resources from all of them. It can do so based on the settings of the http://maven.apache.org/plugins/maven-war-plugin/[maven-war-plugin], or if your project does not use the http://maven.apache.org/plugins/maven-war-plugin/[maven-war-plugin] to handle the overlays, it can fall back to a simple algorithm to determine the ordering of resources. ===== With maven-war-plugin The maven-war-plugin has a rich set of capabilities for merging resources. -The `jetty:run` and `jetty:run-forked` goals are able to interpret most of them and apply them during execution of your unassembled webapp. +The `jetty:run` and `jetty:start` goals are able to interpret most of them and apply them during execution of your unassembled webapp. This is probably best seen by looking at a concrete example. Suppose your webapp depends on the following wars: @@ -1020,7 +909,7 @@ Similarly as `baz.jsp` is excluded, a request for it would result in a 404 error ===== Without maven-war-plugin The algorithm is fairly simple, is based on the ordering of declaration of the dependent wars, and does not support exclusions. -The configuration parameter `` (see the section on link:#configuring-your-webapp[Configuring Your Webapp] for more information) can be used to control whether your webapp's resources are placed first or last on the resource path at runtime. +The configuration parameter `` (see for example link:#jetty-run-goal[jetty:run] for more information) can be used to control whether your webapp's resources are placed first or last on the resource path at runtime. For example, suppose our webapp depends on these two wars: @@ -1082,7 +971,7 @@ Here's an example of setting up the HashLoginService for a webapp: jetty-maven-plugin {VERSION} - 10 + 10 /test @@ -1135,16 +1024,16 @@ Putting the configuration in webapp A's `pom.xml`: jetty-maven-plugin {VERSION} - 10 + 10 /test - + ${project.basedir}../../B.war /B - + ${project.basedir}../../C.war /C @@ -1155,7 +1044,7 @@ Putting the configuration in webapp A's `pom.xml`: ____ [IMPORTANT] -If the `ContextHandler` you are deploying is a webapp, it is *essential* that you use an `org.eclipse.jetty.maven.plugin.JettyWebAppContext` instance rather than a standard `org.eclipse.jetty.webapp.WebAppContext` instance. +If the `ContextHandler` you are deploying is a webapp, it is *essential* that you use an `org.eclipse.jetty.maven.plugin.MavenWebAppContext` instance rather than a standard `org.eclipse.jetty.webapp.WebAppContext` instance. Only the former will allow the webapp to function correctly in the maven environment. ____ @@ -1167,7 +1056,7 @@ Copy the `jetty.xml` file from the Jetty distribution, and then add WebAppContex - + /B ../../B.war @@ -1175,7 +1064,7 @@ Copy the `jetty.xml` file from the Jetty distribution, and then add WebAppContex - + /C ../../C.war @@ -1193,7 +1082,7 @@ Then configure the location of this `jetty.xml` file into webapp A's jetty plugi jetty-maven-plugin {VERSION} - 10 + 10 /test @@ -1206,10 +1095,6 @@ Then configure the location of this `jetty.xml` file into webapp A's jetty plugi For either of these solutions, the other webapps must already have been built, and they are not automatically monitored for changes. You can refer either to the packed WAR file of the pre-built webapps or to their expanded equivalents. -===== With jetty:run-distro - -Simply configure a jetty base that contains all of the other prebuilt webapps you wish to deploy. - [[setting-system-properties]] ==== Setting System Properties @@ -1245,7 +1130,8 @@ In the latter case, you can use the link:http://www.mojohaus.org/[maven properti ____ [NOTE] -If a System property is already set (for example, from the command line or by the JVM itself), then by default these configured properties *DO NOT* override them (see below for use of the parameter). +If a System property is already set (for example, from the command line or by the JVM itself), then by default these configured properties *DO NOT* override them. +However, they can override system properties set from a file instead, see link:#specifying-properties-in-file[specifying system properties in a file]. ____ [[specifying-properties-in-pom]] @@ -1260,10 +1146,7 @@ Here's an example of how to specify System properties in the POM: jetty-maven-plugin - - fooprop - 222 - + 222 /test @@ -1273,28 +1156,6 @@ Here's an example of how to specify System properties in the POM: ---- -To change the default behavior so that these system properties override those on the command line, use the `` parameter: - -[source, xml, subs="{sub-order}"] ----- - - org.eclipse.jetty - jetty-maven-plugin - - - true - - fooprop - 222 - - - - /test - - - ----- - [[specifying-properties-in-file]] ===== Specifying System Properties in a File diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-scanning.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-scanning.adoc index 6d36dd9d497..4bfa3e5ec7f 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-scanning.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/maven/jetty-maven-scanning.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-maven-scanning]] @@ -34,9 +34,9 @@ The files that are scanned depend on the goal being executed. * * * -* or /WEB-INF/web.xml -* or /WEB-INF/jetty-web.xml -* /WEB-INF/jetty-web.xml +* or src/main/webapp/WEB-INF/web.xml +* or src/main/webapp/WEB-INF/jetty-web.xml +* /WEB-INF/jetty-web.xml * * * any link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#setDefaultsDescriptor%28java.lang.String%29[defaultsDescriptor] for the webapp @@ -49,25 +49,4 @@ The files that are scanned depend on the goal being executed. * pom.xml * -|link:#running-assembled-webapp-as-expanded-war[jetty:run-exploded] -| - -* pom.xml -* /WEB-INF/web.xml -* /WEB-INF/jetty-web.xml -* /WEB-INF/jetty-env.xml -* /WEB-INF/classes -* /WEB-INF/lib - -|link:#deploy-war-running-pre-assembled-war[jetty:deploy-war] -| - -* pom.xml -* - -|link:#jetty-run-forked-goal[jetty:run-forked] | -|link:#jetty-effective-web-xml[jetty:effective-web-xml] | -|link:#jetty-run-distro-goal[jetty:run-distro] | -|link:#jetty-start-goal[jetty:start] | -|link:#jetty-stop-goal[jetty:stop] | |======================================================================= diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/chapter.adoc index 2e72902f7f8..64f06c7d393 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[platforms]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/cloudfoundry.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/cloudfoundry.adoc index cb6f02928f8..878aee4b40c 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/cloudfoundry.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/cloudfoundry.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[cloudfoundry]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/elastic-beanstalk.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/elastic-beanstalk.adoc index ed9031146ef..c25d76e4b63 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/elastic-beanstalk.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/elastic-beanstalk.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[elastic-beanstalk]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/fedora.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/fedora.adoc index a0385fd9221..7ba4f30f7d8 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/fedora.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/fedora.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[fedora]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/jelastic.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/jelastic.adoc index b02da5f090a..113c19159ab 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/jelastic.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/jelastic.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jelastic]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/ubuntu.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/ubuntu.adoc index abbe0937599..0e6b8cad65f 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/ubuntu.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/platforms/ubuntu.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[ubuntu]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/server.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/server.adoc index e75b9de54a3..82d815d7d1b 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/server.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/server.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[server]] @@ -26,7 +26,6 @@ include::handlers/chapter.adoc[] include::websockets/intro/chapter.adoc[] include::websockets/jetty/chapter.adoc[] include::ant/chapter.adoc[] -include::continuations/chapter.adoc[] include::frameworks/chapter.adoc[] include::architecture/chapter.adoc[] include::platforms/chapter.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/chapter.adoc index 62f78a632d2..97cf626cb38 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[troubleshooting]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/preventing-memory-leaks.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/preventing-memory-leaks.adoc index c9169ba4840..fe467e7c85d 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/preventing-memory-leaks.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/preventing-memory-leaks.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[preventing-memory-leaks]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/security-reports.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/security-reports.adoc index 658bfd190a5..cba06c71ed2 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/security-reports.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/security-reports.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[security-reports]] @@ -28,6 +28,33 @@ If you would like to report a security issue please follow these link:#security- |======================================================================= |yyyy/mm/dd |ID |Exploitable |Severity |Affects |Fixed Version |Comment +|2019/08/13 |CVE-2019-9518 |Med |Med |< = 9.4.20 |9.4.21 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9518[Some HTTP/2 implementations are vulnerable to a flood of empty frames, potentially leading to a denial of service.] + +|2019/08/13 |CVE-2019-9516 |Med |Med |< = 9.4.20 |9.4.21 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9516[Some HTTP/2 implementations are vulnerable to a header leak, potentially leading to a denial of service.] + +|2019/08/13 |CVE-2019-9515 |Med |Med |< = 9.4.20 |9.4.21 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9515[Some HTTP/2 implementations are vulnerable to a settings flood, potentially leading to a denial of service when an attacker sent a stream of SETTINGS frames to the peer.] + +|2019/08/13 |CVE-2019-9514 |Med |Med |< = 9.4.20 |9.4.21 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9514[Some HTTP/2 implementations are vulnerable to a reset flood, potentially leading to a denial of service.] + +|2019/08/13 |CVE-2019-9512 |Low |Low |< = 9.4.20 |9.4.21 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9512[Some HTTP/2 implementations are vulnerable to ping floods which could lead to a denial of service.] + +|2019/08/13 |CVE-2019-9511 |Low |Low |< = 9.4.20 |9.4.21 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9511[Some HTTP/2 implementations are vulnerable to window size manipulation and stream prioritization manipulation which could lead to a denial of service.] + +|2019/04/11 |CVE-2019-10247 |Med |Med |< = 9.4.16 |9.2.28, 9.3.27, 9.4.17 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10247[If no webapp was mounted to the root namespace and a 404 was encountered, an HTML page would be generated displaying the fully qualified base resource location for each context.] + +|2019/04/11 |CVE-2019-10246 |High |High |< = 9.4.16 |9.2.28, 9.3.27, 9.4.17 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10246[Use of `DefaultServlet` or `ResourceHandler` with indexing was vulnerable to XSS behaviors to expose the directory listing on Windows operating systems.] + +|2019/04/11 |CVE-2019-10241 |High |High |< = 9.4.15 |9.2.27, 9.3.26, 9.4.16 +|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10241[Use of `DefaultServlet` or `ResourceHandler` with indexing was vulnerable to XSS behaviors to expose the directory listing.] + |2018/06/25 |CVE-2018-12538 |High |High |>= 9.4.0, < = 9.4.8 |9.4.9 |https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12538[`HttpSessions` present specifically in the FileSystem’s storage could be hijacked/accessed by an unauthorized user.] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/slow-deployment.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/slow-deployment.adoc index 7f230c33c2b..92b206468fe 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/slow-deployment.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/slow-deployment.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[troubleshooting-slow-deployment]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-locked-files.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-locked-files.adoc index a1adf7988c4..9f440eb270b 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-locked-files.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-locked-files.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[troubleshooting-locked-files-on-windows]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-zip-exceptions.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-zip-exceptions.adoc index 8e6acf07062..773c4b1d416 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-zip-exceptions.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/troubleshooting-zip-exceptions.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[troubleshooting-zip-exceptions]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/watchservice.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/watchservice.adoc index 369c361ab79..5fed4f0ff05 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/watchservice.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/troubleshooting/watchservice.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[watchservice]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/chapter.adoc deleted file mode 100644 index 53641d2b33a..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/chapter.adoc +++ /dev/null @@ -1,22 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -[[upgrading-jetty]] -== Upgrading Jetty - -include::upgrading-from-jetty-9.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/sample.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/sample.adoc deleted file mode 100644 index d11b705f235..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/sample.adoc +++ /dev/null @@ -1,25 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -= Sample Title - -This is a sample paragraph. - -== Sample Subsection - -More sample text. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/upgrading-from-jetty-9.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/upgrading-from-jetty-9.adoc deleted file mode 100644 index f3045c2849f..00000000000 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/upgrading-from-jetty-9.adoc +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -=== Upgrading from Jetty 9.x to Jetty 10.0.x - -The purpose of this guide is to assist users migrating from Jetty 9 to 10. -It is not comprehensive, but covers many of the major changes included in the release that may prove as problem areas for users. - -//TODO - Make note of any specific required Java versions. - -==== Changes to Websocket - -==== `javax.mail` and `javax.transaction` - -Both `javax.mail` and `javax.transaction` have been removed from the Jetty Distribution in Jetty 10. -If you require these jars, you will need to enable the `ext` link:#startup-modules[module] and copy the files to your `$JETTY_BASE/lib/ext` directory. - -==== Removed Classes - -//TODO - Insert major removed/refactored classes from Jetty-9.x.x to Jetty-10.0.x - -==== Module Changes in Jetty 10.0 diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/intro/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/intro/chapter.adoc index f5783ef1c3b..defa91f5730 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/intro/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/intro/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[websocket-intro]] @@ -107,18 +107,18 @@ To enable Websocket, you need to enable the `websocket` link:#enabling-modules[m Once this module is enabled for your Jetty base, it will apply to all webapps deployed to that base. If you want to be more selective about which webapps use Websocket, then you can: -Disable JSR-356 for a particular webapp::: - You can disable jsr-356 for a particular webapp by setting the link:#context_attributes[context attribute] `org.eclipse.jetty.websocket.jsr356` to `false`. +Disable Websocket for a particular webapp::: + You can disable jsr-356 for a particular webapp by setting the link:#context_attributes[context attribute] `org.eclipse.jetty.websocket.javax` to `false`. This will mean that websockets are not available to your webapp, however deployment time scanning for websocket-related classes such as endpoints will still occur. This can be a significant impost if your webapp contains a lot of classes and/or jar files. To completely disable websockets and avoid all setup costs associated with it for a particular webapp, use instead the context attribute `org.eclipse.jetty.containerInitializerExclusionPattern`, described next, which allows you to exclude the websocket ServletContainerInitializer that causes the scanning. -Completely disable jsr-356 for a particular webapp::: - Set the `org.eclipse.jetty.containerInitializerExclusionPattern` link:#context_attributes[context attribute] to include `org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer`. +Completely disable Websocket for a particular webapp::: + Set the `org.eclipse.jetty.containerInitializerExclusionPattern` link:#context_attributes[context attribute] to include `org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer`. Here's an example of doing this in code, although you can do the link:#intro-jetty-configuration-webapps[same in xml]: + [source, java, subs="{sub-order}"] ---- WebAppContext context = new WebAppContext(); -context.setAttribute("org.eclipse.jetty.containerInitializerExclusionPattern", - "org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer|com.acme.*"); +context.setAttribute("org.eclipse.jetty.containerInitializerExclusionPattern", + "org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer|com.acme.*"); ---- diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/chapter.adoc index d9c99b3f54d..6f4aff1ac69 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[websocket-java]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-client-api.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-client-api.adoc index 169ca4eb8b1..7292c1c0170 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-client-api.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-client-api.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[java-websocket-client-api]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-server-api.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-server-api.adoc index 6890f3997d4..6333294bed8 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-server-api.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/java/java-websocket-server-api.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[java-websocket-server-api]] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/chapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/chapter.adoc index 177c3564d37..276d204d2a5 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[websocket-jetty]] @@ -21,12 +21,12 @@ These pages are works in progress that have not been moved to their respective sections yet. -include::jetty-websocket-api.adoc[] -include::jetty-websocket-api-events.adoc[] -include::jetty-websocket-api-session.adoc[] -include::jetty-websocket-api-send-message.adoc[] -include::jetty-websocket-api-annotations.adoc[] -include::jetty-websocket-api-listener.adoc[] -include::jetty-websocket-api-adapter.adoc[] -include::jetty-websocket-server-api.adoc[] -include::jetty-websocket-client-api.adoc[] +include::websocket-jetty-api.adoc[] +include::websocket-jetty-api-events.adoc[] +include::websocket-jetty-api-session.adoc[] +include::websocket-jetty-api-send-message.adoc[] +include::websocket-jetty-api-annotations.adoc[] +include::websocket-jetty-api-listener.adoc[] +include::websocket-jetty-api-adapter.adoc[] +include::websocket-jetty-server-api.adoc[] +include::websocket-jetty-client-api.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-adapter.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-adapter.adoc index 369ac5d7430..38e56d77790 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-adapter.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-adapter.adoc @@ -1,29 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api-adapter]] +[[websocket-jetty-api-adapter]] === Using the WebSocketAdapter A basic adapter for managing the Session object on the WebSocketListener. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java[] ---- This is a convenience class to make using the WebSocketListener easier, and provides some useful methods to check the state of the Session. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-annotations.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-annotations.adoc index 752044d871b..4f5142012c7 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-annotations.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-annotations.adoc @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api-annotations]] +[[websocket-jetty-api-annotations]] === Using WebSocket Annotations The most basic form of WebSocket is a marked up POJO with annotations @@ -24,7 +24,7 @@ provided by the Jetty WebSocket API. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java[] ---- The above example is a simple WebSocket echo endpoint that will echo back any TEXT messages it receives. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-events.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-events.adoc index 0352059229b..b7a8434453b 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-events.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-events.adoc @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api-events]] +[[websocket-jetty-api-events]] === WebSocket Events Every WebSocket can receive various events: diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-listener.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-listener.adoc index e2ebc802a2f..47bd5e90578 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-listener.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-listener.adoc @@ -1,29 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api-listener]] +[[websocket-jetty-api-listener]] === Using WebSocketListener The basic form of a WebSocket using the link:{JDURL}/org/eclipse/jetty/websocket/api/WebSocketListener.html[`org.eclipse.jetty.websocket.api.WebSocketListener`] for incoming events. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java[] ---- This is by far the most basic and best performing (speed and memory wise) WebSocket implementation you can create. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-send-message.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-send-message.adoc index a8b6e11957f..d90be9b0107 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-send-message.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-send-message.adoc @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api-send-message]] +[[websocket-jetty-api-send-message]] === Send Messages to Remote Endpoint The most important feature of the Session is access to the link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html[`org.eclipse.jetty.websocket.api.RemoteEndpoint`] needed to send messages. @@ -115,10 +115,54 @@ catch (IOException e) How to send a Text message in 2 parts, using the partial message support in RemoteEndpoint. This will block until each part of the message is sent, possibly throwing an IOException if unable to send the partial message. +[[websocket-async-send]] +==== Async Send Message + +There are also four (4) async send message methods available: + +* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendBytes(java.nio.ByteBuffer,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendBytes(ByteBuffer message, WriteCallback callback)`] +* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendPartialBytes(java.nio.ByteBuffer,boolean,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendPartialBytes(ByteBuffer message, boolean isLast, WriteCallback callback)`] +* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendString(java.lang.String,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendString(String message, WriteCallback callback)`] +* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendPartialString(java.lang.String,boolean,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendPartialString(String message, boolean isLast, WriteCallback callback)`] + +All these async send methods use `WriteCallback`, which allows you to be notified when the write either succeeds or fails. + +[source, java, subs="{sub-order}"] +---- +WriteCallback callback = new WriteCallback() +{ + @Override + public void writeSuccess() + { + // Notification that the write has succeeded. + } + + @Override + public void writeFailed(Throwable x) + { + // Notification that the write has failed. + t.printStackTrace(); + } +}; +---- + +The async send methods can be used in a similar way to the blocking send methods, however the method will return before the message is transmitted, and you are notified of the final result of the message transmission through the `WriteCallback`. +The static `WriteCallback.NOOP` can be used to do nothing on success / failure of the callback. + +[source, java, subs="{sub-order}"] +---- +RemoteEndpoint remote = session.getRemote(); + +// Async Send of a BINARY message to remote endpoint +ByteBuffer message = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 }); +remote.sendBytes(message, callback); +---- + + [[pingpong]] ==== Send Ping / Pong Control Frame -You can also send Ping and Pong control frames using the RemoteEndpoint. +You can also send Ping and Pong control frames using the `RemoteEndpoint`. [source, java, subs="{sub-order}"] ---- @@ -138,7 +182,7 @@ catch (IOException e) ---- How to send a Ping control frame, with a payload of `"You There?"` (arriving at Remote Endpoint as a byte array payload). -This will block until the message is sent, possibly throwing an IOException if unable to send the ping frame. +This will block until the message is sent, possibly throwing an `IOException` if unable to send the ping frame. [source, java, subs="{sub-order}"] ---- @@ -158,143 +202,23 @@ catch (IOException e) ---- How to send a Pong control frame, with a payload of `"Yup I'm here"` (arriving at Remote Endpoint as a byte array payload). -This will block until the message is sent, possibly throwing an IOException if unable to send the pong frame. +This will block until the message is sent, possibly throwing an `IOException` if unable to send the pong frame. To be correct in your usage of Pong frames, you should return the same byte array data that you received in the Ping frame. -[[async]] -==== Async Send Message - -However there are also 2 Async send message methods available: - -* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendBytesByFuture(java.nio.ByteBuffer)[`RemoteEndpoint.sendBytesByFuture(ByteBuffer message)`] -* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendStringByFuture(java.lang.String)[`RemoteEndpoint.sendStringByFuture(String message)`] - -Both return a `Future` that can be used to test for success and failure of the message send using standard http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html[`java.util.concurrent.Future`] behavior. +You can also asynchronously send Ping and Pong frames using the `WriteCallback`, this will return before the Ping/Pong is +transmitted and notify you of the result in `WriteCallback` `writeSuccess()` or `writeFailed()`. [source, java, subs="{sub-order}"] ---- RemoteEndpoint remote = session.getRemote(); -// Async Send of a BINARY message to remote endpoint -ByteBuffer buf = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 }); -remote.sendBytesByFuture(buf); +String pingData = "You There?"; +ByteBuffer pingPayload = ByteBuffer.wrap(data.getBytes()); + +String pongData = "Yup, I'm here"; +ByteBuffer pongPayload = ByteBuffer.wrap(data.getBytes()); + +remote.sendPing(pingPayload, WriteCallback.NOOP); +remote.sendPong(pongPayload, WriteCallback.NOOP); ---- - -How to send a simple Binary message using the RemoteEndpoint. -The message will be enqueued for outgoing write, but you will not know if it succeeded or failed. - -[source, java, subs="{sub-order}"] ----- -RemoteEndpoint remote = session.getRemote(); - -// Async Send of a BINARY message to remote endpoint -ByteBuffer buf = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 }); -try -{ - Future fut = remote.sendBytesByFuture(buf); - // wait for completion (forever) - fut.get(); -} -catch (ExecutionException | InterruptedException e) -{ - // Send failed - e.printStackTrace(); -} ----- - -How to send a simple Binary message using the RemoteEndpoint, tracking the `Future` to know if the send succeeded or failed. - -[source, java, subs="{sub-order}"] ----- -RemoteEndpoint remote = session.getRemote(); - -// Async Send of a BINARY message to remote endpoint -ByteBuffer buf = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 }); -Future fut = null; -try -{ - fut = remote.sendBytesByFuture(buf); - // wait for completion (timeout) - fut.get(2,TimeUnit.SECONDS); -} -catch (ExecutionException | InterruptedException e) -{ - // Send failed - e.printStackTrace(); -} -catch (TimeoutException e) -{ - // timeout - e.printStackTrace(); - if (fut != null) - { - // cancel the message - fut.cancel(true); - } -} ----- - -How to send a simple Binary message using the RemoteEndpoint, tracking the `Future` and waiting only prescribed amount of time for the send to complete, cancelling the message if the timeout occurs. - -[source, java, subs="{sub-order}"] ----- -RemoteEndpoint remote = session.getRemote(); - -// Async Send of a TEXT message to remote endpoint -remote.sendStringByFuture("Hello World"); ----- - -How to send a simple Text message using the RemoteEndpoint. -The message will be enqueued for outgoing write, but you will not know if it succeeded or failed. - -[source, java, subs="{sub-order}"] ----- -RemoteEndpoint remote = session.getRemote(); - -// Async Send of a TEXT message to remote endpoint -try -{ - Future fut = remote.sendStringByFuture("Hello World"); - // wait for completion (forever) - fut.get(); -} -catch (ExecutionException | InterruptedException e) -{ - // Send failed - e.printStackTrace(); -} ----- - -How to send a simple Binary message using the RemoteEndpoint, tracking the `Future` to know if the send succeeded or failed. - -[source, java, subs="{sub-order}"] ----- -RemoteEndpoint remote = session.getRemote(); - -// Async Send of a TEXT message to remote endpoint -Future fut = null; -try -{ - fut = remote.sendStringByFuture("Hello World"); - // wait for completion (timeout) - fut.get(2,TimeUnit.SECONDS); -} -catch (ExecutionException | InterruptedException e) -{ - // Send failed - e.printStackTrace(); -} -catch (TimeoutException e) -{ - // timeout - e.printStackTrace(); - if (fut != null) - { - // cancel the message - fut.cancel(true); - } -} ----- - -How to send a simple Binary message using the RemoteEndpoint, tracking the `Future` and waiting only prescribed amount of time for the send to complete, cancelling the message if the timeout occurs. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-session.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-session.adoc index 67c34790b40..4e06f6ea350 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-session.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api-session.adoc @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api-session]] +[[websocket-jetty-api-session]] === WebSocket Session The link:{JDURL}/org/eclipse/jetty/websocket/api/Session.html[Session] object can be used to: @@ -54,12 +54,12 @@ What is the Local and Remote Address. [source, java, subs="{sub-order}"] ---- -InetSocketAddress remoteAddr = session.getRemoteAddress(); +SocketAddress remoteAddr = session.getRemoteAddress(); ---- Get and Set the Idle Timeout [source, java, subs="{sub-order}"] ---- -session.setIdleTimeout(2000); // 2 second timeout +session.setIdleTimeout(Duration.ofMillis(2000)); ---- diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api.adoc index 861d11a96dc..897cb3d8653 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-api.adoc @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-api]] +[[websocket-jetty-api]] === Jetty WebSocket API Usage Jetty provides its own more powerful WebSocket API, with a common core API for both server and client use of WebSockets. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-client-api.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-client-api.adoc index 1be100478cf..1a2f143ab09 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-client-api.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-client-api.adoc @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-client-api]] +[[websocket-jetty-client-api]] === Jetty WebSocket Client API Jetty also provides a Jetty WebSocket Client Library to write make talking to WebSocket servers easier. @@ -38,14 +38,14 @@ To use the WebSocketClient you will need to hook up a WebSocket object instance [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoClient.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoClient.java[] ---- The above example connects to a remote WebSocket server and hands off a SimpleEchoSocket to perform the logic on the websocket once connected, waiting for the socket to register that it has closed. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoSocket.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoSocket.java[] ---- When the SimpleEchoSocket connects, it sends 2 Text messages and then closes the socket. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-server-api.adoc b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-server-api.adoc index d18910ae134..56352fc3a6a 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-server-api.adoc +++ b/jetty-documentation/src/main/asciidoc/embedded-guide/server/websockets/jetty/jetty-websocket-server-api.adoc @@ -1,25 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -[[jetty-websocket-server-api]] +[[websocket-jetty-server-api]] === Jetty WebSocket Server API -Jetty provides the ability to wire up WebSocket endpoints to Servlet Path Specs via the use of a WebSocketServlet bridge servlet. +Jetty provides the ability to wire up WebSocket endpoints to Servlet Path Specs via the use of a `JettyWebSocketServlet` bridge servlet. Internally, Jetty manages the HTTP Upgrade to WebSocket and migration from a HTTP Connection to a WebSocket Connection. @@ -27,17 +27,17 @@ This will only work when running within the Jetty Container (unlike past Jetty t ==== The Jetty WebSocketServlet -To wire up your WebSocket to a specific path via the WebSocketServlet, you will need to extend org.eclipse.jetty.websocket.servlet.WebSocketServlet and specify what WebSocket object should be created with incoming Upgrade requests. +To wire up your WebSocket to a specific path via the `JettyWebSocketServlet`, you will need to extend `org.eclipse.jetty.websocket.servlet.JettyWebSocketServlet` and specify what `WebSocket` object should be created with incoming Upgrade requests. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java[] ---- This example will create a Servlet mapped via the http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html[@WebServlet] annotation to the Servlet path spec of `"/echo"` (or you can do this manually in the `WEB-INF/web.xml` of your web application) which will create MyEchoSocket instances when encountering HTTP Upgrade requests. -The link:{JDURL}/org/eclipse/jetty/websocket/servlet/WebSocketServlet.html#configure(org.eclipse.jetty.websocket.servlet.WebSocketServletFactory)[`WebSocketServlet.configure(WebSocketServletFactory factory)`] is where you put your specific configuration for your WebSocket. -In the example we specify a 10 second idle timeout and register MyEchoSocket with the default WebSocketCreator the WebSocket class we want to be created on Upgrade. +The link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketServlet.html#configure(org.eclipse.jetty.websocket.servlet.JettyWebSocketServletFactory)[`JettyWebSocketServlet.configure(JettyWebSocketServletFactory factory)`] is where you put your specific configuration for your WebSocket. +In the example we specify a 10 second idle timeout and register MyEchoSocket with the default JettyWebSocketCreator the WebSocket class we want to be created on Upgrade. ____ [NOTE] @@ -46,31 +46,31 @@ when configuring websockets. Be sure the websocket configuration is lower than your firewall or router. ____ -==== Using the WebSocketCreator +==== Using the JettyWebSocketCreator -All WebSocket's are created via whatever link:{JDURL}/org/eclipse/jetty/websocket/servlet/WebSocketCreator.html[WebSocketCreator] you have registered with the link:{JDURL}/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.html[WebSocketServletFactory]. +All WebSocket's are created via whatever link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketCreator.html[JettyWebSocketCreator] you have registered with the link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketServletFactory.html[JettyWebSocketServletFactory]. -By default, the WebSocketServletFactory is a simple WebSocketCreator capable of creating a single WebSocket object. -Use link:{JDURL}/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.html#register(java.lang.Class)[`WebSocketCreator.register(Class websocket)`] to tell the WebSocketServletFactory which class it should instantiate (make sure it has a default constructor). +By default, the `JettyWebSocketServletFactory` is a simple `JettyWebSocketCreator` capable of creating a single WebSocket object. +Use link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketServletFactory.html#register(java.lang.Class)[`JettyWebSocketCreator.register(Class websocket)`] to tell the `JettyWebSocketServletFactory` which class it should instantiate (make sure it has a default constructor). -If you have a more complicated creation scenario, you might want to provide your own WebSocketCreator that bases the WebSocket it creates off of information present in the UpgradeRequest object. +If you have a more complicated creation scenario, you might want to provide your own `JettyWebSocketCreator` that bases the WebSocket it creates off of information present in the `UpgradeRequest` object. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java[] ---- -Here we show a WebSocketCreator that will utilize the http://tools.ietf.org/html/rfc6455#section-1.9[WebSocket subprotocol] information from request to determine what WebSocket type should be +Here we show a `JettyWebSocketCreator` that will utilize the http://tools.ietf.org/html/rfc6455#section-1.9[WebSocket subprotocol] information from request to determine what WebSocket type should be created. [source, java, subs="{sub-order}"] ---- -include::{SRCDIR}/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java[] +include::{SRCDIR}/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java[] ---- -When you want a custom WebSocketCreator, use link:{JDURL}/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.html#setCreator(org.eclipse.jetty.websocket.servlet.WebSocketCreator)[`WebSocketServletFactory.setCreator(WebSocketCreator creator)`] and the WebSocketServletFactory will use your creator for all incoming Upgrade requests on this servlet. +When you want a custom `JettyWebSocketCreator`, use link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketServletFactory.html#setCreator(org.eclipse.jetty.websocket.servlet.JettyWebSocketCreator)[`JettyWebSocketServletFactory.setCreator(JettyWebSocketCreator creator)`] and the `JettyWebSocketServletFactory` will use your creator for all incoming Upgrade requests on this servlet. -Other uses for a WebSocketCreator: +Other uses for a `JettyWebSocketCreator`: * Controlling the selection of WebSocket subprotocol * Performing any WebSocket origin you deem important. @@ -78,4 +78,4 @@ Other uses for a WebSocketCreator: * Obtaining the Servlet HttpSession object (if it exists) * Specifying a response status code and reason -If you don't want to accept the upgrade, simply return null from the link:{JDURL}/org/eclipse/jetty/websocket/servlet/WebSocketCreator.html#createWebSocket(org.eclipse.jetty.websocket.api.UpgradeRequest, org.eclipse.jetty.websocket.api.UpgradeResponse)[`WebSocketCreator.createWebSocket(UpgradeRequest req, UpgradeResponse resp)`] method. +If you don't want to accept the upgrade, simply return null from the link:{JDURL}/org/eclipse/jetty/websocket/servlet/JettyWebSocketCreator.html#createWebSocket(org.eclipse.jetty.websocket.api.UpgradeRequest,org.eclipse.jetty.websocket.api.UpgradeResponse)[`JettyWebSocketCreator.createWebSocket(UpgradeRequest req, UpgradeResponse resp)`] method. diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/chapter.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/chapter.adoc index d38647dbef3..fe5857d3d06 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quick-start-configure]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/how-to-configure.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/how-to-configure.adoc index 7de7f777357..e0eecec65df 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/how-to-configure.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/how-to-configure.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-config-how]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/what-to-configure.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/what-to-configure.adoc index 02ed4f97682..988fada5027 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/what-to-configure.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/configuring/what-to-configure.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-config-what]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/chapter.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/chapter.adoc index bf2fbfbcaa7..533a91a736b 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quick-start-getting-started]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-common-configuration.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-common-configuration.adoc index ce07076f907..759865755bf 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-common-configuration.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-common-configuration.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-common-config]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-deploying.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-deploying.adoc index 12cd942a998..0df5d34fe0b 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-deploying.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-deploying.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-deploying-webapps]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-installing.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-installing.adoc index ecc102733b5..77842e5e04b 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-installing.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-installing.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-downloading]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-running.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-running.adoc index 5230dc29edc..72d329285ff 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-running.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/getting-started/jetty-running.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-running-jetty]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/index.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/index.adoc index b13695cdd46..a3a369ae02d 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/index.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/index.adoc @@ -1,22 +1,21 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // - :doctitle: Eclipse Jetty: Quickstart Guide :author: Jetty Developers :email: jetty-dev@eclipse.org diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/chapter.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/chapter.adoc index c69837a1a69..7c4d07a48b6 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/chapter.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[introduction]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-coordinates.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-coordinates.adoc index 9385883e9e3..2850e5d62d7 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-coordinates.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-coordinates.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[quickstart-jetty-coordinates]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-javaee.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-javaee.adoc index 6fa929d8f05..08191b22a5e 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-javaee.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/jetty-javaee.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[jetty-javaee]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-is-jetty.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-is-jetty.adoc index 93c858f560a..319ead4c0ca 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-is-jetty.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-is-jetty.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[what-is-jetty]] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-version.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-version.adoc index b4164bb19c7..c1e1dd2e6e0 100644 --- a/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-version.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/introduction/what-version.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // [[what-jetty-version]] @@ -32,11 +32,14 @@ _____ .Jetty Versions [width="100%",cols="12%,9%,15%,6%,21%,10%,6%,21%",options="header",] |======================================================================= -|Version |Year |Home |JVM |Protocols |Servlet |JSP |Status +|Version |Year |Home |Min JVM |Protocols |Servlet |JSP |Status +|10 |2019- |Eclipse |11 ^(1)^ |HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI |4.0.2 |2.3 |*UNSTABLE / Alpha* |9.4 |2016- |Eclipse |1.8 |HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI |3.1 |2.3 |Stable -|9.3 |2015- |Eclipse |1.8 |HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI |3.1 |2.3 |Stable -|9.2 |2014-2018 |Eclipse |1.7 |HTTP/1.1 RFC2616, javax.websocket, SPDY v3 |3.1 |2.3 |Deprecated / *End of Life January 2018* -|8 |2009-2014 |Eclipse/Codehaus |1.6 |HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3 |3.0 |2.2 |Deprecated / *End of Life November 2014* +|9.3 |2015- |Eclipse |1.8 ^(2)^ |HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI |3.1 |2.3 |Deprecated +|9.2 |2014-2018 |Eclipse |1.7 ^(2)^ |HTTP/1.1 RFC2616, javax.websocket, SPDY v3 |3.1 |2.3 |Deprecated / *End of Life January 2018* +|9.1 |2013-2014 |Eclipse |1.7 ^(2)^ |HTTP/1.1 RFC2616 |3.1 |2.3 |Deprecated / *End of Life May 2014* +|9.0 |2013-2013 |Eclipse |1.7 ^(2)^ |HTTP/1.1 RFC2616 |3.1-beta |2.3 |Deprecated / *End of Life November 2013* +|8 |2009-2014 |Eclipse/Codehaus |1.6 ^(2)^ |HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3 |3.0 |2.2 |Deprecated / *End of Life November 2014* |7 |2008-2014 |Eclipse/Codehaus |1.5 |HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3 |2.5 |2.1 |Deprecated / *End of Life November 2014* |6 |2006-2010 |Codehaus |1.4-1.5 |HTTP/1.1 RFC2616 |2.5 |2.0 |Deprecated / *End of Life November 2010* |5 |2003-2009 |Sourceforge |1.2-1.5 |HTTP/1.1 RFC2616 |2.4 |2.0 |Antique @@ -45,3 +48,6 @@ _____ |2 |1998-2000 |Mortbay |1.1 |HTTP/1.0 RFC1945 |2.1 |1.0 |Legendary |1 |1995-1998 |Mortbay |1.0 |HTTP/1.0 RFC1945 |- |- |Mythical |======================================================================= + + 1. JPMS module support is optional + 2. JDK9 and newer is not supported if using MultiRelease JAR Files, or Bytecode / Annotation scanning. diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/chapter.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/chapter.adoc new file mode 100644 index 00000000000..a16491bace2 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/chapter.adoc @@ -0,0 +1,22 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[upgrading-jetty]] +== Upgrading Jetty + +include::upgrading-from-jetty-9.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/sample.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/sample.adoc new file mode 100644 index 00000000000..9eb382c946c --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/sample.adoc @@ -0,0 +1,25 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + += Sample Title + +This is a sample paragraph. + +== Sample Subsection + +More sample text. diff --git a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/upgrading-9.3-to-9.4.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/upgrading-9.3-to-9.4.adoc similarity index 93% rename from jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/upgrading-9.3-to-9.4.adoc rename to jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/upgrading-9.3-to-9.4.adoc index b06571a38f8..d4758f9bd49 100644 --- a/jetty-documentation/src/main/asciidoc/embedded-guide/server/upgrading/upgrading-9.3-to-9.4.adoc +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/upgrading-9.3-to-9.4.adoc @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ======================================================================== -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // === Upgrading from Jetty 9.3.x to Jetty 9.4.0 diff --git a/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/upgrading-9.4-to.10.0.adoc b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/upgrading-9.4-to.10.0.adoc new file mode 100644 index 00000000000..0b3653c10c9 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/quickstart-guide/upgrading/upgrading-9.4-to.10.0.adoc @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +=== Upgrading from Jetty 9.4.x to Jetty 10.0.x + +The purpose of this guide is to assist users migrating from Jetty 9.4 to 10. +It is not comprehensive, but covers many of the major changes included in the release that may prove as problem areas for users. + +==== Required Java Version + +Jetty 10 requires, at a minimum, Java 9 to function. +Items such as the Java Platform Module System (JPMS), which Jetty 10 supports, are not available in earlier versions of Java. + +==== Removed Classes + +//TODO - Insert major removed/refactored classes from Jetty-9.x.x to Jetty-10.0.x + +==== Changes to Websocket + +//TODO - List of changes to Websocket -- Joakim/Lachlan + +==== `javax.mail` and `javax.transaction` + +Both `javax.mail` and `javax.transaction` have been removed from the Jetty Distribution in Jetty 10. +If you require these jars, you will need to enable the `ext` link:#startup-modules[module] and copy the files to your `$JETTY_BASE/lib/ext` directory. + +==== Module Changes in Jetty 10.0 + +===== New Modules in Jetty 10.0 + +//TODO - Insert new modules introduced in Jetty 10 + +===== Changes to Existing Modules in Jetty 10.0 + +//TODO - Insert module changes introduced in Jetty 10 + +==== Changes to Sessions + +//TODO - List of changes to Sessions -- Jan + +==== Removal of System Properties(?) + +//TODO - List of removed System bits --- Greg diff --git a/jetty-documentation/src/main/assembly/html.xml b/jetty-documentation/src/main/assembly/html.xml index aa7f4cb9dec..4047d078f68 100644 --- a/jetty-documentation/src/main/assembly/html.xml +++ b/jetty-documentation/src/main/assembly/html.xml @@ -1,4 +1,24 @@ + + html diff --git a/jetty-documentation/src/main/java/embedded/client/ClientConnectorDocSnippets.java b/jetty-documentation/src/main/java/embedded/client/ClientConnectorDocSnippets.java index 277bc602ab1..41f92da336f 100644 --- a/jetty-documentation/src/main/java/embedded/client/ClientConnectorDocSnippets.java +++ b/jetty-documentation/src/main/java/embedded/client/ClientConnectorDocSnippets.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package embedded.client; diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index 9d4ec739d53..4b20d57bad4 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -35,6 +35,15 @@ jetty-client ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + diff --git a/jetty-fcgi/fcgi-client/src/main/java/module-info.java b/jetty-fcgi/fcgi-client/src/main/java/module-info.java index f5e97563dfa..bb5bcb07fe3 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/module-info.java +++ b/jetty-fcgi/fcgi-client/src/main/java/module-info.java @@ -1,30 +1,28 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.fcgi.client { exports org.eclipse.jetty.fcgi; exports org.eclipse.jetty.fcgi.client.http; - exports org.eclipse.jetty.fcgi.generator to org.eclipse.jetty.fcgi.server; - exports org.eclipse.jetty.fcgi.parser to org.eclipse.jetty.fcgi.server; + exports org.eclipse.jetty.fcgi.generator; + exports org.eclipse.jetty.fcgi.parser; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.client; + requires org.slf4j; } diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java index f7424aea3e8..3906dfc3c5a 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java index d2d3370dead..61c8cd25033 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.client.http; @@ -81,6 +81,11 @@ public class HttpChannelOverFCGI extends HttpChannel return sender.isFailed() || receiver.isFailed(); } + void receive() + { + connection.process(); + } + @Override public void send(HttpExchange exchange) { diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java index 986deda1936..4b8089b51d7 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.client.http; import java.io.IOException; +import java.util.List; import java.util.Map; import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport; @@ -26,6 +27,8 @@ import org.eclipse.jetty.client.DuplexConnectionPool; import org.eclipse.jetty.client.DuplexHttpDestination; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpDestination; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.fcgi.FCGI; @@ -72,9 +75,15 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran } @Override - public HttpDestination newHttpDestination(HttpDestination.Key key) + public Origin newOrigin(HttpRequest request) { - return new DuplexHttpDestination(getHttpClient(), key); + return getHttpClient().createOrigin(request, new Origin.Protocol(List.of("fastcgi/1.1"), false)); + } + + @Override + public HttpDestination newHttpDestination(Origin origin) + { + return new DuplexHttpDestination(getHttpClient(), origin); } @Override diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java index 3934fd007f0..c4720e32318 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.client.http; @@ -49,15 +49,16 @@ import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.RetainableByteBuffer; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.CompletableCallback; +import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpConnectionOverFCGI extends AbstractConnection implements IConnection { - private static final Logger LOG = Log.getLogger(HttpConnectionOverFCGI.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpConnectionOverFCGI.class); private final LinkedList requests = new LinkedList<>(); private final Map activeChannels = new ConcurrentHashMap<>(); @@ -68,7 +69,7 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne private final Flusher flusher; private final Delegate delegate; private final ClientParser parser; - private ByteBuffer buffer; + private RetainableByteBuffer networkBuffer; public HttpConnectionOverFCGI(EndPoint endPoint, HttpDestination destination, Promise promise) { @@ -114,69 +115,79 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne @Override public void onFillable() { - buffer = acquireBuffer(); - process(buffer); + networkBuffer = newNetworkBuffer(); + process(); } - private ByteBuffer acquireBuffer() + private void reacquireNetworkBuffer() + { + if (networkBuffer == null) + throw new IllegalStateException(); + if (networkBuffer.hasRemaining()) + throw new IllegalStateException(); + networkBuffer.release(); + networkBuffer = newNetworkBuffer(); + if (LOG.isDebugEnabled()) + LOG.debug("Reacquired {}", networkBuffer); + } + + private RetainableByteBuffer newNetworkBuffer() { HttpClient client = destination.getHttpClient(); ByteBufferPool bufferPool = client.getByteBufferPool(); - return bufferPool.acquire(client.getResponseBufferSize(), true); + return new RetainableByteBuffer(bufferPool, client.getResponseBufferSize(), client.isUseInputDirectByteBuffers()); } - private void releaseBuffer(ByteBuffer buffer) + private void releaseNetworkBuffer() { - @SuppressWarnings("ReferenceEquality") - boolean isCurrentBuffer = (this.buffer == buffer); - assert (isCurrentBuffer); - HttpClient client = destination.getHttpClient(); - ByteBufferPool bufferPool = client.getByteBufferPool(); - bufferPool.release(buffer); - this.buffer = null; + if (networkBuffer == null) + throw new IllegalStateException(); + if (networkBuffer.hasRemaining()) + throw new IllegalStateException(); + networkBuffer.release(); + if (LOG.isDebugEnabled()) + LOG.debug("Released {}", networkBuffer); + this.networkBuffer = null; } - private void process(ByteBuffer buffer) + void process() { + EndPoint endPoint = getEndPoint(); try { - EndPoint endPoint = getEndPoint(); - boolean looping = false; while (true) { - if (!looping && parse(buffer)) + if (parse(networkBuffer.getBuffer())) return; - int read = endPoint.fill(buffer); + if (networkBuffer.getReferences() > 1) + reacquireNetworkBuffer(); + + // The networkBuffer may have been reacquired. + int read = endPoint.fill(networkBuffer.getBuffer()); if (LOG.isDebugEnabled()) LOG.debug("Read {} bytes from {}", read, endPoint); - if (read > 0) + if (read == 0) { - if (parse(buffer)) - return; - } - else if (read == 0) - { - releaseBuffer(buffer); + releaseNetworkBuffer(); fillInterested(); return; } - else + else if (read < 0) { - releaseBuffer(buffer); + releaseNetworkBuffer(); shutdown(); return; } - - looping = true; } } catch (Exception x) { if (LOG.isDebugEnabled()) - LOG.debug(x); - releaseBuffer(buffer); + LOG.debug("Unable to fill from endpoint {}", endPoint, x); + networkBuffer.clear(); + releaseNetworkBuffer(); close(x); } } @@ -404,13 +415,13 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne } @Override - public void onHeaders(int request) + public boolean onHeaders(int request) { HttpChannelOverFCGI channel = activeChannels.get(request); if (channel != null) - channel.responseHeaders(); - else - noChannel(request); + return !channel.responseHeaders(); + noChannel(request); + return false; } @Override @@ -423,26 +434,8 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne HttpChannelOverFCGI channel = activeChannels.get(request); if (channel != null) { - CompletableCallback callback = new CompletableCallback() - { - @Override - public void resume() - { - if (LOG.isDebugEnabled()) - LOG.debug("Content consumed asynchronously, resuming processing"); - process(HttpConnectionOverFCGI.this.buffer); - } - - @Override - public void abort(Throwable x) - { - close(x); - } - }; - // Do not short circuit these calls. - boolean proceed = channel.content(buffer, callback); - boolean async = callback.tryComplete(); - return !proceed || async; + networkBuffer.retain(); + return !channel.content(buffer, Callback.from(networkBuffer::release, HttpConnectionOverFCGI.this::close)); } else { diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpReceiverOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpReceiverOverFCGI.java index 4f99ea24bb1..c4ea2ce625f 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpReceiverOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpReceiverOverFCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.client.http; @@ -33,6 +33,12 @@ public class HttpReceiverOverFCGI extends HttpReceiver super(channel); } + @Override + protected HttpChannelOverFCGI getHttpChannel() + { + return (HttpChannelOverFCGI)super.getHttpChannel(); + } + @Override protected boolean responseBegin(HttpExchange exchange) { @@ -68,4 +74,10 @@ public class HttpReceiverOverFCGI extends HttpReceiver { return super.responseFailure(failure); } + + @Override + protected void receive() + { + getHttpChannel().receive(); + } } diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java index e3e65d4e431..24210431962 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.client.http; @@ -22,6 +22,7 @@ import java.net.URI; import java.util.Locale; import org.eclipse.jetty.client.HttpChannel; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpContent; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpSender; @@ -44,7 +45,8 @@ public class HttpSenderOverFCGI extends HttpSender public HttpSenderOverFCGI(HttpChannel channel) { super(channel); - this.generator = new ClientGenerator(channel.getHttpDestination().getHttpClient().getByteBufferPool()); + HttpClient httpClient = channel.getHttpDestination().getHttpClient(); + this.generator = new ClientGenerator(httpClient.getByteBufferPool(), httpClient.isUseOutputDirectByteBuffers()); } @Override diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java index 4d79147d467..1bddc5aba68 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.generator; @@ -40,7 +40,12 @@ public class ClientGenerator extends Generator public ClientGenerator(ByteBufferPool byteBufferPool) { - super(byteBufferPool); + this(byteBufferPool, true); + } + + public ClientGenerator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers) + { + super(byteBufferPool, useDirectByteBuffers); } public Result generateRequestHeaders(int request, HttpFields fields, Callback callback) @@ -79,9 +84,9 @@ public class ClientGenerator extends Generator // One FCGI_BEGIN_REQUEST + N FCGI_PARAMS + one last FCGI_PARAMS - ByteBuffer beginRequestBuffer = byteBufferPool.acquire(16, false); + ByteBuffer beginRequestBuffer = acquire(16); BufferUtil.clearToFill(beginRequestBuffer); - Result result = new Result(byteBufferPool, callback); + Result result = new Result(getByteBufferPool(), callback); result = result.append(beginRequestBuffer, true); // Generate the FCGI_BEGIN_REQUEST frame @@ -95,7 +100,7 @@ public class ClientGenerator extends Generator while (fieldsLength > 0) { int capacity = 8 + Math.min(maxCapacity, fieldsLength); - ByteBuffer buffer = byteBufferPool.acquire(capacity, true); + ByteBuffer buffer = acquire(capacity); BufferUtil.clearToFill(buffer); result = result.append(buffer, true); @@ -132,7 +137,7 @@ public class ClientGenerator extends Generator BufferUtil.flipToFlush(buffer, 0); } - ByteBuffer lastParamsBuffer = byteBufferPool.acquire(8, false); + ByteBuffer lastParamsBuffer = acquire(8); BufferUtil.clearToFill(lastParamsBuffer); result = result.append(lastParamsBuffer, true); diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java index a8006a5df55..0b31c501a4a 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.generator; @@ -24,12 +24,12 @@ import java.util.Queue; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Flusher { - private static final Logger LOG = Log.getLogger(Flusher.class); + private static final Logger LOG = LoggerFactory.getLogger(Flusher.class); private final Queue queue = new ArrayDeque<>(); private final IteratingCallback flushCallback = new FlushCallback(); diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java index aaceab03673..15cefbd35fe 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.generator; @@ -31,11 +31,23 @@ public class Generator { public static final int MAX_CONTENT_LENGTH = 0xFF_FF; - protected final ByteBufferPool byteBufferPool; + private final ByteBufferPool byteBufferPool; + private final boolean useDirectByteBuffers; - public Generator(ByteBufferPool byteBufferPool) + public Generator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers) { this.byteBufferPool = byteBufferPool; + this.useDirectByteBuffers = useDirectByteBuffers; + } + + ByteBufferPool getByteBufferPool() + { + return byteBufferPool; + } + + ByteBuffer acquire(int capacity) + { + return byteBufferPool.acquire(capacity, useDirectByteBuffers); } protected Result generateContent(int id, ByteBuffer content, boolean recycle, boolean lastContent, Callback callback, FCGI.FrameType frameType) @@ -47,7 +59,7 @@ public class Generator while (contentLength > 0 || lastContent) { - ByteBuffer buffer = byteBufferPool.acquire(8, false); + ByteBuffer buffer = acquire(8); BufferUtil.clearToFill(buffer); result = result.append(buffer, true); diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java index 25f2138b455..59562fa2cc9 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.generator; @@ -42,12 +42,12 @@ public class ServerGenerator extends Generator public ServerGenerator(ByteBufferPool byteBufferPool) { - this(byteBufferPool, true); + this(byteBufferPool, true, true); } - public ServerGenerator(ByteBufferPool byteBufferPool, boolean sendStatus200) + public ServerGenerator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers, boolean sendStatus200) { - super(byteBufferPool); + super(byteBufferPool, useDirectByteBuffers); this.sendStatus200 = sendStatus200; } @@ -55,7 +55,7 @@ public class ServerGenerator extends Generator { request &= 0xFF_FF; - final Charset utf8 = StandardCharsets.UTF_8; + Charset utf8 = StandardCharsets.UTF_8; List bytes = new ArrayList<>(fields.size() * 2); int length = 0; @@ -88,7 +88,7 @@ public class ServerGenerator extends Generator // End of headers length += EOL.length; - final ByteBuffer buffer = byteBufferPool.acquire(length, true); + ByteBuffer buffer = acquire(length); BufferUtil.clearToFill(buffer); for (int i = 0; i < bytes.size(); i += 2) @@ -106,7 +106,7 @@ public class ServerGenerator extends Generator { if (aborted) { - Result result = new Result(byteBufferPool, callback); + Result result = new Result(getByteBufferPool(), callback); if (lastContent) result.append(generateEndRequest(request, true), true); else @@ -125,7 +125,7 @@ public class ServerGenerator extends Generator private ByteBuffer generateEndRequest(int request, boolean aborted) { request &= 0xFF_FF; - ByteBuffer endRequestBuffer = byteBufferPool.acquire(8, false); + ByteBuffer endRequestBuffer = acquire(8); BufferUtil.clearToFill(endRequestBuffer); endRequestBuffer.putInt(0x01_03_00_00 + request); endRequestBuffer.putInt(0x00_08_00_00); diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/BeginRequestContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/BeginRequestContentParser.java index 6fe19cd44b3..2d7357db583 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/BeginRequestContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/BeginRequestContentParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java index 94dc7e43e19..65ee845123a 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -80,9 +80,9 @@ public class ClientParser extends Parser } @Override - public void onHeaders(int request) + public boolean onHeaders(int request) { - listener.onHeaders(request); + return listener.onHeaders(request); } @Override diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ContentParser.java index 54521faeb24..ab824c99501 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ContentParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/EndRequestContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/EndRequestContentParser.java index 9116159c70f..9e27cbc4365 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/EndRequestContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/EndRequestContentParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/HeaderParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/HeaderParser.java index c02ddb655f3..15e90361dd4 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/HeaderParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/HeaderParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -21,8 +21,8 @@ package org.eclipse.jetty.fcgi.parser; import java.nio.ByteBuffer; import org.eclipse.jetty.fcgi.FCGI; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    Parser for FastCGI frame headers.

    @@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HeaderParser { - private static final Logger LOG = Log.getLogger(Parser.class); + private static final Logger LOG = LoggerFactory.getLogger(Parser.class); private State state = State.VERSION; private int cursor; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ParamsContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ParamsContentParser.java index 888f12a1863..538d229db9f 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ParamsContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ParamsContentParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -23,8 +23,8 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    Parser for the PARAMS frame body.

    @@ -60,7 +60,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ParamsContentParser extends ContentParser { - private static final Logger LOG = Log.getLogger(ParamsContentParser.class); + private static final Logger LOG = LoggerFactory.getLogger(ParamsContentParser.class); private final ServerParser.Listener listener; private State state = State.LENGTH; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/Parser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/Parser.java index 8eee11f53b1..b4abccd8268 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/Parser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/Parser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -22,8 +22,8 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.fcgi.FCGI; import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    The FastCGI protocol exchanges frames.

    @@ -47,7 +47,7 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class Parser { - private static final Logger LOG = Log.getLogger(Parser.class); + private static final Logger LOG = LoggerFactory.getLogger(Parser.class); protected final HeaderParser headerParser = new HeaderParser(); private State state = State.HEADER; @@ -135,7 +135,11 @@ public abstract class Parser { public void onHeader(int request, HttpField field); - public void onHeaders(int request); + /** + * @param request the request id + * @return true to signal to the parser to stop parsing, false to continue parsing + */ + public boolean onHeaders(int request); /** * @param request the request id @@ -158,8 +162,9 @@ public abstract class Parser } @Override - public void onHeaders(int request) + public boolean onHeaders(int request) { + return false; } @Override diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java index 51742bde50b..ade1a39b03c 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -32,8 +32,8 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    The parser for STDOUT type frame bodies.

    @@ -45,7 +45,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ResponseContentParser extends StreamContentParser { - private static final Logger LOG = Log.getLogger(ResponseContentParser.class); + private static final Logger LOG = LoggerFactory.getLogger(ResponseContentParser.class); private final Map parsers = new ConcurrentHashMap<>(); private final ClientParser.Listener listener; @@ -82,7 +82,7 @@ public class ResponseContentParser extends StreamContentParser parsers.remove(request); } - private class ResponseParser implements HttpParser.ResponseHandler + private static class ResponseParser implements HttpParser.ResponseHandler { private final HttpFields fields = new HttpFields(); private ClientParser.Listener listener; @@ -90,6 +90,7 @@ public class ResponseContentParser extends StreamContentParser private final FCGIHttpParser httpParser; private State state = State.HEADERS; private boolean seenResponseCode; + private boolean stalled; private ResponseParser(ClientParser.Listener listener, int request) { @@ -111,7 +112,11 @@ public class ResponseContentParser extends StreamContentParser case HEADERS: { if (httpParser.parseNext(buffer)) + { state = State.CONTENT_MODE; + if (stalled) + return true; + } remaining = buffer.remaining(); break; } @@ -151,21 +156,7 @@ public class ResponseContentParser extends StreamContentParser } @Override - public int getHeaderCacheSize() - { - // TODO: configure this - return 4096; - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - // TODO get from configuration - return false; - } - - @Override - public boolean startResponse(HttpVersion version, int status, String reason) + public void startResponse(HttpVersion version, int status, String reason) { // The HTTP request line does not exist in FCGI responses throw new IllegalStateException(); @@ -247,16 +238,17 @@ public class ResponseContentParser extends StreamContentParser } } - private void notifyHeaders() + private boolean notifyHeaders() { try { - listener.onHeaders(request); + return listener.onHeaders(request); } catch (Throwable x) { if (LOG.isDebugEnabled()) LOG.debug("Exception while invoking listener " + listener, x); + return false; } } @@ -269,8 +261,10 @@ public class ResponseContentParser extends StreamContentParser notifyBegin(200, "OK"); notifyHeaders(fields); } - notifyHeaders(); - // Return from HTTP parsing so that we can parse the content. + // Remember whether we have demand. + stalled = notifyHeaders(); + // Always return from HTTP parsing so that we + // can parse the content with the FCGI parser. return true; } diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ServerParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ServerParser.java index 0ffeba7bfb8..7f3b440f536 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ServerParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ServerParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/StreamContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/StreamContentParser.java index 4280ddd284a..1d801ae0cbb 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/StreamContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/StreamContentParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -21,8 +21,8 @@ package org.eclipse.jetty.fcgi.parser; import java.nio.ByteBuffer; import org.eclipse.jetty.fcgi.FCGI; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

    A stream content parser parses frame bodies of type STDIN, STDOUT and STDERR.

    @@ -30,7 +30,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class StreamContentParser extends ContentParser { - private static final Logger LOG = Log.getLogger(StreamContentParser.class); + private static final Logger LOG = LoggerFactory.getLogger(StreamContentParser.class); private final FCGI.StreamType streamType; private final Parser.Listener listener; diff --git a/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java b/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java index 67e6fe9761b..3900eadef18 100644 --- a/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java +++ b/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.generator; @@ -109,10 +109,11 @@ public class ClientGeneratorTest } @Override - public void onHeaders(int request) + public boolean onHeaders(int request) { assertEquals(id, request); params.set(params.get() * primes[4]); + return false; } }); diff --git a/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java b/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java index 7e9e9dbb2b6..9238a48eef8 100644 --- a/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java +++ b/jetty-fcgi/fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.parser; @@ -91,10 +91,11 @@ public class ClientParserTest } @Override - public void onHeaders(int request) + public boolean onHeaders(int request) { assertEquals(id, request); params.set(params.get() * primes[2]); + return false; } }); diff --git a/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties b/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties index b8df62d071d..4e7406f1b54 100644 --- a/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties +++ b/jetty-fcgi/fcgi-client/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.client.LEVEL=DEBUG #org.eclipse.jetty.fcgi.LEVEL=DEBUG diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index 742fcf5a9fe..7eb70468863 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -15,6 +15,10 @@ + + org.slf4j + slf4j-api + org.eclipse.jetty.toolchain jetty-servlet-api @@ -35,7 +39,11 @@ jetty-server ${project.version} - + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty jetty-servlet diff --git a/jetty-fcgi/fcgi-server/src/main/java/module-info.java b/jetty-fcgi/fcgi-server/src/main/java/module-info.java index 2e7e4ce4441..2722eaaec7a 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/module-info.java +++ b/jetty-fcgi/fcgi-server/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.fcgi.server @@ -21,13 +21,9 @@ module org.eclipse.jetty.fcgi.server exports org.eclipse.jetty.fcgi.server; exports org.eclipse.jetty.fcgi.server.proxy; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.fcgi.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.proxy; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.fcgi.client; + requires transitive org.eclipse.jetty.proxy; + requires org.slf4j; // Only required if using the proxy features. requires static jetty.servlet.api; diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java index 1ba90e21ce2..ddba3fa5f70 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; @@ -36,12 +36,12 @@ import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpChannelOverFCGI extends HttpChannel { - private static final Logger LOG = Log.getLogger(HttpChannelOverFCGI.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpChannelOverFCGI.class); private final HttpFields fields = new HttpFields(); private final Dispatcher dispatcher; @@ -125,6 +125,14 @@ public class HttpChannelOverFCGI extends HttpChannel dispatcher.dispatch(); } + public boolean onIdleTimeout(Throwable timeout) + { + boolean handle = getRequest().getHttpInput().onIdleTimeout(timeout); + if (handle) + execute(this); + return !handle; + } + private static class Dispatcher implements Runnable { private final AtomicReference state = new AtomicReference<>(State.IDLE); diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java index 09d9b2dbb51..866989a7cd1 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; @@ -25,41 +25,39 @@ import org.eclipse.jetty.fcgi.generator.Generator; import org.eclipse.jetty.fcgi.generator.ServerGenerator; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpTransportOverFCGI implements HttpTransport { - private static final Logger LOG = Log.getLogger(HttpTransportOverFCGI.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpTransportOverFCGI.class); private final ServerGenerator generator; private final Flusher flusher; private final int request; private volatile boolean shutdown; private volatile boolean aborted; - public HttpTransportOverFCGI(ByteBufferPool byteBufferPool, Flusher flusher, int request, boolean sendStatus200) + public HttpTransportOverFCGI(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers, boolean sendStatus200, Flusher flusher, int request) { - this.generator = new ServerGenerator(byteBufferPool, sendStatus200); + this.generator = new ServerGenerator(byteBufferPool, useDirectByteBuffers, sendStatus200); this.flusher = flusher; this.request = request; } @Override - public boolean isOptimizedForDirectBuffers() + public void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback) { - return false; - } - - @Override - public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) - { - if (info != null) - commit(info, head, content, lastContent, callback); + boolean head = HttpMethod.HEAD.is(request.getMethod()); + if (response != null) + { + commit(response, head, content, lastContent, callback); + } else { if (head) diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java index dc9547d7119..27b1b9ba465 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; @@ -34,12 +34,12 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpInput; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ServerFCGIConnection extends AbstractConnection { - private static final Logger LOG = Log.getLogger(ServerFCGIConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(ServerFCGIConnection.class); private final ConcurrentMap channels = new ConcurrentHashMap<>(); private final Connector connector; @@ -47,6 +47,8 @@ public class ServerFCGIConnection extends AbstractConnection private final Flusher flusher; private final HttpConfiguration configuration; private final ServerParser parser; + private boolean useInputDirectByteBuffers; + private boolean useOutputDirectByteBuffers; public ServerFCGIConnection(Connector connector, EndPoint endPoint, HttpConfiguration configuration, boolean sendStatus200) { @@ -58,6 +60,26 @@ public class ServerFCGIConnection extends AbstractConnection this.parser = new ServerParser(new ServerListener()); } + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + @Override public void onOpen() { @@ -70,7 +92,7 @@ public class ServerFCGIConnection extends AbstractConnection { EndPoint endPoint = getEndPoint(); ByteBufferPool bufferPool = connector.getByteBufferPool(); - ByteBuffer buffer = bufferPool.acquire(configuration.getResponseHeaderSize(), true); + ByteBuffer buffer = bufferPool.acquire(configuration.getResponseHeaderSize(), isUseInputDirectByteBuffers()); try { while (true) @@ -99,12 +121,20 @@ public class ServerFCGIConnection extends AbstractConnection catch (Exception x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Unable to fill endpoint", x); bufferPool.release(buffer); // TODO: fail and close ? } } + @Override + protected boolean onReadTimeout(Throwable timeout) + { + return channels.values().stream() + .mapToInt(channel -> channel.onIdleTimeout(timeout) ? 0 : 1) + .sum() == 0; + } + private void parse(ByteBuffer buffer) { while (buffer.hasRemaining()) @@ -125,7 +155,7 @@ public class ServerFCGIConnection extends AbstractConnection { // TODO: handle flags HttpChannelOverFCGI channel = new HttpChannelOverFCGI(connector, configuration, getEndPoint(), - new HttpTransportOverFCGI(connector.getByteBufferPool(), flusher, request, sendStatus200)); + new HttpTransportOverFCGI(connector.getByteBufferPool(), isUseOutputDirectByteBuffers(), sendStatus200, flusher, request)); HttpChannelOverFCGI existing = channels.putIfAbsent(request, channel); if (existing != null) throw new IllegalStateException(); @@ -144,7 +174,7 @@ public class ServerFCGIConnection extends AbstractConnection } @Override - public void onHeaders(int request) + public boolean onHeaders(int request) { HttpChannelOverFCGI channel = channels.get(request); if (LOG.isDebugEnabled()) @@ -154,6 +184,7 @@ public class ServerFCGIConnection extends AbstractConnection channel.onRequest(); channel.dispatch(); } + return false; } @Override diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java index 57da66914fe..05d4f5ecfe7 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; @@ -23,11 +23,16 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.AbstractConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; +@ManagedObject public class ServerFCGIConnectionFactory extends AbstractConnectionFactory { private final HttpConfiguration configuration; private final boolean sendStatus200; + private boolean useInputDirectByteBuffers; + private boolean useOutputDirectByteBuffers; public ServerFCGIConnectionFactory(HttpConfiguration configuration) { @@ -39,11 +44,38 @@ public class ServerFCGIConnectionFactory extends AbstractConnectionFactory super("fcgi/1.0"); this.configuration = configuration; this.sendStatus200 = sendStatus200; + setUseInputDirectByteBuffers(configuration.isUseInputDirectByteBuffers()); + setUseOutputDirectByteBuffers(configuration.isUseOutputDirectByteBuffers()); + } + + @ManagedAttribute("Whether to use direct ByteBuffers for reading") + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + @ManagedAttribute("Whether to use direct ByteBuffers for writing") + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; } @Override public Connection newConnection(Connector connector, EndPoint endPoint) { - return new ServerFCGIConnection(connector, endPoint, configuration, sendStatus200); + ServerFCGIConnection connection = new ServerFCGIConnection(connector, endPoint, configuration, sendStatus200); + connection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers()); + connection.setUseOutputDirectByteBuffers(isUseOutputDirectByteBuffers()); + return configure(connection, connector, endPoint); } } diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java index 4d0614de153..f842f7f9ecd 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server.proxy; @@ -44,7 +44,7 @@ import org.eclipse.jetty.util.ProcessorUtils; /** * Specific implementation of {@link org.eclipse.jetty.proxy.AsyncProxyServlet.Transparent} for FastCGI. *

    - * This servlet accepts a HTTP request and transforms it into a FastCGI request + * This servlet accepts an HTTP request and transforms it into a FastCGI request * that is sent to the FastCGI server specified in the {@code proxyTo} * init-param. *

    @@ -260,7 +260,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent fcgi.put(field.getName(), field.getValue()); } String eol = System.lineSeparator(); - _log.debug("FastCGI variables{}{}", eol, fcgi.entrySet().stream() + _log.debug("FastCGI variables {}{}", eol, fcgi.entrySet().stream() .map(entry -> String.format("%s: %s", entry.getKey(), entry.getValue())) .collect(Collectors.joining(eol))); } diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java index 7a047c6c1cc..edfa3f8bdd4 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server.proxy; diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java index 3a95b768888..9e791a2513f 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/EmptyServerHandler.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/EmptyServerHandler.java index 708231649b1..760ea2b5ae9 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/EmptyServerHandler.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/EmptyServerHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/ExternalFastCGIServerTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/ExternalFastCGIServerTest.java index 1aade944611..6791ea37954 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/ExternalFastCGIServerTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/ExternalFastCGIServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java index 8a4b959b9d4..f2727aab175 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server; @@ -45,11 +45,11 @@ import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.client.util.FutureResponseListener; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.Net; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; @@ -64,6 +64,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpClientTest extends AbstractHttpClientServerTest { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck + @Test public void testGETResponseWithoutContent() throws Exception { diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java index 9584ead7dd2..0a81190dcd8 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server.proxy; @@ -37,21 +37,19 @@ public class DrupalHTTP2FastCGIProxyServer public static void main(String[] args) throws Exception { SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); - sslContextFactory.setTrustStorePassword("storepwd"); sslContextFactory.setCipherComparator(new HTTP2Cipher.CipherComparator()); Server server = new Server(); // HTTP(S) Configuration HttpConfiguration config = new HttpConfiguration(); - HttpConfiguration https_config = new HttpConfiguration(config); - https_config.addCustomizer(new SecureRequestCustomizer()); + HttpConfiguration httpsConfig = new HttpConfiguration(config); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); // HTTP2 factory - HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(https_config); + HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig); ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); alpn.setDefaultProtocol(h2.getProtocol()); @@ -60,7 +58,7 @@ public class DrupalHTTP2FastCGIProxyServer // HTTP2 Connector ServerConnector http2Connector = - new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(https_config)); + new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig)); http2Connector.setPort(8443); http2Connector.setIdleTimeout(15000); server.addConnector(http2Connector); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java index e3a93abb663..68919b66ede 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server.proxy; diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java index f42aaae0a6a..dc785eb841e 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server.proxy; @@ -55,7 +55,7 @@ public class TryFilesFilterTest server.addConnector(connector); SslContextFactory.Server serverSslContextFactory = new SslContextFactory.Server(); - serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); serverSslContextFactory.setKeyStorePassword("storepwd"); sslConnector = new ServerConnector(server, serverSslContextFactory); server.addConnector(sslConnector); @@ -71,10 +71,8 @@ public class TryFilesFilterTest ClientConnector clientConnector = new ClientConnector(); SslContextFactory.Client clientSslContextFactory = new SslContextFactory.Client(); clientSslContextFactory.setEndpointIdentificationAlgorithm(null); - clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); clientSslContextFactory.setKeyStorePassword("storepwd"); - clientSslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); - clientSslContextFactory.setTrustStorePassword("storepwd"); clientConnector.setSslContextFactory(clientSslContextFactory); client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); server.addBean(client); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java index 0818d1dae93..f8aa371c7bd 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.fcgi.server.proxy; @@ -43,21 +43,19 @@ public class WordPressHTTP2FastCGIProxyServer int tlsPort = 8443; SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); - sslContextFactory.setTrustStorePassword("storepwd"); sslContextFactory.setCipherComparator(new HTTP2Cipher.CipherComparator()); Server server = new Server(); // HTTP(S) Configuration - HttpConfiguration config = new HttpConfiguration(); - HttpConfiguration https_config = new HttpConfiguration(config); - https_config.addCustomizer(new SecureRequestCustomizer()); + HttpConfiguration httpConfig = new HttpConfiguration(); + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); // HTTP2 factory - HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(https_config); + HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig); ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); alpn.setDefaultProtocol(h2.getProtocol()); @@ -66,7 +64,7 @@ public class WordPressHTTP2FastCGIProxyServer // HTTP2 Connector ServerConnector http2Connector = - new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(https_config)); + new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig)); http2Connector.setPort(tlsPort); http2Connector.setIdleTimeout(15000); server.addConnector(http2Connector); diff --git a/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties b/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties index b8df62d071d..4e7406f1b54 100644 --- a/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties +++ b/jetty-fcgi/fcgi-server/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.client.LEVEL=DEBUG #org.eclipse.jetty.fcgi.LEVEL=DEBUG diff --git a/jetty-fcgi/fcgi-server/src/test/resources/keystore.jks b/jetty-fcgi/fcgi-server/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-fcgi/fcgi-server/src/test/resources/keystore.jks and /dev/null differ diff --git a/jetty-fcgi/fcgi-server/src/test/resources/keystore.p12 b/jetty-fcgi/fcgi-server/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..8ab40f72afd Binary files /dev/null and b/jetty-fcgi/fcgi-server/src/test/resources/keystore.p12 differ diff --git a/jetty-fcgi/fcgi-server/src/test/resources/truststore.jks b/jetty-fcgi/fcgi-server/src/test/resources/truststore.jks deleted file mode 100644 index 839cb8c3515..00000000000 Binary files a/jetty-fcgi/fcgi-server/src/test/resources/truststore.jks and /dev/null differ diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 4e2c291d2b7..5044d383aed 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -16,6 +16,10 @@ jetty-server ${project.version} + + org.slf4j + slf4j-api + com.google.cloud google-cloud-datastore @@ -71,7 +75,7 @@ org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} test @@ -80,6 +84,11 @@ jetty-test-helper test + + org.eclipse.jetty + jetty-slf4j-impl + test + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod index 9415b77ed9d..11dbd23f2ff 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod @@ -9,6 +9,6 @@ gcloud [depends] gcloud -jcl-slf4j -jul-impl +logging-jcl-capture +logging-jul diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java index 5589c194220..9daa5f146e6 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -45,8 +45,8 @@ import org.eclipse.jetty.util.ClassLoadingObjectInputStream; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * GCloudSessionDataStore @@ -54,7 +54,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public class GCloudSessionDataStore extends AbstractSessionDataStore { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(GCloudSessionDataStore.class); public static final int DEFAULT_MAX_QUERY_RESULTS = 100; public static final int DEFAULT_MAX_RETRIES = 5; @@ -594,7 +594,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to expire candidate sessions individually", e); } } } @@ -603,7 +603,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get expired", e); return expired; //return what we got } } @@ -921,7 +921,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore } catch (DatastoreException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } long expiry = entity.getLong(_model.getExpiry()); long maxInactive = entity.getLong(_model.getMaxInactive()); diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java index d4743b7af6d..10874cb76e8 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -78,9 +78,6 @@ public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFacto _namespace = namespace; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java b/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java index b132a76511d..ba069a85dff 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 5ed59343949..1bb1d405806 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -11,7 +11,7 @@ Jetty :: Hazelcast Session Manager - 3.9.4 + 3.12.6 ${project.groupId}.hazelcast @@ -38,6 +38,15 @@ jetty-server ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty jetty-webapp @@ -58,7 +67,7 @@ org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} test diff --git a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml index d96524fa6c3..2889de98cff 100644 --- a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml +++ b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml @@ -15,7 +15,8 @@ - + + diff --git a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml index 908130b4b0d..b531a9013a5 100644 --- a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml +++ b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml @@ -5,17 +5,35 @@ - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod index 374493bc509..a34c2d9a1b4 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod @@ -13,7 +13,7 @@ session-store sessions [files] -maven://com.hazelcast/hazelcast/3.9.4|lib/hazelcast/hazelcast-3.9.4.jar +maven://com.hazelcast/hazelcast/3.12.6|lib/hazelcast/hazelcast-3.12.6.jar [xml] etc/sessions/hazelcast/default.xml @@ -31,7 +31,7 @@ http://www.apache.org/licenses/LICENSE-2.0.html [ini-template] jetty.session.hazelcast.mapName=jetty-distributed-session-map jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE -#jetty.session.hazelcast.configurationLocation= jetty.session.hazelcast.scavengeZombies=false jetty.session.gracePeriod.seconds=3600 jetty.session.savePeriod.seconds=0 +#jetty.session.hazelcast.configurationLocation diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod index 3796bef5924..dd276d3fbdb 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod @@ -13,8 +13,8 @@ session-store sessions [files] -maven://com.hazelcast/hazelcast/3.9.4|lib/hazelcast/hazelcast-3.9.4.jar -maven://com.hazelcast/hazelcast-client/3.9.4|lib/hazelcast/hazelcast-client-3.9.4.jar +maven://com.hazelcast/hazelcast/3.12.6|lib/hazelcast/hazelcast-3.12.6.jar +maven://com.hazelcast/hazelcast-client/3.12.6|lib/hazelcast/hazelcast-client-3.12.6.jar [xml] etc/sessions/hazelcast/remote.xml @@ -34,6 +34,7 @@ jetty.session.hazelcast.mapName=jetty-distributed-session-map jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE jetty.session.hazelcast.onlyClient=true jetty.session.hazelcast.scavengeZombies=false -#jetty.session.hazelcast.configurationLocation= jetty.session.gracePeriod.seconds=3600 jetty.session.savePeriod.seconds=0 +#jetty.session.hazelcast.configurationLocation +#jetty.session.hazelcast.addresses= diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java index 8e2d32c1906..c61ecbc3b7a 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; @@ -34,8 +34,8 @@ import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.server.session.SessionDataStore; import org.eclipse.jetty.server.session.UnreadableSessionDataException; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Session data stored in Hazelcast @@ -46,7 +46,7 @@ public class HazelcastSessionDataStore implements SessionDataStore { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(HazelcastSessionDataStore.class); private IMap sessionDataMap; diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java index d6106ce9f34..6d6f042f5ec 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; import java.io.IOException; +import java.util.Arrays; import com.hazelcast.client.HazelcastClient; import com.hazelcast.client.config.ClientConfig; @@ -34,6 +35,7 @@ import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.server.session.SessionDataStore; import org.eclipse.jetty.server.session.SessionDataStoreFactory; import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.util.StringUtil; /** * Factory to construct {@link HazelcastSessionDataStore} @@ -57,6 +59,8 @@ public class HazelcastSessionDataStoreFactory private boolean scavengeZombies = false; + private String addresses; + public boolean isScavengeZombies() { return scavengeZombies; @@ -79,9 +83,15 @@ public class HazelcastSessionDataStoreFactory { if (onlyClient) { - if (configurationLocation == null) + if (StringUtil.isEmpty(configurationLocation)) { ClientConfig config = new ClientConfig(); + + if (addresses != null && !addresses.isEmpty()) + { + config.getNetworkConfig().setAddresses(Arrays.asList(addresses.split(","))); + } + SerializerConfig sc = new SerializerConfig() .setImplementation(new SessionDataSerializer()) .setTypeClass(SessionData.class); @@ -97,7 +107,7 @@ public class HazelcastSessionDataStoreFactory else { Config config; - if (configurationLocation == null) + if (StringUtil.isEmpty(configurationLocation)) { SerializerConfig sc = new SerializerConfig() @@ -202,4 +212,14 @@ public class HazelcastSessionDataStoreFactory { this.hazelcastInstanceName = hazelcastInstanceName; } + + public String getAddresses() + { + return addresses; + } + + public void setAddresses(String addresses) + { + this.addresses = addresses; + } } diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java index da11033940d..48b5d8f4759 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; diff --git a/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java b/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java index 641dd478007..88fe6a48db9 100644 --- a/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java +++ b/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index 6fdf20dbfaf..f7bdb194a0a 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -170,6 +170,33 @@ ${source-assembly-directory}/lib + + copy-lib-logging-deps + generate-resources + + copy-dependencies + + + org.eclipse.jetty,org.slf4j + jetty-slf4j-impl,slf4j-api + jar + ${assembly-directory}/lib/logging + + + + copy-lib-logging-src-deps + generate-resources + + copy-dependencies + + + org.eclipse.jetty,org.slf4j + jetty-slf4j-impl,slf4j-api + jar + sources + ${source-assembly-directory}/lib/logging + + copy-lib-websocket-deps generate-resources @@ -603,6 +630,11 @@ + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty jetty-deploy @@ -636,12 +668,12 @@ org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} @@ -689,8 +721,8 @@ jboss-logging - org.eclipse.jetty.cdi - cdi-2 + org.eclipse.jetty + jetty-cdi ${project.version} @@ -723,6 +755,11 @@ jetty-alpn-java-server ${project.version} + + org.eclipse.jetty + jetty-openid + ${project.version} + org.eclipse.jetty jetty-alpn-conscrypt-server diff --git a/jetty-home/src/main/resources/etc/jetty-setuid.xml b/jetty-home/src/main/resources/etc/jetty-setuid.xml index 2fd25150b6c..3c70cbb266f 100644 --- a/jetty-home/src/main/resources/etc/jetty-setuid.xml +++ b/jetty-home/src/main/resources/etc/jetty-setuid.xml @@ -6,13 +6,16 @@ - + + + + - + diff --git a/jetty-home/src/main/resources/etc/logging-jul-capture.xml b/jetty-home/src/main/resources/etc/logging-jul-capture.xml new file mode 100644 index 00000000000..a701abe77c1 --- /dev/null +++ b/jetty-home/src/main/resources/etc/logging-jul-capture.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/jetty-util/src/main/config/modules/slf4j-api.mod b/jetty-home/src/main/resources/modules/logging-jcl-capture.mod similarity index 74% rename from jetty-util/src/main/config/modules/slf4j-api.mod rename to jetty-home/src/main/resources/modules/logging-jcl-capture.mod index 70c7b548249..78f59c7fb1b 100644 --- a/jetty-util/src/main/config/modules/slf4j-api.mod +++ b/jetty-home/src/main/resources/modules/logging-jcl-capture.mod @@ -1,23 +1,23 @@ -DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Provides SLF4J API. Requires a slf4j implementation (eg slf4j-simple-impl) -otherwise a noop implementation is used. +Capture jakarta-commons-logging events and bridge them to org.slf4j [tags] logging -slf4j -internal + +[depends] +logging/slf4j +logging + +[provides] +commons-logging [files] -maven://org.slf4j/slf4j-api/${slf4j.version}|lib/slf4j/slf4j-api-${slf4j.version}.jar +maven://org.slf4j/jcl-over-slf4j/%{slf4j.version}|jcl-over-slf4j-${slf4j.version}.jar [lib] -lib/slf4j/slf4j-api-${slf4j.version}.jar - -[ini] -slf4j.version?=1.8.0-beta2 -jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/slf4j/ +lib/logging/jcl-over-slf4j-${slf4j.version}.jar [license] SLF4J is distributed under the MIT License. @@ -42,3 +42,5 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + diff --git a/jetty-home/src/main/resources/modules/logging-jetty.mod b/jetty-home/src/main/resources/modules/logging-jetty.mod new file mode 100644 index 00000000000..71da0e34905 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-jetty.mod @@ -0,0 +1,24 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure jetty logging mechanism. +Provides a ${jetty.base}/resources/jetty-logging.properties. + +[tags] +logging + +[depends] +logging/slf4j +resources + +[provides] +logging|default + +[files] +basehome:modules/logging/jetty + +[lib] +lib/logging/jetty-slf4j-impl-${jetty.version}.jar + +[ini] +jetty.webapp.addServerClasses+=,org.eclipse.jetty.logging. diff --git a/jetty-home/src/main/resources/modules/logging-jul-capture.mod b/jetty-home/src/main/resources/modules/logging-jul-capture.mod new file mode 100644 index 00000000000..5401a052c17 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-jul-capture.mod @@ -0,0 +1,47 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Capture java.util.logging events and bridge them to org.slf4j + +[tags] +logging + +[depends] +logging/slf4j +logging + +[provides] +java-util-logging + +[xml] +etc/logging-jul-capture.xml + +[files] +maven://org.slf4j/jul-to-slf4j/%{slf4j.version}|jul-to-slf4j-${slf4j.version}.jar + +[lib] +lib/logging/jul-to-slf4j-${slf4j.version}.jar + +[license] +SLF4J is distributed under the MIT License. +Copyright (c) 2004-2013 QOS.ch +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/jetty-home/src/main/resources/modules/logging-jul.mod b/jetty-home/src/main/resources/modules/logging-jul.mod new file mode 100644 index 00000000000..4bf63a0924b --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-jul.mod @@ -0,0 +1,53 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure jetty logging to use Java Util Logging (jul) +SLF4J is used as the core logging mechanism. + +[tags] +logging + +[depends] +logging/slf4j +resources + +[provides] +logging +java-util-logging + +[files] +basehome:modules/logging/jul +maven://org.slf4j/slf4j-jdk14/${slf4j.version}|lib/logging/slf4j-jdk14-${slf4j.version}.jar + +[lib] +lib/logging/slf4j-jdk14-${slf4j.version}.jar + +[ini] +slf4j.version?=2.0.0-alpha1 +java.util.logging.config.file=${jetty.base}/resources/java-util-logging.properties + +[license] +SLF4J is distributed under the MIT License. +Copyright (c) 2004-2013 QOS.ch +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + diff --git a/jetty-home/src/main/resources/modules/logging-log4j1-capture.mod b/jetty-home/src/main/resources/modules/logging-log4j1-capture.mod new file mode 100644 index 00000000000..41dca46cf85 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-log4j1-capture.mod @@ -0,0 +1,44 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Capture Apache log4j events and bridge them to org.slf4j + +[tags] +logging + +[depends] +logging/slf4j +logging + +[provides] +log4j + +[files] +maven://org.slf4j/jcl-over-slf4j/%{slf4j.version}|jcl-over-slf4j-${slf4j.version}.jar + +[lib] +lib/logging/log4j-to-slf4j-${slf4j.version}.jar + +[license] +SLF4J is distributed under the MIT License. +Copyright (c) 2004-2013 QOS.ch +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/jetty-home/src/main/resources/modules/logging-log4j1.mod b/jetty-home/src/main/resources/modules/logging-log4j1.mod new file mode 100644 index 00000000000..ef7332070e7 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-log4j1.mod @@ -0,0 +1,58 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure jetty logging to use Log4j Logging +SLF4J is used as the core logging mechanism. + +[tags] +logging + +[depends] +logging/slf4j +resources + +[provides] +logging +log4j + +[files] +basehome:modules/logging/log4j1 +maven://log4j/log4j/${log4j.version}|lib/logging/log4j-${log4j.version}.jar +maven://org.slf4j/slf4j-log4j12/${slf4j.version}|lib/logging/slf4j-log4j12-${slf4j.version}.jar + +[lib] +lib/logging/slf4j-log4j12-${slf4j.version}.jar +lib/logging/log4j-${log4j.version}.jar + +[ini] +log4j.version?=1.2.17 +jetty.webapp.addServerClasses+=,org.apache.log4j. + + +[license] +Log4j is released under the Apache 2.0 license. +http://www.apache.org/licenses/LICENSE-2.0.html + + +SLF4J is distributed under the MIT License. +Copyright (c) 2004-2013 QOS.ch +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/jetty-home/src/main/resources/modules/logging-log4j2.mod b/jetty-home/src/main/resources/modules/logging-log4j2.mod new file mode 100644 index 00000000000..784320b33ab --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-log4j2.mod @@ -0,0 +1,35 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure jetty logging to use log4j version 2 +SLF4J is used as the core logging mechanism. + +[tags] +logging + +[depends] +logging/slf4j +resources + +[provides] +logging +log4j + +[files] +basehome:modules/logging/log4j2 +maven://org.apache.logging.log4j/log4j-slf4j18-impl/${log4j.version}|lib/logging/log4j-slf4j18-impl-${log4j.version}.jar +maven://org.apache.logging.log4j/log4j-api/${log4j.version}|lib/logging/log4j-api-${log4j.version}.jar +maven://org.apache.logging.log4j/log4j-core/${log4j.version}|lib/logging/log4j-core-${log4j.version}.jar + +[lib] +lib/logging/log4j-slf4j18-impl-${log4j.version}.jar +lib/logging/log4j-api-${log4j.version}.jar +lib/logging/log4j-core-${log4j.version}.jar + +[ini] +log4j.version?=2.13.0 +jetty.webapp.addServerClasses+=,org.apache.logging.log4j. + +[license] +Log4j is released under the Apache 2.0 license. +http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/jetty-home/src/main/resources/modules/logging-logback.mod b/jetty-home/src/main/resources/modules/logging-logback.mod new file mode 100644 index 00000000000..cdffd67921f --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-logback.mod @@ -0,0 +1,45 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure jetty logging to use Logback Logging. +SLF4J is used as the core logging mechanism. + +[tags] +logging + +[depends] +logging/slf4j +resources + +[provides] +logging + +[files] +basehome:modules/logging/logback +maven://ch.qos.logback/logback-classic/${logback.version}|lib/logging/logback-classic-${logback.version}.jar +maven://ch.qos.logback/logback-core/${logback.version}|lib/logging/logback-core-${logback.version}.jar + +[lib] +lib/logging/logback-classic-${logback.version}.jar +lib/logging/logback-core-${logback.version}.jar + +[ini] +logback.version?=1.3.0-alpha5 +jetty.webapp.addServerClasses+=,ch.qos.logback. + +[license] +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2012, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either: + + the terms of the Eclipse Public License v1.0 + as published by the Eclipse Foundation: + http://www.eclipse.org/legal/epl-v10.html + +or (per the licensee's choosing) under + + the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation: + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html diff --git a/jetty-home/src/main/resources/modules/logging-noop.mod b/jetty-home/src/main/resources/modules/logging-noop.mod new file mode 100644 index 00000000000..2a8c3743c47 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging-noop.mod @@ -0,0 +1,13 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure logging to use SLF4J No-Op Implementation + +[tags] +logging + +[provides] +logging + +[depends] +logging/slf4j diff --git a/jetty-home/src/main/resources/modules/logging/jetty/resources/jetty-logging.properties b/jetty-home/src/main/resources/modules/logging/jetty/resources/jetty-logging.properties new file mode 100644 index 00000000000..d0fdf6c5bd5 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging/jetty/resources/jetty-logging.properties @@ -0,0 +1,8 @@ +## Set logging levels from: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF +org.eclipse.jetty.LEVEL=INFO +## Configure a level for an arbitrary logger tree +#com.example.LEVEL=INFO +## Configure a level for specific logger +#com.example.MyComponent.LEVEL=INFO +## Hide stacks traces in an arbitrary logger tree +#com.example.STACKS=false diff --git a/jetty-home/src/main/resources/modules/logging/jul/resources/java-util-logging.properties b/jetty-home/src/main/resources/modules/logging/jul/resources/java-util-logging.properties new file mode 100644 index 00000000000..a09450fc280 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging/jul/resources/java-util-logging.properties @@ -0,0 +1,13 @@ +.level=INFO +handlers=java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level=INFO +java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter +## Note: The java.util.logging.SimpleFormatter does NOT have the ability to display +## the Thread name of when the logging event occurred, this will make debugging difficult +## See https://stackoverflow.com/questions/6889057/printing-thread-name-using-java-util-logging +java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS [%4$s] (%3$s) - %5$s%6$s%n +#handlers = java.util.logging.FileHandler +#java.util.logging.FileHandler.pattern = ${jetty.logging.dir}/jetty%u.log +#java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter + + diff --git a/jetty-home/src/main/resources/modules/logging/log4j1/resources/log4j.xml b/jetty-home/src/main/resources/modules/logging/log4j1/resources/log4j.xml new file mode 100644 index 00000000000..b4bf0ae6994 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging/log4j1/resources/log4j.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jetty-home/src/main/resources/modules/logging/log4j2/resources/log4j2.xml b/jetty-home/src/main/resources/modules/logging/log4j2/resources/log4j2.xml new file mode 100644 index 00000000000..f20a1d40515 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging/log4j2/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/jetty-home/src/main/resources/modules/logging/logback/resources/logback.xml b/jetty-home/src/main/resources/modules/logging/logback/resources/logback.xml new file mode 100644 index 00000000000..23a6dbc24da --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging/logback/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%level] :%thread: \(%logger\) - %msg%n + + + + + + + \ No newline at end of file diff --git a/jetty-home/src/main/resources/modules/logging/slf4j.mod b/jetty-home/src/main/resources/modules/logging/slf4j.mod new file mode 100644 index 00000000000..67387a2c1f5 --- /dev/null +++ b/jetty-home/src/main/resources/modules/logging/slf4j.mod @@ -0,0 +1,18 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Configure logging to use slf4j with no impl +(If you don't select an impl, then NOP will be used by slf4j) + +[tags] +logging + +[provides] +slf4j + +[lib] +lib/logging/slf4j-api-${slf4j.version}.jar + +[ini] +slf4j.version?=2.0.0-alpha1 +jetty.webapp.addServerClasses+=,org.slf4j. diff --git a/jetty-home/src/main/resources/modules/setuid.mod b/jetty-home/src/main/resources/modules/setuid.mod index be4f8476714..a50ed698b9f 100644 --- a/jetty-home/src/main/resources/modules/setuid.mod +++ b/jetty-home/src/main/resources/modules/setuid.mod @@ -1,4 +1,4 @@ -DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] Enables the unix setUID configuration so that the server @@ -9,7 +9,7 @@ changing to a restricted user (eg jetty). server [lib] -lib/setuid/jetty-setuid-java-1.0.3.jar +lib/setuid/jetty-setuid-java-1.0.4.jar [xml] etc/jetty-setuid.xml @@ -20,3 +20,4 @@ etc/jetty-setuid.xml # jetty.setuid.userName=jetty # jetty.setuid.groupName=jetty # jetty.setuid.umask=002 +# jetty.setuid.clearSupplementalGroups=false diff --git a/jetty-home/start.ini b/jetty-home/start.ini deleted file mode 100644 index 215582944fe..00000000000 --- a/jetty-home/start.ini +++ /dev/null @@ -1,9 +0,0 @@ -# --------------------------------------- -# Module: session-store-infinispan-embedded -# Enables session data store in a local Infinispan cache -# --------------------------------------- ---module=session-store-infinispan-embedded - -#jetty.session.gracePeriod.seconds=3600 -#jetty.session.savePeriod.seconds=0 - diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 2fb509cd685..7ae35abd45d 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -35,6 +35,22 @@ ${project.version} provided + + org.slf4j + slf4j-api + provided + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + test + + + org.eclipse.jetty + jetty-slf4j-impl + test + javax.xml jaxws-api diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/DelegatingThreadPool.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/DelegatingThreadPool.java index 9dac2add752..7f967c7b0cf 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/DelegatingThreadPool.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/DelegatingThreadPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java index 8753e30493f..0e1caf4b3ed 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; @@ -35,15 +35,15 @@ import com.sun.net.httpserver.HttpPrincipal; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Jetty handler that bridges requests to {@link HttpHandler}. */ public class HttpSpiContextHandler extends ContextHandler { - public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class); + public static final Logger LOG = LoggerFactory.getLogger(HttpSpiContextHandler.class); private HttpContext _httpContext; @@ -89,7 +89,7 @@ public class HttpSpiContextHandler extends ContextHandler } catch (Exception ex) { - LOG.debug(ex); + LOG.debug("Failed to handle", ex); PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody()); resp.setStatus(500); diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyExchange.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyExchange.java index ecb02f41bac..a3ab811ee7c 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyExchange.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyExchange.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java index 98da2cad6a4..5b87d4b87bd 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java index 01ab7408c42..7a28daac9a9 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java index 20ba1c4bcb4..157d84592ff 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java index 0733ac6a2f6..5d5ab6d670a 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; @@ -36,16 +36,16 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Jetty implementation of {@link com.sun.net.httpserver.HttpServer}. */ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer { - private static final Logger LOG = Log.getLogger(JettyHttpServer.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyHttpServer.class); private final HttpConfiguration _httpConfiguration; @@ -223,7 +223,7 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer } catch (Exception ex) { - LOG.warn(ex); + LOG.warn("Unable to stop connector {}", connector, ex); } _server.removeConnector(connector); } diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java index 6809d698577..43ab5f8242e 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java index 02e0e82498b..99426f059da 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; @@ -171,9 +171,6 @@ public class JettyHttpsExchange extends HttpsExchange implements JettyExchange return _delegate.toString(); } - /** - * @see com.sun.net.httpserver.HttpsExchange#getSSLSession() - */ @Override public SSLSession getSSLSession() { diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/LoggingUtil.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/LoggingUtil.java new file mode 100644 index 00000000000..b3c27d24688 --- /dev/null +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/LoggingUtil.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http.spi; + +public final class LoggingUtil +{ + /** + * It's easier to setup logging in code for this test project, + * then it is to setup the various system properties and files for every test + * execution (maven, CI, and IDE). + */ + public static void init() + { + // Wire up java.util.logging (used by javax.xml.soap others) to slf4j. + org.slf4j.bridge.SLF4JBridgeHandler.removeHandlersForRootLogger(); + org.slf4j.bridge.SLF4JBridgeHandler.install(); + } +} diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/SPIServerTest.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/SPIServerTest.java index e2a8b8ece06..9933369a5c7 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/SPIServerTest.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/SPIServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; @@ -44,6 +44,11 @@ import static org.hamcrest.Matchers.is; public class SPIServerTest { + static + { + LoggingUtil.init(); + } + String host = "localhost"; HttpServer server; int port; diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java index e488b24aa2d..702d90f01ed 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; @@ -41,17 +41,21 @@ import org.junit.jupiter.api.Test; public class TestEndpointMultiplePublishProblem { + static + { + LoggingUtil.init(); + } private static String default_impl = System.getProperty("com.sun.net.httpserver.HttpServerProvider"); @BeforeAll - public static void change_Impl() + public static void changeImpl() { System.setProperty("com.sun.net.httpserver.HttpServerProvider", JettyHttpServerProvider.class.getName()); } @AfterAll - public static void restore_Impl() + public static void restoreImpl() { if (default_impl != null) { diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java index 1b44817bd46..0893db6aa2f 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi; @@ -42,6 +42,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class TestSPIServer { + static + { + LoggingUtil.init(); + } /** * Create a server that has a null InetSocketAddress, then diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/Pool.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/Pool.java index ea5e6335813..7175e2c8b2d 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/Pool.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/Pool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi.util; diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/PrintTask.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/PrintTask.java index e9a3a9e7dc6..d112ceb56b6 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/PrintTask.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/PrintTask.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi.util; diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiConstants.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiConstants.java index 7520135a898..06202ff944b 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiConstants.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiConstants.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi.util; diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiUtility.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiUtility.java index 0ea8a3c8b39..264a880cc25 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiUtility.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiUtility.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.spi.util; diff --git a/jetty-http-spi/src/test/resources/jetty-logging.properties b/jetty-http-spi/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..f602bee5c31 --- /dev/null +++ b/jetty-http-spi/src/test/resources/jetty-logging.properties @@ -0,0 +1,5 @@ +# Jetty Logging using jetty-slf4j-impl +org.eclipse.jetty.logging.appender.NAME_CONDENSE=false +org.eclipse.jetty.logging.appender.MESSAGE_ESCAPE=false +# org.eclipse.jetty.LEVEL=WARN +log.LEVEL=INFO diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index a5071238200..b4c0b9677a6 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -26,11 +26,15 @@ ${project.version} - org.eclipse.jetty.toolchain - jetty-servlet-api - true + org.slf4j + slf4j-api + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper @@ -40,14 +44,6 @@ - - maven-surefire-plugin - - - @{argLine} ${jetty.surefire.argLine} --add-modules jetty.servlet.api - - - org.apache.felix maven-bundle-plugin diff --git a/jetty-http/src/main/java/module-info.java b/jetty-http/src/main/java/module-info.java index c15d7c01f3f..918c69b7735 100644 --- a/jetty-http/src/main/java/module-info.java +++ b/jetty-http/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.http.Http1FieldPreEncoder; @@ -24,11 +24,8 @@ module org.eclipse.jetty.http exports org.eclipse.jetty.http; exports org.eclipse.jetty.http.pathmap; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; - - // Only required if using the MultiPart classes. - requires static jetty.servlet.api; + requires transitive org.eclipse.jetty.io; + requires org.slf4j; uses HttpFieldPreEncoder; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java b/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java index 84c446edd9f..57f11e003c3 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/ComplianceViolation.java b/jetty-http/src/main/java/org/eclipse/jetty/http/ComplianceViolation.java index b0ec773e161..0723a3bc7f1 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/ComplianceViolation.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/ComplianceViolation.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/CompressedContentFormat.java b/jetty-http/src/main/java/org/eclipse/jetty/http/CompressedContentFormat.java index dfe8c9db79f..93fc1eff338 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/CompressedContentFormat.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/CompressedContentFormat.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java b/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java index 48a80eda6f5..0f012844dc6 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -34,7 +34,7 @@ import static java.util.EnumSet.noneOf; */ public class CookieCompliance implements ComplianceViolation.Mode { - enum Violation implements ComplianceViolation + public enum Violation implements ComplianceViolation { COMMA_NOT_VALID_OCTET("https://tools.ietf.org/html/rfc6265#section-4.1.1", "Comma not valid as cookie-octet or separator"), RESERVED_NAMES_NOT_DOLLAR_PREFIXED("https://tools.ietf.org/html/rfc6265#section-4.1.1", "Reserved names no longer use '$' prefix"); @@ -57,13 +57,13 @@ public class CookieCompliance implements ComplianceViolation.Mode @Override public String getURL() { - return null; + return url; } @Override public String getDescription() { - return null; + return description; } } @@ -87,9 +87,8 @@ public class CookieCompliance implements ComplianceViolation.Mode private CookieCompliance(String name, Set violations) { - Objects.nonNull(violations); _name = name; - _violations = unmodifiableSet(copyOf(violations)); + _violations = unmodifiableSet(copyOf(Objects.requireNonNull(violations))); } @Override diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java b/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java index a5a4ac64952..570daca5159 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -21,8 +21,8 @@ package org.eclipse.jetty.http; import java.util.List; import java.util.Locale; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.http.CookieCompliance.Violation.COMMA_NOT_VALID_OCTET; import static org.eclipse.jetty.http.CookieCompliance.Violation.RESERVED_NAMES_NOT_DOLLAR_PREFIXED; @@ -32,7 +32,7 @@ import static org.eclipse.jetty.http.CookieCompliance.Violation.RESERVED_NAMES_N */ public abstract class CookieCutter { - protected static final Logger LOG = Log.getLogger(CookieCutter.class); + protected static final Logger LOG = LoggerFactory.getLogger(CookieCutter.class); protected final CookieCompliance _complianceMode; private final ComplianceViolation.Listener _complianceListener; @@ -64,15 +64,14 @@ public abstract class CookieCutter boolean inQuoted = false; boolean quoted = false; boolean escaped = false; + boolean reject = false; int tokenstart = -1; int tokenend = -1; for (int i = 0, length = hdr.length(); i <= length; i++) { char c = i == length ? 0 : hdr.charAt(i); - // System.err.printf("i=%d/%d c=%s v=%b q=%b/%b e=%b u=%s s=%d e=%d \t%s=%s%n" ,i,length,c==0?"|":(""+c),invalue,inQuoted,quoted,escaped,unquoted,tokenstart,tokenend,name,value); - - // Handle quoted values for name or value + // Handle quoted values for value if (inQuoted) { if (escaped) @@ -119,7 +118,7 @@ public abstract class CookieCutter // Handle name and value state machines if (invalue) { - // parse the value + // parse the cookie-value switch (c) { case ' ': @@ -193,7 +192,11 @@ public abstract class CookieCutter // This is a new cookie, so add the completed last cookie if we have one if (cookieName != null) { - addCookie(cookieName, cookieValue, cookieDomain, cookiePath, cookieVersion, cookieComment); + if (!reject) + { + addCookie(cookieName, cookieValue, cookieDomain, cookiePath, cookieVersion, cookieComment); + reject = false; + } cookieDomain = null; cookiePath = null; cookieComment = null; @@ -204,7 +207,7 @@ public abstract class CookieCutter } catch (Exception e) { - LOG.debug(e); + LOG.debug("Unable to process Cookie", e); } name = null; @@ -234,6 +237,15 @@ public abstract class CookieCutter quoted = false; continue; } + + if (_complianceMode == CookieCompliance.RFC6265) + { + if (isRFC6265RejectedCharacter(inQuoted, c)) + { + reject = true; + } + } + if (tokenstart < 0) tokenstart = i; tokenend = i; @@ -242,13 +254,26 @@ public abstract class CookieCutter } else { - // parse the name + // parse the cookie-name switch (c) { + case 0: case ' ': case '\t': continue; + case '"': + // Quoted name is not allowed in any version of the Cookie spec + reject = true; + break; + + case ';': + // a cookie terminated with no '=' sign. + tokenstart = -1; + invalue = false; + reject = false; + continue; + case '=': if (quoted) { @@ -272,6 +297,15 @@ public abstract class CookieCutter quoted = false; continue; } + + if (_complianceMode == CookieCompliance.RFC6265) + { + if (isRFC6265RejectedCharacter(inQuoted, c)) + { + reject = true; + } + } + if (tokenstart < 0) tokenstart = i; tokenend = i; @@ -281,7 +315,7 @@ public abstract class CookieCutter } } - if (cookieName != null) + if (cookieName != null && !reject) addCookie(cookieName, cookieValue, cookieDomain, cookiePath, cookieVersion, cookieComment); } } @@ -295,4 +329,31 @@ public abstract class CookieCutter } protected abstract void addCookie(String cookieName, String cookieValue, String cookieDomain, String cookiePath, int cookieVersion, String cookieComment); + + protected boolean isRFC6265RejectedCharacter(boolean inQuoted, char c) + { + if (inQuoted) + { + // We only reject if a Control Character is encountered + if (Character.isISOControl(c)) + { + return true; + } + } + else + { + /* From RFC6265 - Section 4.1.1 - Syntax + * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + * ; US-ASCII characters excluding CTLs, + * ; whitespace DQUOTE, comma, semicolon, + * ; and backslash + */ + return Character.isISOControl(c) || // control characters + c > 127 || // 8-bit characters + c == ',' || // comma + c == ';'; // semicolon + } + + return false; + } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/DateGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/DateGenerator.java index 4b0cf79a3f5..40170cc8266 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/DateGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/DateGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/DateParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/DateParser.java index 073d26d700b..6b4c69cce68 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/DateParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/DateParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java index 6ca334aba29..518e6ab710a 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -37,13 +37,16 @@ import org.eclipse.jetty.util.component.Destroyable; */ public class GZIPContentDecoder implements Destroyable { + // Unsigned Integer Max == 2^32 + private static final long UINT_MAX = 0xFFFFFFFFL; + private final List _inflateds = new ArrayList<>(); private final Inflater _inflater = new Inflater(true); private final ByteBufferPool _pool; private final int _bufferSize; private State _state; private int _size; - private int _value; + private long _value; private byte _flags; private ByteBuffer _inflated; @@ -375,11 +378,12 @@ public class GZIPContentDecoder implements Destroyable } case ISIZE: { - _value += (currByte & 0xFF) << 8 * _size; + _value = _value | ((currByte & 0xFFL) << (8 * _size)); ++_size; if (_size == 4) { - if (_value != _inflater.getBytesWritten()) + // RFC 1952: Section 2.3.1; ISIZE is the input size modulo 2^32 + if (_value != (_inflater.getBytesWritten() & UINT_MAX)) throw new ZipException("Invalid input size"); // TODO ByteBuffer result = output == null ? BufferUtil.EMPTY_BUFFER : ByteBuffer.wrap(output); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java index 2379bcef99e..1bda127bec3 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -21,7 +21,7 @@ package org.eclipse.jetty.http; import org.eclipse.jetty.util.HostPort; /** - * A HttpField holding a preparsed Host and port number + * An HttpField holding a preparsed Host and port number * * @see HostPort */ diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java index 41f80514143..9308fd3450d 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -28,18 +28,12 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1; public class Http1FieldPreEncoder implements HttpFieldPreEncoder { - /** - * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getHttpVersion() - */ @Override public HttpVersion getHttpVersion() { return HttpVersion.HTTP_1_0; } - /** - * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getEncodedField(org.eclipse.jetty.http.HttpHeader, java.lang.String, java.lang.String) - */ @Override public byte[] getEncodedField(HttpHeader header, String headerString, String value) { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java index 9a19d3cf675..a0017569bf8 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -25,8 +25,8 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.util.Arrays.asList; import static java.util.Collections.unmodifiableSet; @@ -84,7 +84,7 @@ public final class HttpCompliance implements ComplianceViolation.Mode } } - private static final Logger LOG = Log.getLogger(HttpParser.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpParser.class); public static final String VIOLATIONS_ATTR = "org.eclipse.jetty.http.compliance.violations"; public static final HttpCompliance RFC7230 = new HttpCompliance("RFC7230", noneOf(Violation.class)); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java index 858f21d3fcd..a416226921d 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java index e52ec2dee6a..219e9c13584 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java @@ -1,34 +1,75 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; import java.util.List; +import java.util.Locale; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.QuotedStringTokenizer; +import org.eclipse.jetty.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -// TODO consider replacing this with java.net.HttpCookie +// TODO consider replacing this with java.net.HttpCookie (once it supports RFC6265) public class HttpCookie { + private static final Logger LOG = LoggerFactory.getLogger(HttpCookie.class); + private static final String __COOKIE_DELIM = "\",;\\ \t"; private static final String __01Jan1970_COOKIE = DateGenerator.formatCookieDate(0).trim(); + /** + *If this string is found within the comment parsed with {@link #isHttpOnlyInComment(String)} the check will return true + **/ + public static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__"; + /** + *These strings are used by {@link #getSameSiteFromComment(String)} to check for a SameSite specifier in the comment + **/ + private static final String SAME_SITE_COMMENT = "__SAME_SITE_"; + public static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__"; + public static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__"; + public static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__"; + + /** + * Name of context attribute with default SameSite cookie value + */ + public static final String SAME_SITE_DEFAULT_ATTRIBUTE = "org.eclipse.jetty.cookie.sameSiteDefault"; + + public enum SameSite + { + NONE("None"), STRICT("Strict"), LAX("Lax"); + + private String attributeValue; + + SameSite(String attributeValue) + { + this.attributeValue = attributeValue; + } + + public String getAttributeValue() + { + return this.attributeValue; + } + } + private final String _name; private final String _value; private final String _comment; @@ -39,6 +80,7 @@ public class HttpCookie private final int _version; private final boolean _httpOnly; private final long _expiration; + private final SameSite _sameSite; public HttpCookie(String name, String value) { @@ -61,6 +103,11 @@ public class HttpCookie } public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version) + { + this(name, value, domain, path, maxAge, httpOnly, secure, comment, version, null); + } + + public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version, SameSite sameSite) { _name = name; _value = value; @@ -72,6 +119,7 @@ public class HttpCookie _comment = comment; _version = version; _expiration = maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(maxAge); + _sameSite = sameSite; } public HttpCookie(String setCookie) @@ -92,6 +140,8 @@ public class HttpCookie _comment = cookie.getComment(); _version = cookie.getVersion(); _expiration = _maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(_maxAge); + // support for SameSite values has not yet been added to java.net.HttpCookie + _sameSite = getSameSiteFromComment(cookie.getComment()); } /** @@ -158,6 +208,14 @@ public class HttpCookie return _version; } + /** + * @return the cookie SameSite enum attribute + */ + public SameSite getSameSite() + { + return _sameSite; + } + /** * @return whether the cookie is valid for the http protocol only */ @@ -231,7 +289,6 @@ public class HttpCookie return getRFC6265SetCookie(); if (compliance == CookieCompliance.RFC2965) return getRFC2965SetCookie(); - throw new IllegalStateException(); } @@ -363,9 +420,132 @@ public class HttpCookie buf.append("; Secure"); if (_httpOnly) buf.append("; HttpOnly"); + if (_sameSite != null) + { + buf.append("; SameSite="); + buf.append(_sameSite.getAttributeValue()); + } + return buf.toString(); } + public static boolean isHttpOnlyInComment(String comment) + { + return comment != null && comment.contains(HTTP_ONLY_COMMENT); + } + + public static SameSite getSameSiteFromComment(String comment) + { + if (comment != null) + { + if (comment.contains(SAME_SITE_STRICT_COMMENT)) + { + return SameSite.STRICT; + } + if (comment.contains(SAME_SITE_LAX_COMMENT)) + { + return SameSite.LAX; + } + if (comment.contains(SAME_SITE_NONE_COMMENT)) + { + return SameSite.NONE; + } + } + + return null; + } + + /** + * Get the default value for SameSite cookie attribute, if one + * has been set for the given context. + * + * @param contextAttributes the context to check for default SameSite value + * @return the default SameSite value or null if one does not exist + * @throws IllegalStateException if the default value is not a permitted value + */ + public static SameSite getSameSiteDefault(Attributes contextAttributes) + { + if (contextAttributes == null) + return null; + Object o = contextAttributes.getAttribute(SAME_SITE_DEFAULT_ATTRIBUTE); + if (o == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("No default value for SameSite"); + return null; + } + + if (o instanceof SameSite) + return (SameSite)o; + + try + { + SameSite samesite = Enum.valueOf(SameSite.class, o.toString().trim().toUpperCase(Locale.ENGLISH)); + contextAttributes.setAttribute(SAME_SITE_DEFAULT_ATTRIBUTE, samesite); + return samesite; + } + catch (Exception e) + { + LOG.warn("Bad default value {} for SameSite", o); + throw new IllegalStateException(e); + } + } + + public static String getCommentWithoutAttributes(String comment) + { + if (comment == null) + { + return null; + } + + String strippedComment = comment.trim(); + + strippedComment = StringUtil.strip(strippedComment, HTTP_ONLY_COMMENT); + strippedComment = StringUtil.strip(strippedComment, SAME_SITE_NONE_COMMENT); + strippedComment = StringUtil.strip(strippedComment, SAME_SITE_LAX_COMMENT); + strippedComment = StringUtil.strip(strippedComment, SAME_SITE_STRICT_COMMENT); + + return strippedComment.length() == 0 ? null : strippedComment; + } + + public static String getCommentWithAttributes(String comment, boolean httpOnly, SameSite sameSite) + { + if (comment == null && sameSite == null) + return null; + + StringBuilder builder = new StringBuilder(); + if (StringUtil.isNotBlank(comment)) + { + comment = getCommentWithoutAttributes(comment); + if (StringUtil.isNotBlank(comment)) + builder.append(comment); + } + if (httpOnly) + builder.append(HTTP_ONLY_COMMENT); + + if (sameSite != null) + { + switch (sameSite) + { + case NONE: + builder.append(SAME_SITE_NONE_COMMENT); + break; + case STRICT: + builder.append(SAME_SITE_STRICT_COMMENT); + break; + case LAX: + builder.append(SAME_SITE_LAX_COMMENT); + break; + default: + throw new IllegalArgumentException(sameSite.toString()); + } + } + + if (builder.length() == 0) + return null; + return builder.toString(); + } + public static class SetCookieHttpField extends HttpField { final HttpCookie _cookie; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java index e69af07893f..4dc702e4211 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -23,7 +23,7 @@ import java.util.Objects; import org.eclipse.jetty.util.StringUtil; /** - * A HTTP Field + * An HTTP Field */ public class HttpField { @@ -37,7 +37,10 @@ public class HttpField public HttpField(HttpHeader header, String name, String value) { _header = header; - _name = name; + if (_header != null && name == null) + _name = _header.asString(); + else + _name = Objects.requireNonNull(name); _value = value; } @@ -66,6 +69,11 @@ public class HttpField return _name; } + public String getLowerCaseName() + { + return _header != null ? _header.lowerCaseName() : StringUtil.asciiToLowerCase(_name); + } + public String getValue() { return _value; @@ -327,8 +335,6 @@ public class HttpField return false; if (!_name.equalsIgnoreCase(field.getName())) return false; - if (_value == null && field.getValue() != null) - return false; return Objects.equals(_value, field.getValue()); } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFieldPreEncoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFieldPreEncoder.java index c22fc7ae960..389c8e5e3d3 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFieldPreEncoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFieldPreEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java index ba4022b4861..7def4fdcfc4 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -34,8 +34,8 @@ import java.util.function.ToIntFunction; import java.util.stream.Stream; import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * HTTP Fields. A collection of HTTP header and or Trailer fields. @@ -47,7 +47,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HttpFields implements Iterable { - private static final Logger LOG = Log.getLogger(HttpFields.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpFields.class); private HttpField[] _fields; private int _size; @@ -896,7 +896,7 @@ public class HttpFields implements Iterable } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get fields as String", e); return e.toString(); } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index f55569858c1..c488b990403 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -29,8 +29,8 @@ import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.http.HttpStatus.INTERNAL_SERVER_ERROR_500; @@ -44,7 +44,7 @@ import static org.eclipse.jetty.http.HttpStatus.INTERNAL_SERVER_ERROR_500; */ public class HttpGenerator { - private static final Logger LOG = Log.getLogger(HttpGenerator.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpGenerator.class); public static final boolean __STRICT = Boolean.getBoolean("org.eclipse.jetty.http.HttpGenerator.STRICT"); @@ -74,11 +74,12 @@ public class HttpGenerator NEED_CHUNK, // Need a small chunk buffer of CHUNK_SIZE NEED_INFO, // Need the request/response metadata info NEED_HEADER, // Need a buffer to build HTTP headers into + HEADER_OVERFLOW, // The header buffer overflowed NEED_CHUNK_TRAILER, // Need a large chunk buffer for last chunk and trailers FLUSH, // The buffers previously generated should be flushed CONTINUE, // Continue generating the message SHUTDOWN_OUT, // Need EOF to be signaled - DONE // Message generation complete + DONE // The current phase of generation is complete } // other statics @@ -250,7 +251,8 @@ public class HttpGenerator } catch (BufferOverflowException e) { - throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Request header too large", e); + LOG.trace("IGNORED", e); + return Result.HEADER_OVERFLOW; } catch (Exception e) { @@ -427,7 +429,8 @@ public class HttpGenerator } catch (BufferOverflowException e) { - throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Response header too large", e); + LOG.trace("IGNORED", e); + return Result.HEADER_OVERFLOW; } catch (Exception e) { @@ -686,17 +689,24 @@ public class HttpGenerator _endOfContent = EndOfContent.NO_CONTENT; // But it is an error if there actually is content - if (_contentPrepared > 0 || contentLength > 0) + if (_contentPrepared > 0) + throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Content for no content response"); + + if (contentLengthField) { - if (_contentPrepared == 0 && last) + if (response != null && response.getStatus() == HttpStatus.NOT_MODIFIED_304) + putContentLength(header, contentLength); + else if (contentLength > 0) { - // TODO discard content for backward compatibility with 9.3 releases - // TODO review if it is still needed in 9.4 or can we just throw. - content.clear(); - contentLength = 0; + if (_contentPrepared == 0 && last) + { + // TODO discard content for backward compatibility with 9.3 releases + // TODO review if it is still needed in 9.4 or can we just throw. + content.clear(); + } + else + throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Content for no content response"); } - else - throw new BadMessageException(INTERNAL_SERVER_ERROR_500, "Content for no content response"); } } // Else if we are HTTP/1.1 and the content length is unknown and we are either persistent diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java index 826e0cc3d45..f2ba9dc1b84 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -133,6 +133,7 @@ public enum HttpHeader C_AUTHORITY(":authority"), C_PATH(":path"), C_STATUS(":status"), + C_PROTOCOL(":protocol"), UNKNOWN("::UNKNOWN::"); @@ -149,6 +150,7 @@ public enum HttpHeader } private final String _string; + private final String _lowerCase; private final byte[] _bytes; private final byte[] _bytesColonSpace; private final ByteBuffer _buffer; @@ -156,11 +158,17 @@ public enum HttpHeader HttpHeader(String s) { _string = s; + _lowerCase = StringUtil.asciiToLowerCase(s); _bytes = StringUtil.getBytes(s); _bytesColonSpace = StringUtil.getBytes(s + ": "); _buffer = ByteBuffer.wrap(_bytes); } + public String lowerCaseName() + { + return _lowerCase; + } + public ByteBuffer toBuffer() { return _buffer.asReadOnlyBuffer(); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java index 996b070cdd5..e4d84eb72a4 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpMethod.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpMethod.java index 741be954df5..31d94223eaf 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpMethod.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpMethod.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -48,7 +48,7 @@ public enum HttpMethod * @param bytes Array containing ISO-8859-1 characters * @param position The first valid index * @param limit The first non valid index - * @return A HttpMethod if a match or null if no easy match. + * @return An HttpMethod if a match or null if no easy match. */ public static HttpMethod lookAheadGet(byte[] bytes, final int position, int limit) { @@ -110,7 +110,7 @@ public enum HttpMethod * Optimized lookup to find a method name and trailing space in a byte array. * * @param buffer buffer containing ISO-8859-1 characters, it is not modified. - * @return A HttpMethod if a match or null if no easy match. + * @return An HttpMethod if a match or null if no easy match. */ public static HttpMethod lookAheadGet(ByteBuffer buffer) { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index 26ef2ca2337..1d6db1f0cf9 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -24,7 +24,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Locale; -import org.eclipse.jetty.http.HttpCompliance.Violation; import org.eclipse.jetty.http.HttpTokens.EndOfContent; import org.eclipse.jetty.util.ArrayTernaryTrie; import org.eclipse.jetty.util.ArrayTrie; @@ -32,9 +31,11 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.eclipse.jetty.http.HttpCompliance.RFC7230; +import static org.eclipse.jetty.http.HttpCompliance.Violation; import static org.eclipse.jetty.http.HttpCompliance.Violation.CASE_SENSITIVE_FIELD_NAME; import static org.eclipse.jetty.http.HttpCompliance.Violation.MULTIPLE_CONTENT_LENGTHS; import static org.eclipse.jetty.http.HttpCompliance.Violation.NO_COLON_AFTER_FIELD_NAME; @@ -88,7 +89,7 @@ import static org.eclipse.jetty.http.HttpCompliance.Violation.WHITESPACE_AFTER_F */ public class HttpParser { - public static final Logger LOG = Log.getLogger(HttpParser.class); + public static final Logger LOG = LoggerFactory.getLogger(HttpParser.class); public static final int INITIAL_URI_LENGTH = 256; private static final int MAX_CHUNK_LENGTH = Integer.MAX_VALUE / 16 - 16; @@ -136,6 +137,7 @@ public class HttpParser CHUNK_SIZE, CHUNK_PARAMS, CHUNK, + CONTENT_END, TRAILER, END, CLOSE, // The associated stream/endpoint should be closed @@ -160,7 +162,6 @@ public class HttpParser private int _headerBytes; private boolean _host; private boolean _headerComplete; - private volatile State _state = State.START; private volatile FieldState _fieldState = FieldState.FIELD; private volatile boolean _eof; @@ -170,6 +171,7 @@ public class HttpParser private Utf8StringBuilder _uri = new Utf8StringBuilder(INITIAL_URI_LENGTH); // Tune? private EndOfContent _endOfContent; private boolean _hasContentLength; + private boolean _hasTransferEncoding; private long _contentLength = -1; private long _contentPosition; private int _chunkLength; @@ -178,9 +180,10 @@ public class HttpParser private boolean _cr; private ByteBuffer _contentChunk; private Trie _fieldCache; - private int _length; private final StringBuilder _string = new StringBuilder(); + private int _headerCacheSize = 1024; + private boolean _headerCacheCaseSensitive; static { @@ -237,7 +240,7 @@ public class HttpParser private static HttpCompliance compliance() { - return HttpCompliance.RFC7230; + return RFC7230; } public HttpParser(RequestHandler handler) @@ -290,6 +293,26 @@ public class HttpParser return _handler; } + public int getHeaderCacheSize() + { + return _headerCacheSize; + } + + public void setHeaderCacheSize(int headerCacheSize) + { + _headerCacheSize = headerCacheSize; + } + + public boolean isHeaderCacheCaseSensitive() + { + return _headerCacheCaseSensitive; + } + + public void setHeaderCacheCaseSensitive(boolean headerCacheCaseSensitive) + { + _headerCacheCaseSensitive = headerCacheCaseSensitive; + } + protected void checkViolation(Violation violation) throws BadMessageException { if (violation.isAllowedBy(_complianceMode)) @@ -442,7 +465,7 @@ public class HttpParser return t; } - /* Quick lookahead for the start state looking for a request method or a HTTP version, + /* Quick lookahead for the start state looking for a request method or an HTTP version, * otherwise skip white space until something else to parse. */ private boolean quickStart(ByteBuffer buffer) @@ -528,16 +551,19 @@ public class HttpParser { boolean handleHeader = _handler.headerComplete(); _headerComplete = true; - boolean handleContent = _handler.contentComplete(); - boolean handleMessage = _handler.messageComplete(); - return handleHeader || handleContent || handleMessage; + if (handleHeader) + return true; + setState(State.CONTENT_END); + return handleContentMessage(); } private boolean handleContentMessage() { boolean handleContent = _handler.contentComplete(); - boolean handleMessage = _handler.messageComplete(); - return handleContent || handleMessage; + if (handleContent) + return true; + setState(State.END); + return _handler.messageComplete(); } /* Parse a request or response line @@ -707,7 +733,7 @@ public class HttpParser case LF: setState(State.HEADER); - handle |= _responseHandler.startResponse(_version, _responseStatus, null); + _responseHandler.startResponse(_version, _responseStatus, null); break; default: @@ -725,10 +751,11 @@ public class HttpParser case LF: // HTTP/0.9 checkViolation(Violation.HTTP_0_9); - handle = _requestHandler.startRequest(_methodString, _uri.toString(), HttpVersion.HTTP_0_9); - setState(State.END); + _requestHandler.startRequest(_methodString, _uri.toString(), HttpVersion.HTTP_0_9); + setState(State.CONTENT); + _endOfContent = EndOfContent.NO_CONTENT; BufferUtil.clear(buffer); - handle |= handleHeaderContentMessage(); + handle = handleHeaderContentMessage(); break; case ALPHA: @@ -804,16 +831,17 @@ public class HttpParser if (_responseHandler != null) { setState(State.HEADER); - handle |= _responseHandler.startResponse(_version, _responseStatus, null); + _responseHandler.startResponse(_version, _responseStatus, null); } else { // HTTP/0.9 checkViolation(Violation.HTTP_0_9); - handle = _requestHandler.startRequest(_methodString, _uri.toString(), HttpVersion.HTTP_0_9); - setState(State.END); + _requestHandler.startRequest(_methodString, _uri.toString(), HttpVersion.HTTP_0_9); + setState(State.CONTENT); + _endOfContent = EndOfContent.NO_CONTENT; BufferUtil.clear(buffer); - handle |= handleHeaderContentMessage(); + handle = handleHeaderContentMessage(); } break; @@ -834,15 +862,13 @@ public class HttpParser checkVersion(); // Should we try to cache header fields? - if (_fieldCache == null && _version.getVersion() >= HttpVersion.HTTP_1_1.getVersion() && _handler.getHeaderCacheSize() > 0) - { - int headerCache = _handler.getHeaderCacheSize(); + int headerCache = getHeaderCacheSize(); + if (_fieldCache == null && _version.getVersion() >= HttpVersion.HTTP_1_1.getVersion() && headerCache > 0) _fieldCache = new ArrayTernaryTrie<>(headerCache); - } setState(State.HEADER); - handle |= _requestHandler.startRequest(_methodString, _uri.toString(), _version); + _requestHandler.startRequest(_methodString, _uri.toString(), _version); continue; case ALPHA: @@ -864,7 +890,7 @@ public class HttpParser case LF: String reason = takeString(); setState(State.HEADER); - handle |= _responseHandler.startResponse(_version, _responseStatus, reason); + _responseHandler.startResponse(_version, _responseStatus, reason); continue; case ALPHA: @@ -916,6 +942,9 @@ public class HttpParser switch (_header) { case CONTENT_LENGTH: + if (_hasTransferEncoding) + checkViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH); + if (_hasContentLength) { checkViolation(MULTIPLE_CONTENT_LENGTHS); @@ -924,9 +953,6 @@ public class HttpParser } _hasContentLength = true; - if (_endOfContent == EndOfContent.CHUNKED_CONTENT) - checkViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH); - if (_endOfContent != EndOfContent.CHUNKED_CONTENT) { _contentLength = convertContentLength(_valueString); @@ -938,9 +964,15 @@ public class HttpParser break; case TRANSFER_ENCODING: + _hasTransferEncoding = true; + if (_hasContentLength) checkViolation(TRANSFER_ENCODING_WITH_CONTENT_LENGTH); + // we encountered another Transfer-Encoding header, but chunked was already set + if (_endOfContent == EndOfContent.CHUNKED_CONTENT) + throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, chunked not last"); + if (HttpHeaderValue.CHUNKED.is(_valueString)) { _endOfContent = EndOfContent.CHUNKED_CONTENT; @@ -949,15 +981,26 @@ public class HttpParser else { List values = new QuotedCSV(_valueString).getValues(); - if (!values.isEmpty() && HttpHeaderValue.CHUNKED.is(values.get(values.size() - 1))) + int chunked = -1; + int len = values.size(); + for (int i = 0; i < len; i++) { - _endOfContent = EndOfContent.CHUNKED_CONTENT; - _contentLength = -1; + if (HttpHeaderValue.CHUNKED.is(values.get(i))) + { + if (chunked != -1) + throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, multiple chunked tokens"); + chunked = i; + // declared chunked + _endOfContent = EndOfContent.CHUNKED_CONTENT; + _contentLength = -1; + } + // we have a non-chunked token after a declared chunked token + else if (_endOfContent == EndOfContent.CHUNKED_CONTENT) + { + throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, chunked not last"); + } } - else if (values.stream().anyMatch(HttpHeaderValue.CHUNKED::is)) - throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad chunking"); } - break; case HOST: @@ -1026,7 +1069,7 @@ public class HttpParser } catch (NumberFormatException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Invalid Content-Length Value", e); } } @@ -1098,6 +1141,17 @@ public class HttpParser return _handler.messageComplete(); } + // We found Transfer-Encoding headers, but none declared the 'chunked' token + if (_hasTransferEncoding && _endOfContent != EndOfContent.CHUNKED_CONTENT) + { + if (_responseHandler == null || _endOfContent != EndOfContent.EOF_CONTENT) + { + // Transfer-Encoding chunked not specified + // https://tools.ietf.org/html/rfc7230#section-3.3.1 + throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Transfer-Encoding, chunked not last"); + } + } + // Was there a required host header? if (!_host && _version == HttpVersion.HTTP_1_1 && _requestHandler != null) { @@ -1140,11 +1194,6 @@ public class HttpParser _headerComplete = true; return handle; } - case NO_CONTENT: - { - setState(State.END); - return handleHeaderContentMessage(); - } default: { setState(State.CONTENT); @@ -1190,7 +1239,7 @@ public class HttpParser } } - if (v != null && _handler.isHeaderCacheCaseSensitive()) + if (v != null && isHeaderCacheCaseSensitive()) { String ev = BufferUtil.toString(buffer, buffer.position() + n.length() + 1, v.length(), StandardCharsets.ISO_8859_1); if (!v.equals(ev)) @@ -1443,8 +1492,16 @@ public class HttpParser // Handle HEAD response if (_responseStatus > 0 && _headResponse) { - setState(State.END); - return handleContentMessage(); + if (_state != State.CONTENT_END) + { + setState(State.CONTENT_END); + return handleContentMessage(); + } + else + { + setState(State.END); + return _handler.messageComplete(); + } } else { @@ -1463,11 +1520,18 @@ public class HttpParser // handle end states if (_state == State.END) { - // eat white space - while (buffer.remaining() > 0 && buffer.get(buffer.position()) <= HttpTokens.SPACE) + // Eat CR or LF white space, but not SP. + int whiteSpace = 0; + while (buffer.remaining() > 0) { + byte b = buffer.get(buffer.position()); + if (b != HttpTokens.CARRIAGE_RETURN && b != HttpTokens.LINE_FEED) + break; buffer.get(); + ++whiteSpace; } + if (debugEnabled && whiteSpace > 0) + LOG.debug("Discarded {} CR or LF characters", whiteSpace); } else if (isClose() || isClosed()) { @@ -1475,18 +1539,13 @@ public class HttpParser } // Handle EOF - if (_eof && !buffer.hasRemaining()) + if (isAtEOF() && !buffer.hasRemaining()) { switch (_state) { case CLOSED: break; - case START: - setState(State.CLOSED); - _handler.earlyEOF(); - break; - case END: case CLOSE: setState(State.CLOSED); @@ -1497,13 +1556,18 @@ public class HttpParser if (_fieldState == FieldState.FIELD) { // Be forgiving of missing last CRLF + setState(State.CONTENT_END); + boolean handle = handleContentMessage(); + if (handle && _state == State.CONTENT_END) + return true; setState(State.CLOSED); - return handleContentMessage(); + return handle; } setState(State.CLOSED); _handler.earlyEOF(); break; + case START: case CONTENT: case CHUNKED_CONTENT: case CHUNK_SIZE: @@ -1549,18 +1613,28 @@ public class HttpParser protected boolean parseContent(ByteBuffer buffer) { int remaining = buffer.remaining(); - if (remaining == 0 && _state == State.CONTENT) + if (remaining == 0) { - long content = _contentLength - _contentPosition; - if (content == 0) + switch (_state) { - setState(State.END); - return handleContentMessage(); + case CONTENT: + long content = _contentLength - _contentPosition; + if (_endOfContent == EndOfContent.NO_CONTENT || content == 0) + { + setState(State.CONTENT_END); + return handleContentMessage(); + } + break; + case CONTENT_END: + setState(_endOfContent == EndOfContent.EOF_CONTENT ? State.CLOSED : State.END); + return _handler.messageComplete(); + default: + // No bytes to parse, return immediately. + return false; } } - // Handle _content - byte ch; + // Handle content. while (_state.ordinal() < State.TRAILER.ordinal() && remaining > 0) { switch (_state) @@ -1576,9 +1650,9 @@ public class HttpParser case CONTENT: { long content = _contentLength - _contentPosition; - if (content == 0) + if (_endOfContent == EndOfContent.NO_CONTENT || content == 0) { - setState(State.END); + setState(State.CONTENT_END); return handleContentMessage(); } else @@ -1601,7 +1675,7 @@ public class HttpParser if (_contentPosition == _contentLength) { - setState(State.END); + setState(State.CONTENT_END); return handleContentMessage(); } } @@ -1726,10 +1800,10 @@ public class HttpParser break; } - case CLOSED: + case CONTENT_END: { - BufferUtil.clear(buffer); - return false; + setState(_endOfContent == EndOfContent.EOF_CONTENT ? State.CLOSED : State.END); + return _handler.messageComplete(); } default: @@ -1779,6 +1853,7 @@ public class HttpParser _endOfContent = EndOfContent.UNKNOWN_CONTENT; _contentLength = -1; _hasContentLength = false; + _hasTransferEncoding = false; _contentPosition = 0; _responseStatus = 0; _contentChunk = null; @@ -1812,8 +1887,8 @@ public class HttpParser return String.format("%s{s=%s,%d of %d}", getClass().getSimpleName(), _state, - _contentPosition, - _contentLength); + getContentRead(), + getContentLength()); } /* Event Handler interface @@ -1834,14 +1909,14 @@ public class HttpParser boolean messageComplete(); /** - * This is the method called by parser when a HTTP Header name and value is found + * This is the method called by parser when an HTTP Header name and value is found * * @param field The field parsed */ void parsedHeader(HttpField field); /** - * This is the method called by parser when a HTTP Trailer name and value is found + * This is the method called by parser when an HTTP Trailer name and value is found * * @param field The field parsed */ @@ -1851,7 +1926,7 @@ public class HttpParser /** * Called to signal that an EOF was received unexpectedly - * during the parsing of a HTTP message + * during the parsing of an HTTP message */ void earlyEOF(); @@ -1863,13 +1938,6 @@ public class HttpParser default void badMessage(BadMessageException failure) { } - - /** - * @return the size in bytes of the per parser header cache - */ - int getHeaderCacheSize(); - - boolean isHeaderCacheCaseSensitive(); } public interface RequestHandler extends HttpHandler @@ -1880,9 +1948,8 @@ public class HttpParser * @param method The method * @param uri The raw bytes of the URI. These are copied into a ByteBuffer that will not be changed until this parser is reset and reused. * @param version the http version in use - * @return true if handling parsing should return. */ - boolean startRequest(String method, String uri, HttpVersion version); + void startRequest(String method, String uri, HttpVersion version); } public interface ResponseHandler extends HttpHandler @@ -1893,9 +1960,8 @@ public class HttpParser * @param version the http version in use * @param status the response status * @param reason the response reason phrase - * @return true if handling parsing should return */ - boolean startResponse(HttpVersion version, int status, String reason); + void startResponse(HttpVersion version, int status, String reason); } @SuppressWarnings("serial") diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpScheme.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpScheme.java index 9340fb6f974..b80b5d4e879 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpScheme.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpScheme.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java index 58d2a98f4bd..501d9340bac 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -314,6 +314,20 @@ public class HttpStatus } } + public static boolean hasNoBody(int status) + { + switch (status) + { + case NO_CONTENT_204: + case NOT_MODIFIED_304: + case PARTIAL_CONTENT_206: + return true; + + default: + return status < OK_200; + } + } + /** * Simple test against an code to determine if it falls into the * Informational message category as defined in the http://user@host:port/path/info;param?query#fragment * this class will split it into the following undecoded optional elements:

      *
    • {@link #getScheme()} - http:
    • @@ -161,7 +161,8 @@ public class HttpURI _host = host; _port = port; - parse(State.PATH, pathQuery); + if (pathQuery != null) + parse(State.PATH, pathQuery); } public void parse(String uri) @@ -607,6 +608,15 @@ public class HttpURI return _param; } + public void setParam(String param) + { + _param = param; + if (_path != null && !_path.contains(_param)) + { + _path += ";" + _param; + } + } + public String getQuery() { return _query; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpVersion.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpVersion.java index 483233846d2..a259f201f22 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpVersion.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpVersion.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -42,12 +42,12 @@ public enum HttpVersion } /** - * Optimised lookup to find a Http Version and whitespace in a byte array. + * Optimised lookup to find an Http Version and whitespace in a byte array. * * @param bytes Array containing ISO-8859-1 characters * @param position The first valid index * @param limit The first non valid index - * @return A HttpMethod if a match or null if no easy match. + * @return An HttpMethod if a match or null if no easy match. */ public static HttpVersion lookAheadGet(byte[] bytes, int position, int limit) { @@ -88,10 +88,10 @@ public enum HttpVersion } /** - * Optimised lookup to find a HTTP Version and trailing white space in a byte array. + * Optimised lookup to find an HTTP Version and trailing white space in a byte array. * * @param buffer buffer containing ISO-8859-1 characters - * @return A HttpVersion if a match or null if no easy match. + * @return An HttpVersion if a match or null if no easy match. */ public static HttpVersion lookAheadGet(ByteBuffer buffer) { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java index cc9cac1d6ed..491cd123b1c 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -109,10 +109,6 @@ public class MetaData implements Iterable return _contentLength; } - /** - * @return an iterator over the HTTP fields - * @see #getFields() - */ @Override public Iterator iterator() { @@ -155,25 +151,19 @@ public class MetaData implements Iterable public Request(String method, HttpScheme scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields) { - this(method, new HttpURI(scheme == null ? null : scheme.asString(), - hostPort == null ? null : hostPort.getHost(), - hostPort == null ? -1 : hostPort.getPort(), - uri), version, fields); + this(method, scheme, hostPort, uri, version, fields, Long.MIN_VALUE); } public Request(String method, HttpScheme scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields, long contentLength) { - this(method, new HttpURI(scheme == null ? null : scheme.asString(), - hostPort == null ? null : hostPort.getHost(), - hostPort == null ? -1 : hostPort.getPort(), - uri), version, fields, contentLength); + this(method, scheme == null ? null : scheme.asString(), hostPort, uri, version, fields, contentLength); } public Request(String method, String scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields, long contentLength) { this(method, new HttpURI(scheme, - hostPort == null ? null : hostPort.getHost(), - hostPort == null ? -1 : hostPort.getPort(), + hostPort == null ? null : hostPort.getHost(), + hostPort == null ? -1 : hostPort.getPort(), uri), version, fields, contentLength); } @@ -221,14 +211,6 @@ public class MetaData implements Iterable return _uri; } - /** - * @return the HTTP URI in string form - */ - public String getURIString() - { - return _uri == null ? null : _uri.toString(); - } - /** * @param uri the HTTP URI to set */ @@ -237,12 +219,54 @@ public class MetaData implements Iterable _uri = uri; } + /** + * @return the HTTP URI in string form + */ + public String getURIString() + { + return _uri == null ? null : _uri.toString(); + } + + public String getProtocol() + { + return null; + } + @Override public String toString() { HttpFields fields = getFields(); - return String.format("%s{u=%s,%s,h=%d,cl=%d}", - getMethod(), getURI(), getHttpVersion(), fields == null ? -1 : fields.size(), getContentLength()); + return String.format("%s{u=%s,%s,h=%d,cl=%d,p=%s}", + getMethod(), getURI(), getHttpVersion(), fields == null ? -1 : fields.size(), getContentLength(), getProtocol()); + } + } + + public static class ConnectRequest extends Request + { + private String _protocol; + + public ConnectRequest(HttpScheme scheme, HostPortHttpField authority, String path, HttpFields fields, String protocol) + { + this(scheme == null ? null : scheme.asString(), authority, path, fields, protocol); + } + + public ConnectRequest(String scheme, HostPortHttpField authority, String path, HttpFields fields, String protocol) + { + super(HttpMethod.CONNECT.asString(), scheme, authority, path, HttpVersion.HTTP_2, fields, Long.MIN_VALUE); + _protocol = protocol; + } + + @Override + public String getProtocol() + { + return _protocol; + } + + @Override + public void recycle() + { + super.recycle(); + _protocol = null; } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java index 08f19690362..f377b566cfb 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -36,8 +36,8 @@ import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MIME Type enum and utilities @@ -45,7 +45,7 @@ import org.eclipse.jetty.util.log.Logger; public class MimeTypes { - private static final Logger LOG = Log.getLogger(MimeTypes.class); + private static final Logger LOG = LoggerFactory.getLogger(MimeTypes.class); private static final Trie TYPES = new ArrayTrie(512); private static final Map __dftMimeMap = new HashMap(); private static final Map __inferredEncodings = new HashMap(); @@ -218,15 +218,19 @@ public class MimeTypes } catch (IOException e) { - LOG.warn(e.toString()); - LOG.debug(e); + if (LOG.isDebugEnabled()) + LOG.warn("Unable to read mime-type resource: {}", resourceName, e); + else + LOG.warn("Unable to read mime-type resource: {} - {}", resourceName, e.toString()); } } } catch (IOException e) { - LOG.warn(e.toString()); - LOG.debug(e); + if (LOG.isDebugEnabled()) + LOG.warn("Unable to load mime-type resource: {}", resourceName, e); + else + LOG.warn("Unable to load mime-type resource: {} - {}", resourceName, e.toString()); } resourceName = "encoding.properties"; @@ -262,15 +266,19 @@ public class MimeTypes } catch (IOException e) { - LOG.warn(e.toString()); - LOG.debug(e); + if (LOG.isDebugEnabled()) + LOG.warn("Unable to read encoding resource: {}", resourceName, e); + else + LOG.warn("Unable to read encoding resource: {} - {}", resourceName, e.toString()); } } } catch (IOException e) { - LOG.warn(e.toString()); - LOG.debug(e); + if (LOG.isDebugEnabled()) + LOG.warn("Unable to load encoding resource: {}", resourceName, e); + else + LOG.warn("Unable to load encoding resource: {} - {}", resourceName, e.toString()); } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java index 35ec9a7cd40..6cc19ab8090 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java @@ -1,35 +1,35 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.TypeUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Pre encoded HttpField. - *

      A HttpField that will be cached and used many times can be created as + *

      An HttpField that will be cached and used many times can be created as * a {@link PreEncodedHttpField}, which will use the {@link HttpFieldPreEncoder} * instances discovered by the {@link ServiceLoader} to pre-encode the header * for each version of HTTP in use. This will save garbage @@ -38,26 +38,26 @@ import org.eclipse.jetty.util.log.Logger; */ public class PreEncodedHttpField extends HttpField { - private static final Logger LOG = Log.getLogger(PreEncodedHttpField.class); + private static final Logger LOG = LoggerFactory.getLogger(PreEncodedHttpField.class); private static final HttpFieldPreEncoder[] __encoders; static { List encoders = new ArrayList<>(); - Iterator iter = ServiceLoader.load(HttpFieldPreEncoder.class).iterator(); - while (iter.hasNext()) + TypeUtil.serviceProviderStream(ServiceLoader.load(HttpFieldPreEncoder.class)).forEach(provider -> { try { - HttpFieldPreEncoder encoder = iter.next(); + HttpFieldPreEncoder encoder = provider.get(); if (index(encoder.getHttpVersion()) >= 0) encoders.add(encoder); } catch (Error | RuntimeException e) { - LOG.debug(e); + LOG.debug("Unable to add HttpFieldPreEncoder", e); } - } + }); + LOG.debug("HttpField encoders loaded: {}", encoders); int size = encoders.size(); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/PrecompressedHttpContent.java b/jetty-http/src/main/java/org/eclipse/jetty/http/PrecompressedHttpContent.java index e7fceabea63..2d3b1cec4a9 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/PrecompressedHttpContent.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/PrecompressedHttpContent.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java index d767e006fed..a05fef693e7 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java index b730258fe3f..c25917e25ec 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java index 2e4a97058df..d2bf32835fc 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -23,7 +23,8 @@ import java.util.Iterator; import java.util.List; import java.util.function.ToIntFunction; -import org.eclipse.jetty.util.log.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.lang.Integer.MIN_VALUE; @@ -39,6 +40,8 @@ import static java.lang.Integer.MIN_VALUE; */ public class QuotedQualityCSV extends QuotedCSV implements Iterable { + private static final Logger LOG = LoggerFactory.getLogger(QuotedQualityCSV.class); + /** * Lambda to apply a most specific MIME encoding secondary ordering. * @@ -129,7 +132,7 @@ public class QuotedQualityCSV extends QuotedCSV implements Iterable } catch (Exception e) { - Log.getLogger(QuotedQualityCSV.class).ignore(e); + LOG.trace("IGNORED", e); q = 0.0D; } buffer.setLength(Math.max(0, paramName - 1)); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java b/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java index 22e404a0df8..ead0b554f08 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/Syntax.java b/jetty-http/src/main/java/org/eclipse/jetty/http/Syntax.java index cb0b2a7d97d..215a4ed99d5 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/Syntax.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/Syntax.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/package-info.java b/jetty-http/src/main/java/org/eclipse/jetty/http/package-info.java index 0532f07bf83..e7e4bdead3e 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/package-info.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MappedResource.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MappedResource.java index 2d50bb15175..ad4d4445f4a 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MappedResource.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MappedResource.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java index f3c50aaeff3..b0ef6bf817b 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; @@ -32,8 +32,8 @@ import org.eclipse.jetty.util.Trie; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Path Mappings of PathSpec to Resource. @@ -45,7 +45,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject("Path Mappings") public class PathMappings implements Iterable>, Dumpable { - private static final Logger LOG = Log.getLogger(PathMappings.class); + private static final Logger LOG = LoggerFactory.getLogger(PathMappings.class); private final Set> _mappings = new TreeSet<>(); private Trie> _exactMap = new ArrayTernaryTrie<>(false); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java index eb1c2e111e3..a507db966da 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecGroup.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecGroup.java index 7d364ab2035..8f1ba412962 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecGroup.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecGroup.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecSet.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecSet.java index 252706d67dc..c75555f82cc 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecSet.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecSet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/RegexPathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/RegexPathSpec.java index 5381f4726af..94ed1cfa534 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/RegexPathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/RegexPathSpec.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java index aea328cca0a..fefc652d854 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java @@ -1,28 +1,33 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ServletPathSpec extends PathSpec { + + private static final Logger LOG = LoggerFactory.getLogger(ServletPathSpec.class); + /** * If a servlet or filter path mapping isn't a suffix mapping, ensure * it starts with '/' @@ -213,13 +218,13 @@ public class ServletPathSpec extends PathSpec super.pathDepth = 0; char lastChar = servletPathSpec.charAt(specLength - 1); // prefix based - if ((servletPathSpec.charAt(0) == '/') && (specLength > 1) && (lastChar == '*')) + if (servletPathSpec.charAt(0) == '/' && servletPathSpec.endsWith("/*")) { this.group = PathSpecGroup.PREFIX_GLOB; this.prefix = servletPathSpec.substring(0, specLength - 2); } // suffix based - else if (servletPathSpec.charAt(0) == '*') + else if (servletPathSpec.charAt(0) == '*' && servletPathSpec.length() > 1) { this.group = PathSpecGroup.SUFFIX_GLOB; this.suffix = servletPathSpec.substring(2, specLength); @@ -228,6 +233,11 @@ public class ServletPathSpec extends PathSpec { this.group = PathSpecGroup.EXACT; this.prefix = servletPathSpec; + if (servletPathSpec.endsWith("*")) + { + LOG.warn("Suspicious URL pattern: '{}'; see sections 12.1 and 12.2 of the Servlet specification", + servletPathSpec); + } } for (int i = 0; i < specLength; i++) @@ -276,11 +286,6 @@ public class ServletPathSpec extends PathSpec { throw new IllegalArgumentException("Servlet Spec 12.2 violation: glob '*' can only exist at end of prefix based matches: bad spec \"" + servletPathSpec + "\""); } - - if (idx < 1 || servletPathSpec.charAt(idx - 1) != '/') - { - throw new IllegalArgumentException("Servlet Spec 12.2 violation: suffix glob '*' can only exist after '/': bad spec \"" + servletPathSpec + "\""); - } } else if (servletPathSpec.startsWith("*.")) { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java index f24c1a05fb3..63a5463044f 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; @@ -31,8 +31,8 @@ import java.util.regex.Pattern; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.UrlEncoded; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PathSpec for URI Template based declarations @@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class UriTemplatePathSpec extends RegexPathSpec { - private static final Logger LOG = Log.getLogger(UriTemplatePathSpec.class); + private static final Logger LOG = LoggerFactory.getLogger(UriTemplatePathSpec.class); private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{(.*)\\}"); /** diff --git a/jetty-http/src/main/resources/org/eclipse/jetty/http/mime.properties b/jetty-http/src/main/resources/org/eclipse/jetty/http/mime.properties index b4ad431489b..fe10cfdba3d 100644 --- a/jetty-http/src/main/resources/org/eclipse/jetty/http/mime.properties +++ b/jetty-http/src/main/resources/org/eclipse/jetty/http/mime.properties @@ -167,6 +167,7 @@ ustar=application/x-ustar vcd=application/x-cdlink vrml=model/vrml vxml=application/voicexml+xml +wasm=application/wasm wav=audio/x-wav wbmp=image/vnd.wap.wbmp wml=text/vnd.wap.wml diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterLenientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterLenientTest.java index e5bf0672a16..8d7839575e7 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterLenientTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterLenientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -40,6 +40,7 @@ public class CookieCutterLenientTest { return Stream.of( // Simple test to verify behavior + Arguments.of("x=y", "x", "y"), Arguments.of("key=value", "key", "value"), // Tests that conform to RFC2109 @@ -62,12 +63,17 @@ public class CookieCutterLenientTest // quoted-string = ( <"> *(qdtext) <"> ) // qdtext = > + // rejected, as name cannot be DQUOTED + Arguments.of("\"a\"=bcd", null, null), + Arguments.of("\"a\"=\"b c d\"", null, null), + // lenient with spaces and EOF Arguments.of("abc=", "abc", ""), Arguments.of("abc = ", "abc", ""), Arguments.of("abc = ;", "abc", ""), Arguments.of("abc = ; ", "abc", ""), Arguments.of("abc = x ", "abc", "x"), + Arguments.of("abc = e f g ", "abc", "e f g"), Arguments.of("abc=\"\"", "abc", ""), Arguments.of("abc= \"\" ", "abc", ""), Arguments.of("abc= \"x\" ", "abc", "x"), @@ -112,28 +118,29 @@ public class CookieCutterLenientTest // Unterminated Quotes with trailing escape Arguments.of("x=\"abc\\", "x", "\"abc\\"), - // UTF-8 values - Arguments.of("2sides=\u262F", "2sides", "\u262f"), // 2 byte - Arguments.of("currency=\"\u20AC\"", "currency", "\u20AC"), // 3 byte - Arguments.of("gothic=\"\uD800\uDF48\"", "gothic", "\uD800\uDF48"), // 4 byte + // UTF-8 raw values (not encoded) - VIOLATION of RFC6265 + Arguments.of("2sides=\u262F", null, null), // 2 byte (YIN YANG) - rejected due to not being DQUOTED + Arguments.of("currency=\"\u20AC\"", "currency", "\u20AC"), // 3 byte (EURO SIGN) + Arguments.of("gothic=\"\uD800\uDF48\"", "gothic", "\uD800\uDF48"), // 4 byte (GOTHIC LETTER HWAIR) // Spaces Arguments.of("foo=bar baz", "foo", "bar baz"), Arguments.of("foo=\"bar baz\"", "foo", "bar baz"), Arguments.of("z=a b c d e f g", "z", "a b c d e f g"), - // Bad tspecials usage + // Bad tspecials usage - VIOLATION of RFC6265 Arguments.of("foo=bar;baz", "foo", "bar"), Arguments.of("foo=\"bar;baz\"", "foo", "bar;baz"), Arguments.of("z=a;b,c:d;e/f[g]", "z", "a"), Arguments.of("z=\"a;b,c:d;e/f[g]\"", "z", "a;b,c:d;e/f[g]"), + Arguments.of("name=quoted=\"\\\"badly\\\"\"", "name", "quoted=\"\\\"badly\\\"\""), // someone attempting to escape a DQUOTE from within a DQUOTED pair) // Quoted with other Cookie keywords Arguments.of("x=\"$Version=0\"", "x", "$Version=0"), Arguments.of("x=\"$Path=/\"", "x", "$Path=/"), Arguments.of("x=\"$Path=/ $Domain=.foo.com\"", "x", "$Path=/ $Domain=.foo.com"), Arguments.of("x=\" $Path=/ $Domain=.foo.com \"", "x", " $Path=/ $Domain=.foo.com "), - Arguments.of("a=\"b; $Path=/a; c=d; $PATH=/c; e=f\"; $Path=/e/", "a", "b; $Path=/a; c=d; $PATH=/c; e=f"), + Arguments.of("a=\"b; $Path=/a; c=d; $PATH=/c; e=f\"; $Path=/e/", "a", "b; $Path=/a; c=d; $PATH=/c; e=f"), // VIOLATES RFC6265 // Lots of equals signs Arguments.of("query=b=c&d=e", "query", "b=c&d=e"), @@ -144,7 +151,7 @@ public class CookieCutterLenientTest // Google cookies (seen in wild, has `tspecials` of ':' in value) Arguments.of("GAPS=1:A1aaaAaAA1aaAAAaa1a11a:aAaaAa-aaA1-", "GAPS", "1:A1aaaAaAA1aaAAAaa1a11a:aAaaAa-aaA1-"), - // Strong abuse of cookie spec (lots of tspecials) + // Strong abuse of cookie spec (lots of tspecials) - VIOLATION of RFC6265 Arguments.of("$Version=0; rToken=F_TOKEN''!--\"=&{()}", "rToken", "F_TOKEN''!--\"=&{()}"), // Commas that were not commas diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterTest.java index 22516a5c024..3616b340277 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -55,7 +55,7 @@ public class CookieCutterTest * Example from RFC2109 and RFC2965 */ @Test - public void testRFC_Single() + public void testRFCSingle() { String rawCookie = "$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\""; @@ -69,7 +69,7 @@ public class CookieCutterTest * Example from RFC2109 and RFC2965 */ @Test - public void testRFC_Double() + public void testRFCDouble() { String rawCookie = "$Version=\"1\"; " + "Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; " + @@ -86,7 +86,7 @@ public class CookieCutterTest * Example from RFC2109 and RFC2965 */ @Test - public void testRFC_Triple() + public void testRFCTriple() { String rawCookie = "$Version=\"1\"; " + "Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; " + @@ -105,7 +105,7 @@ public class CookieCutterTest * Example from RFC2109 and RFC2965 */ @Test - public void testRFC_PathExample() + public void testRFCPathExample() { String rawCookie = "$Version=\"1\"; " + "Part_Number=\"Riding_Rocket_0023\"; $Path=\"/acme/ammo\"; " + @@ -122,7 +122,7 @@ public class CookieCutterTest * Example from RFC2109 */ @Test - public void testRFC2109_CookieSpoofingExample() + public void testRFC2109CookieSpoofingExample() { String rawCookie = "$Version=\"1\"; " + "session_id=\"1234\"; " + @@ -139,7 +139,7 @@ public class CookieCutterTest * Example from RFC2965 */ @Test - public void testRFC2965_CookieSpoofingExample() + public void testRFC2965CookieSpoofingExample() { String rawCookie = "$Version=\"1\"; session_id=\"1234\", " + "$Version=\"1\"; session_id=\"1111\"; $Domain=\".cracker.edu\""; @@ -160,7 +160,7 @@ public class CookieCutterTest * Example from RFC6265 */ @Test - public void testRFC6265_SidExample() + public void testRFC6265SidExample() { String rawCookie = "SID=31d4d96e407aad42"; @@ -174,7 +174,7 @@ public class CookieCutterTest * Example from RFC6265 */ @Test - public void testRFC6265_SidLangExample() + public void testRFC6265SidLangExample() { String rawCookie = "SID=31d4d96e407aad42; lang=en-US"; @@ -212,6 +212,34 @@ public class CookieCutterTest assertThat("Cookies.length", cookies.length, is(0)); } + @Test + public void testMultipleCookies() + { + String rawCookie = "testcookie; server.id=abcd; server.detail=cfg"; + + // The first cookie "testcookie" should be ignored, per RFC6265, as it's missing the "=" sign. + + Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC6265, rawCookie); + + assertThat("Cookies.length", cookies.length, is(2)); + assertCookie("Cookies[0]", cookies[0], "server.id", "abcd", 0, null); + assertCookie("Cookies[1]", cookies[1], "server.detail", "cfg", 0, null); + } + + @Test + public void testExcessiveSemicolons() + { + char[] excessive = new char[65535]; + Arrays.fill(excessive, ';'); + String rawCookie = "foo=bar; " + excessive + "; xyz=pdq"; + + Cookie[] cookies = parseCookieHeaders(CookieCompliance.RFC6265, rawCookie); + + assertThat("Cookies.length", cookies.length, is(2)); + assertCookie("Cookies[0]", cookies[0], "foo", "bar", 0, null); + assertCookie("Cookies[1]", cookies[1], "xyz", "pdq", 0, null); + } + static class Cookie { String name; @@ -282,6 +310,4 @@ public class CookieCutterTest super.parseFields(Arrays.asList(fields)); } } - - ; } diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/DateParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/DateParserTest.java index 72a90c31d02..e867e8ec22c 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/DateParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/DateParserTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java index 93c7c4c3f37..9fd0825538f 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java @@ -1,25 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicInteger; @@ -30,7 +32,11 @@ import org.eclipse.jetty.io.ArrayByteBufferPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -351,4 +357,81 @@ public class GZIPContentDecoderTest assertTrue(buffer.hasRemaining()); assertEquals(data2, StandardCharsets.UTF_8.decode(buffer).toString()); } + + // Signed Integer Max + static final long INT_MAX = Integer.MAX_VALUE; + + // Unsigned Integer Max == 2^32 + static final long UINT_MAX = 0xFFFFFFFFL; + + @ParameterizedTest + @ValueSource(longs = {INT_MAX, INT_MAX + 1, UINT_MAX, UINT_MAX + 1}) + public void testLargeGzipStream(long origSize) throws IOException + { + // Size chosen for trade off between speed of I/O vs speed of Gzip + final int BUFSIZE = 1024 * 1024; + + // Create a buffer to use over and over again to produce the uncompressed input + byte[] cbuf = "0123456789ABCDEFGHIJKLMOPQRSTUVWXYZ".getBytes(StandardCharsets.UTF_8); + byte[] buf = new byte[BUFSIZE]; + for (int off = 0; off < buf.length; ) + { + int len = Math.min(cbuf.length, buf.length - off); + System.arraycopy(cbuf, 0, buf, off, len); + off += len; + } + + GZIPDecoderOutputStream out = new GZIPDecoderOutputStream(new GZIPContentDecoder(BUFSIZE)); + GZIPOutputStream outputStream = new GZIPOutputStream(out, BUFSIZE); + + for (long bytesLeft = origSize; bytesLeft > 0; ) + { + int len = buf.length; + if (bytesLeft < buf.length) + { + len = (int)bytesLeft; + } + outputStream.write(buf, 0, len); + bytesLeft -= len; + } + + // Close GZIPOutputStream to have it generate gzip trailer. + // This can cause more writes of unflushed gzip buffers + outputStream.close(); + + // out.decodedByteCount is only valid after close + assertThat("Decoded byte count", out.decodedByteCount, is(origSize)); + } + + public static class GZIPDecoderOutputStream extends OutputStream + { + private final GZIPContentDecoder decoder; + public long decodedByteCount = 0L; + + public GZIPDecoderOutputStream(GZIPContentDecoder decoder) + { + this.decoder = decoder; + } + + @Override + public void write(byte[] b, int off, int len) throws IOException + { + ByteBuffer buf = ByteBuffer.wrap(b, off, len); + while (buf.hasRemaining()) + { + ByteBuffer decoded = decoder.decode(buf); + if (decoded.hasRemaining()) + { + decodedByteCount += decoded.remaining(); + } + decoder.release(decoded); + } + } + + @Override + public void write(int b) throws IOException + { + write(new byte[]{(byte)b}, 0, 1); + } + } } diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java index e58550bee61..194139e9c6c 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java @@ -1,34 +1,72 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; +import java.util.stream.Stream; + +import org.eclipse.jetty.http.HttpCookie.SameSite; +import org.eclipse.jetty.util.AttributesMap; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpCookieTest { + @Test + public void testDefaultSameSite() + { + AttributesMap context = new AttributesMap(); + + //test null value for default + assertNull(HttpCookie.getSameSiteDefault(context)); + + //test good value for default as SameSite enum + context.setAttribute(HttpCookie.SAME_SITE_DEFAULT_ATTRIBUTE, SameSite.LAX); + assertEquals(SameSite.LAX, HttpCookie.getSameSiteDefault(context)); + + //test good value for default as String + context.setAttribute(HttpCookie.SAME_SITE_DEFAULT_ATTRIBUTE, "NONE"); + assertEquals(SameSite.NONE, HttpCookie.getSameSiteDefault(context)); + + //test case for default as String + context.setAttribute(HttpCookie.SAME_SITE_DEFAULT_ATTRIBUTE, "sTrIcT"); + assertEquals(SameSite.STRICT, HttpCookie.getSameSiteDefault(context)); + + //test bad value for default as String + context.setAttribute(HttpCookie.SAME_SITE_DEFAULT_ATTRIBUTE, "fooBAR"); + assertThrows(IllegalStateException.class, + () -> HttpCookie.getSameSiteDefault(context)); + } @Test public void testConstructFromSetCookie() @@ -90,7 +128,19 @@ public class HttpCookieTest httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1); assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly", httpCookie.getRFC6265SetCookie()); - String[] badNameExamples = { + httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.NONE); + assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=None", httpCookie.getRFC6265SetCookie()); + + httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.LAX); + assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Lax", httpCookie.getRFC6265SetCookie()); + + httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.STRICT); + assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=Strict", httpCookie.getRFC6265SetCookie()); + } + + public static Stream rfc6265BadNameSource() + { + return Stream.of( "\"name\"", "name\t", "na me", @@ -100,25 +150,32 @@ public class HttpCookieTest "{name}", "[name]", "\"" - }; + ); + } - for (String badNameExample : badNameExamples) - { - try + @ParameterizedTest + @MethodSource("rfc6265BadNameSource") + public void testSetRFC6265CookieBadName(String badNameExample) + { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, + () -> { - httpCookie = new HttpCookie(badNameExample, "value", null, "/", 1, true, true, null, -1); + HttpCookie httpCookie = new HttpCookie(badNameExample, "value", null, "/", 1, true, true, null, -1); httpCookie.getRFC6265SetCookie(); - fail(badNameExample); - } - catch (IllegalArgumentException ex) - { - // System.err.printf("%s: %s%n", ex.getClass().getSimpleName(), ex.getMessage()); - assertThat("Testing bad name: [" + badNameExample + "]", ex.getMessage(), - allOf(containsString("RFC6265"), containsString("RFC2616"))); - } - } + }); + // make sure that exception mentions just how mad of a name it truly is + assertThat("message", ex.getMessage(), + allOf( + // violation of Cookie spec + containsString("RFC6265"), + // violation of HTTP spec + containsString("RFC2616") + )); + } - String[] badValueExamples = { + public static Stream rfc6265BadValueSource() + { + return Stream.of( "va\tlue", "\t", "value\u0000", @@ -130,39 +187,44 @@ public class HttpCookieTest "val\\ue", "val\"ue", "\"" - }; + ); + } - for (String badValueExample : badValueExamples) - { - try + @ParameterizedTest + @MethodSource("rfc6265BadValueSource") + public void testSetRFC6265CookieBadValue(String badValueExample) + { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, + () -> { - httpCookie = new HttpCookie("name", badValueExample, null, "/", 1, true, true, null, -1); + HttpCookie httpCookie = new HttpCookie("name", badValueExample, null, "/", 1, true, true, null, -1); httpCookie.getRFC6265SetCookie(); - fail(); - } - catch (IllegalArgumentException ex) - { - // System.err.printf("%s: %s%n", ex.getClass().getSimpleName(), ex.getMessage()); - assertThat("Testing bad value [" + badValueExample + "]", ex.getMessage(), Matchers.containsString("RFC6265")); - } - } + }); + assertThat("message", ex.getMessage(), containsString("RFC6265")); + } - String[] goodNameExamples = { + public static Stream rfc6265GoodNameSource() + { + return Stream.of( "name", "n.a.m.e", "na-me", "+name", "na*me", "na$me", - "#name" - }; + "#name"); + } - for (String goodNameExample : goodNameExamples) - { - httpCookie = new HttpCookie(goodNameExample, "value", null, "/", 1, true, true, null, -1); - // should not throw an exception - } + @ParameterizedTest + @MethodSource("rfc6265GoodNameSource") + public void testSetRFC6265CookieGoodName(String goodNameExample) + { + new HttpCookie(goodNameExample, "value", null, "/", 1, true, true, null, -1); + // should not throw an exception + } + public static Stream rfc6265GoodValueSource() + { String[] goodValueExamples = { "value", "", @@ -172,11 +234,150 @@ public class HttpCookieTest "val/ue", "v.a.l.u.e" }; + return Stream.of(goodValueExamples); + } - for (String goodValueExample : goodValueExamples) + @ParameterizedTest + @MethodSource("rfc6265GoodValueSource") + public void testSetRFC6265CookieGoodValue(String goodValueExample) + { + new HttpCookie("name", goodValueExample, null, "/", 1, true, true, null, -1); + // should not throw an exception + } + + @ParameterizedTest + @ValueSource(strings = { + "__HTTP_ONLY__", + "__HTTP_ONLY__comment", + "comment__HTTP_ONLY__" + }) + public void testIsHttpOnlyInCommentTrue(String comment) + { + assertTrue(HttpCookie.isHttpOnlyInComment(comment), "Comment \"" + comment + "\""); + } + + @ParameterizedTest + @ValueSource(strings = { + "comment", + "", + "__", + "__HTTP__ONLY__", + "__http_only__", + "HTTP_ONLY", + "__HTTP__comment__ONLY__" + }) + public void testIsHttpOnlyInCommentFalse(String comment) + { + assertFalse(HttpCookie.isHttpOnlyInComment(comment), "Comment \"" + comment + "\""); + } + + @ParameterizedTest + @ValueSource(strings = { + "__SAME_SITE_NONE__", + "__SAME_SITE_NONE____SAME_SITE_NONE__" + }) + public void testGetSameSiteFromCommentNONE(String comment) + { + assertEquals(HttpCookie.getSameSiteFromComment(comment), HttpCookie.SameSite.NONE, "Comment \"" + comment + "\""); + } + + @ParameterizedTest + @ValueSource(strings = { + "__SAME_SITE_LAX__", + "__SAME_SITE_LAX____SAME_SITE_NONE__", + "__SAME_SITE_NONE____SAME_SITE_LAX__", + "__SAME_SITE_LAX____SAME_SITE_NONE__" + }) + public void testGetSameSiteFromCommentLAX(String comment) + { + assertEquals(HttpCookie.getSameSiteFromComment(comment), HttpCookie.SameSite.LAX, "Comment \"" + comment + "\""); + } + + @ParameterizedTest + @ValueSource(strings = { + "__SAME_SITE_STRICT__", + "__SAME_SITE_NONE____SAME_SITE_STRICT____SAME_SITE_LAX__", + "__SAME_SITE_STRICT____SAME_SITE_LAX____SAME_SITE_NONE__", + "__SAME_SITE_STRICT____SAME_SITE_STRICT__" + }) + public void testGetSameSiteFromCommentSTRICT(String comment) + { + assertEquals(HttpCookie.getSameSiteFromComment(comment), HttpCookie.SameSite.STRICT, "Comment \"" + comment + "\""); + } + + /** + * A comment that does not have a declared SamesSite attribute defined + */ + @ParameterizedTest + @ValueSource(strings = { + "__HTTP_ONLY__", + "comment", + // not jetty attributes + "SameSite=None", + "SameSite=Lax", + "SameSite=Strict", + // incomplete jetty attributes + "SAME_SITE_NONE", + "SAME_SITE_LAX", + "SAME_SITE_STRICT", + }) + public void testGetSameSiteFromCommentUndefined(String comment) + { + assertNull(HttpCookie.getSameSiteFromComment(comment), "Comment \"" + comment + "\""); + } + + public static Stream getCommentWithoutAttributesSource() + { + return Stream.of( + // normal - only attribute comment + Arguments.of("__SAME_SITE_LAX__", null), + // normal - no attribute comment + Arguments.of("comment", "comment"), + // mixed - attributes at end + Arguments.of("comment__SAME_SITE_NONE__", "comment"), + Arguments.of("comment__HTTP_ONLY____SAME_SITE_NONE__", "comment"), + // mixed - attributes at start + Arguments.of("__SAME_SITE_NONE__comment", "comment"), + Arguments.of("__HTTP_ONLY____SAME_SITE_NONE__comment", "comment"), + // mixed - attributes at start and end + Arguments.of("__SAME_SITE_NONE__comment__HTTP_ONLY__", "comment"), + Arguments.of("__HTTP_ONLY__comment__SAME_SITE_NONE__", "comment") + ); + } + + @ParameterizedTest + @MethodSource("getCommentWithoutAttributesSource") + public void testGetCommentWithoutAttributes(String rawComment, String expectedComment) + { + String actualComment = HttpCookie.getCommentWithoutAttributes(rawComment); + if (expectedComment == null) { - httpCookie = new HttpCookie("name", goodValueExample, null, "/", 1, true, true, null, -1); - // should not throw an exception + assertNull(actualComment); + } + else + { + assertEquals(actualComment, expectedComment); } } + + @Test + public void testGetCommentWithAttributes() + { + assertThat(HttpCookie.getCommentWithAttributes(null, false, null), nullValue()); + assertThat(HttpCookie.getCommentWithAttributes("", false, null), nullValue()); + assertThat(HttpCookie.getCommentWithAttributes("hello", false, null), is("hello")); + + assertThat(HttpCookie.getCommentWithAttributes(null, true, HttpCookie.SameSite.STRICT), + is("__HTTP_ONLY____SAME_SITE_STRICT__")); + assertThat(HttpCookie.getCommentWithAttributes("", true, HttpCookie.SameSite.NONE), + is("__HTTP_ONLY____SAME_SITE_NONE__")); + assertThat(HttpCookie.getCommentWithAttributes("hello", true, HttpCookie.SameSite.LAX), + is("hello__HTTP_ONLY____SAME_SITE_LAX__")); + + assertThat(HttpCookie.getCommentWithAttributes("__HTTP_ONLY____SAME_SITE_LAX__", false, null), nullValue()); + assertThat(HttpCookie.getCommentWithAttributes("__HTTP_ONLY____SAME_SITE_LAX__", true, HttpCookie.SameSite.NONE), + is("__HTTP_ONLY____SAME_SITE_NONE__")); + assertThat(HttpCookie.getCommentWithAttributes("__HTTP_ONLY____SAME_SITE_LAX__hello", true, HttpCookie.SameSite.LAX), + is("hello__HTTP_ONLY____SAME_SITE_LAX__")); + } } diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldTest.java index 101b3f1fa61..6db122dced0 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -32,9 +32,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpFieldTest { - @Test - public void testContainsSimple() throws Exception + public void testContainsSimple() { HttpField field = new HttpField("name", "SomeValue"); assertTrue(field.contains("somevalue")); @@ -50,7 +49,7 @@ public class HttpFieldTest } @Test - public void testCaseInsensitiveHashcode_KnownField() throws Exception + public void testCaseInsensitiveHashcodeKnownField() { HttpField fieldFoo1 = new HttpField("Cookie", "foo"); HttpField fieldFoo2 = new HttpField("cookie", "foo"); @@ -59,7 +58,7 @@ public class HttpFieldTest } @Test - public void testCaseInsensitiveHashcode_UnknownField() throws Exception + public void testCaseInsensitiveHashcodeUnknownField() { HttpField fieldFoo1 = new HttpField("X-Foo", "bar"); HttpField fieldFoo2 = new HttpField("x-foo", "bar"); @@ -68,7 +67,7 @@ public class HttpFieldTest } @Test - public void testContainsList() throws Exception + public void testContainsList() { HttpField field = new HttpField("name", ",aaa,Bbb,CCC, ddd , e e, \"\\\"f,f\\\"\", "); assertTrue(field.contains("aaa")); @@ -91,7 +90,7 @@ public class HttpFieldTest } @Test - public void testQualityContainsList() throws Exception + public void testQualityContainsList() { HttpField field; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java index 34714b148e7..d6ba63ad007 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -30,6 +30,8 @@ import java.util.NoSuchElementException; import org.eclipse.jetty.util.BufferUtil; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -666,6 +668,41 @@ public class HttpFieldsTest assertFalse(header.containsKey("n11")); } + @ParameterizedTest + @ValueSource(strings = {"Host", "host", "HOST", "HoSt", "Connection", "CONNECTION", "connection", "CoNnEcTiOn"}) + public void testContainsKeyTrue(String keyName) + { + HttpFields fields = new HttpFields(); + fields.put("Host", "localhost"); + HttpField namelessField = new HttpField(HttpHeader.CONNECTION, null, "bogus"); + fields.put(namelessField); + + assertTrue(fields.containsKey(keyName), "containsKey('" + keyName + "')"); + } + + @ParameterizedTest + @ValueSource(strings = {"Content-Type", "Content-Length", "X-Bogus", ""}) + public void testContainsKeyFalse(String keyName) + { + HttpFields fields = new HttpFields(); + fields.add("Host", "localhost"); + HttpField namelessField = new HttpField(HttpHeader.CONNECTION, null, "bogus"); + fields.put(namelessField); + + assertFalse(fields.containsKey(keyName), "containsKey('" + keyName + "')"); + } + + @Test + public void testPreventNullField() + { + HttpFields fields = new HttpFields(); + assertThrows(NullPointerException.class, () -> + { + HttpField nullNullField = new HttpField(null, null, "bogus"); + fields.put(nullNullField); + }); + } + @Test public void testIteration() throws Exception { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java index 01d965be55d..e5bdf2609aa 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpGeneratorClientTest @@ -122,6 +123,42 @@ public class HttpGeneratorClientTest assertThat(out, Matchers.not(Matchers.containsString("Null:"))); } + @Test + public void testHeaderOverflow() throws Exception + { + HttpGenerator gen = new HttpGenerator(); + + Info info = new Info("GET", "/index.html"); + info.getFields().add("Host", "localhost"); + info.getFields().add("Field", "SomeWhatLongValue"); + info.setHttpVersion(HttpVersion.HTTP_1_0); + + HttpGenerator.Result result = gen.generateRequest(info, null, null, null, true); + assertEquals(HttpGenerator.Result.NEED_HEADER, result); + + ByteBuffer header = BufferUtil.allocate(16); + result = gen.generateRequest(info, header, null, null, true); + assertEquals(HttpGenerator.Result.HEADER_OVERFLOW, result); + + header = BufferUtil.allocate(2048); + result = gen.generateRequest(info, header, null, null, true); + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + assertFalse(gen.isChunking()); + String out = BufferUtil.toString(header); + BufferUtil.clear(header); + + result = gen.generateResponse(null, false, null, null, null, false); + assertEquals(HttpGenerator.Result.SHUTDOWN_OUT, result); + assertEquals(HttpGenerator.State.END, gen.getState()); + assertFalse(gen.isChunking()); + + assertEquals(0, gen.getContentPrepared()); + assertThat(out, Matchers.containsString("GET /index.html HTTP/1.0")); + assertThat(out, Matchers.not(Matchers.containsString("Content-Length"))); + assertThat(out, Matchers.containsString("Field: SomeWhatLongValue")); + } + @Test public void testPOSTRequestNoContent() throws Exception { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java index b28625e0e8a..ba845cca4ab 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -32,6 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.either; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpGeneratorServerHTTPTest @@ -70,7 +71,7 @@ public class HttpGeneratorServerHTTPTest assertEquals("OK??Test", _reason); if (_content == null) - assertTrue(run.result._body == null, msg); + assertNull(run.result._body, msg); else assertThat(msg, run.result._contentLength, either(equalTo(_content.length())).or(equalTo(-1))); } @@ -155,6 +156,12 @@ public class HttpGeneratorServerHTTPTest header = BufferUtil.allocate(2048); continue; + case HEADER_OVERFLOW: + if (header.capacity() >= 8192) + throw new BadMessageException(500, "Header too large"); + header = BufferUtil.allocate(8192); + continue; + case NEED_CHUNK: chunk = BufferUtil.allocate(HttpGenerator.CHUNK_SIZE); continue; @@ -248,10 +255,9 @@ public class HttpGeneratorServerHTTPTest } @Override - public boolean startResponse(HttpVersion version, int status, String reason) + public void startResponse(HttpVersion version, int status, String reason) { _reason = reason; - return false; } @Override @@ -259,18 +265,6 @@ public class HttpGeneratorServerHTTPTest { throw failure; } - - @Override - public int getHeaderCacheSize() - { - return 4096; - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - return false; - } } public static final String CONTENT = "The quick brown fox jumped over the lazy dog.\nNow is the time for all good men to come to the aid of the party\nThe moon is blue to a fish in love.\n"; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java index cc1b0ff61e5..f7ed242964d 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; public class HttpGeneratorServerTest { @Test - public void test_0_9() throws Exception + public void test09() throws Exception { ByteBuffer header = BufferUtil.allocate(8096); ByteBuffer content = BufferUtil.toBuffer("0123456789"); @@ -110,6 +110,38 @@ public class HttpGeneratorServerTest assertThat(response, containsString("\r\n0123456789")); } + @Test + public void testHeaderOverflow() throws Exception + { + HttpGenerator gen = new HttpGenerator(); + + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 302, null, new HttpFields(), 0); + info.getFields().add("Location", "http://somewhere/else"); + + HttpGenerator.Result result = gen.generateResponse(info, false, null, null, null, true); + assertEquals(HttpGenerator.Result.NEED_HEADER, result); + + ByteBuffer header = BufferUtil.allocate(16); + result = gen.generateResponse(info, false, header, null, null, true); + assertEquals(HttpGenerator.Result.HEADER_OVERFLOW, result); + + header = BufferUtil.allocate(8096); + result = gen.generateResponse(info, false, header, null, null, true); + assertEquals(HttpGenerator.Result.FLUSH, result); + assertEquals(HttpGenerator.State.COMPLETING, gen.getState()); + String response = BufferUtil.toString(header); + BufferUtil.clear(header); + + result = gen.generateResponse(null, false, null, null, null, false); + assertEquals(HttpGenerator.Result.DONE, result); + assertEquals(HttpGenerator.State.END, gen.getState()); + + assertEquals(0, gen.getContentPrepared()); + + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://somewhere/else")); + } + @Test public void test204() throws Exception { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index d8eaaa3841a..b2109cabb0e 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -24,9 +24,9 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.jetty.http.HttpParser.State; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.toolchain.test.Net; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; @@ -43,9 +43,12 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck public class HttpParserTest { /** @@ -67,16 +70,16 @@ public class HttpParserTest int remaining = buffer.remaining(); while (!parser.isState(State.END) && remaining > 0) { - int was_remaining = remaining; + int wasRemaining = remaining; parser.parseNext(buffer); remaining = buffer.remaining(); - if (remaining == was_remaining) + if (remaining == wasRemaining) break; } } @Test - public void HttpMethodTest() + public void testHttpMethod() { assertNull(HttpMethod.lookAheadGet(BufferUtil.toBuffer("Wibble "))); assertNull(HttpMethod.lookAheadGet(BufferUtil.toBuffer("GET"))); @@ -94,7 +97,7 @@ public class HttpParserTest } @Test - public void testLineParse_Mock_IP() throws Exception + public void testLineParseMockIP() { ByteBuffer buffer = BufferUtil.toBuffer("POST /mock/127.0.0.1 HTTP/1.1\r\n" + "\r\n"); @@ -108,7 +111,7 @@ public class HttpParserTest } @Test - public void testLineParse0() throws Exception + public void testLineParse0() { ByteBuffer buffer = BufferUtil.toBuffer("POST /foo HTTP/1.0\r\n" + "\r\n"); @@ -122,7 +125,7 @@ public class HttpParserTest } @Test - public void testLineParse1_RFC2616() throws Exception + public void testLineParse1RFC2616() { ByteBuffer buffer = BufferUtil.toBuffer("GET /999\r\n"); @@ -139,7 +142,7 @@ public class HttpParserTest } @Test - public void testLineParse1() throws Exception + public void testLineParse1() { ByteBuffer buffer = BufferUtil.toBuffer("GET /999\r\n"); @@ -151,7 +154,7 @@ public class HttpParserTest } @Test - public void testLineParse2_RFC2616() throws Exception + public void testLineParse2RFC2616() { ByteBuffer buffer = BufferUtil.toBuffer("POST /222 \r\n"); @@ -168,7 +171,7 @@ public class HttpParserTest } @Test - public void testLineParse2() throws Exception + public void testLineParse2() { ByteBuffer buffer = BufferUtil.toBuffer("POST /222 \r\n"); @@ -181,7 +184,7 @@ public class HttpParserTest } @Test - public void testLineParse3() throws Exception + public void testLineParse3() { ByteBuffer buffer = BufferUtil.toBuffer("POST /fo\u0690 HTTP/1.0\r\n" + "\r\n", StandardCharsets.UTF_8); @@ -195,7 +198,7 @@ public class HttpParserTest } @Test - public void testLineParse4() throws Exception + public void testLineParse4() { ByteBuffer buffer = BufferUtil.toBuffer("POST /foo?param=\u0690 HTTP/1.0\r\n" + "\r\n", StandardCharsets.UTF_8); @@ -209,7 +212,7 @@ public class HttpParserTest } @Test - public void testLongURLParse() throws Exception + public void testLongURLParse() { ByteBuffer buffer = BufferUtil.toBuffer("POST /123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/ HTTP/1.0\r\n" + "\r\n"); @@ -223,7 +226,7 @@ public class HttpParserTest } @Test - public void testAllowedLinePreamble() throws Exception + public void testAllowedLinePreamble() { ByteBuffer buffer = BufferUtil.toBuffer("\r\n\r\nGET / HTTP/1.0\r\n"); @@ -237,7 +240,7 @@ public class HttpParserTest } @Test - public void testDisallowedLinePreamble() throws Exception + public void testDisallowedLinePreamble() { ByteBuffer buffer = BufferUtil.toBuffer("\r\n \r\nGET / HTTP/1.0\r\n"); @@ -248,7 +251,7 @@ public class HttpParserTest } @Test - public void testConnect() throws Exception + public void testConnect() { ByteBuffer buffer = BufferUtil.toBuffer("CONNECT 192.168.1.2:80 HTTP/1.1\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); @@ -261,7 +264,7 @@ public class HttpParserTest } @Test - public void testSimple() throws Exception + public void testSimple() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -286,7 +289,7 @@ public class HttpParserTest } @Test - public void testFoldedField2616() throws Exception + public void testFoldedField2616() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -313,7 +316,7 @@ public class HttpParserTest } @Test - public void testFoldedField7230() throws Exception + public void testFoldedField7230() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -332,7 +335,7 @@ public class HttpParserTest } @Test - public void testWhiteSpaceInName() throws Exception + public void testWhiteSpaceInName() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -349,7 +352,7 @@ public class HttpParserTest } @Test - public void testWhiteSpaceAfterName() throws Exception + public void testWhiteSpaceAfterName() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -373,7 +376,7 @@ public class HttpParserTest HttpCompliance.RFC7230, HttpCompliance.RFC2616 }; - String whitespaces[][] = new String[][] + String[][] whitespaces = new String[][] { {" ", "Illegal character SPACE"}, {"\t", "Illegal character HTAB"}, @@ -390,10 +393,8 @@ public class HttpParserTest {" \r \t \r\n\r\n\r\n", "Illegal character SPACE"} }; - for (int i = 0; i < compliances.length; i++) + for (HttpCompliance compliance : compliances) { - HttpCompliance compliance = compliances[i]; - for (int j = 0; j < whitespaces.length; j++) { String request = @@ -421,7 +422,7 @@ public class HttpParserTest } @Test - public void testNoValue() throws Exception + public void testNoValue() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -449,7 +450,7 @@ public class HttpParserTest } @Test - public void testTrailingSpacesInHeaderNameNoCustom0() throws Exception + public void testTrailingSpacesInHeaderNameNoCustom0() { ByteBuffer buffer = BufferUtil.toBuffer( "HTTP/1.1 204 No Content\r\n" + @@ -468,7 +469,7 @@ public class HttpParserTest } @Test - public void testNoColon7230() throws Exception + public void testNoColon7230() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -484,7 +485,7 @@ public class HttpParserTest } @Test - public void testHeaderParseDirect() throws Exception + public void testHeaderParseDirect() { ByteBuffer b0 = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -535,7 +536,7 @@ public class HttpParserTest } @Test - public void testHeaderParseCRLF() throws Exception + public void testHeaderParseCRLF() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\r\n" + @@ -581,7 +582,7 @@ public class HttpParserTest } @Test - public void testHeaderParseLF() throws Exception + public void testHeaderParseLF() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\n" + @@ -627,7 +628,7 @@ public class HttpParserTest } @Test - public void testQuoted() throws Exception + public void testQuoted() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.0\n" + @@ -652,7 +653,7 @@ public class HttpParserTest } @Test - public void testEncodedHeader() throws Exception + public void testEncodedHeader() { ByteBuffer buffer = BufferUtil.allocate(4096); BufferUtil.flipToFill(buffer); @@ -678,11 +679,11 @@ public class HttpParserTest assertEquals("Header2", _hdr[1]); assertEquals("" + (char)255, _val[1]); assertEquals(1, _headers); - assertEquals(null, _bad); + assertNull(_bad); } @Test - public void testResponseBufferUpgradeFrom() throws Exception + public void testResponseBufferUpgradeFrom() { ByteBuffer buffer = BufferUtil.toBuffer( "HTTP/1.1 101 Upgrade\r\n" + @@ -704,7 +705,7 @@ public class HttpParserTest } @Test - public void testBadMethodEncoding() throws Exception + public void testBadMethodEncoding() { ByteBuffer buffer = BufferUtil.toBuffer( "G\u00e6T / HTTP/1.0\r\nHeader0: value0\r\n\n\n"); @@ -716,7 +717,7 @@ public class HttpParserTest } @Test - public void testBadVersionEncoding() throws Exception + public void testBadVersionEncoding() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / H\u00e6P/1.0\r\nHeader0: value0\r\n\n\n"); @@ -728,12 +729,12 @@ public class HttpParserTest } @Test - public void testBadHeaderEncoding() throws Exception + public void testBadHeaderEncoding() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" - + "H\u00e6der0: value0\r\n" - + "\n\n"); + "GET / HTTP/1.0\r\n" + + "H\u00e6der0: value0\r\n" + + "\n\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -742,7 +743,7 @@ public class HttpParserTest } @Test // TODO: Parameterize Test - public void testBadHeaderNames() throws Exception + public void testBadHeaderNames() { String[] bad = new String[] { @@ -760,23 +761,23 @@ public class HttpParserTest "Foo\"Bar: value\r\n", "Foo/Bar: value\r\n", "Foo]Bar: value\r\n", - "Foo[Bar: value\r\n", - }; + "Foo[Bar: value\r\n" + }; - for (int i = 0; i < bad.length; i++) + for (String s : bad) { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" + bad[i] + "\r\n"); + "GET / HTTP/1.0\r\n" + s + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); - assertThat(bad[i], _bad, Matchers.notNullValue()); + assertThat(s, _bad, Matchers.notNullValue()); } } @Test - public void testHeaderTab() throws Exception + public void testHeaderTab() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.1\r\n" + @@ -798,7 +799,7 @@ public class HttpParserTest } @Test - public void testCaseSensitiveMethod() throws Exception + public void testCaseSensitiveMethod() { ByteBuffer buffer = BufferUtil.toBuffer( "gEt / http/1.0\r\n" + @@ -814,7 +815,7 @@ public class HttpParserTest } @Test - public void testCaseSensitiveMethodLegacy() throws Exception + public void testCaseSensitiveMethodLegacy() { ByteBuffer buffer = BufferUtil.toBuffer( "gEt / http/1.0\r\n" + @@ -830,7 +831,7 @@ public class HttpParserTest } @Test - public void testCaseInsensitiveHeader() throws Exception + public void testCaseInsensitiveHeader() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / http/1.0\r\n" + @@ -853,15 +854,16 @@ public class HttpParserTest } @Test - public void testCaseInSensitiveHeaderLegacy() throws Exception + public void testCaseInSensitiveHeaderLegacy() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / http/1.0\r\n" + "HOST: localhost\r\n" + "cOnNeCtIoN: ClOsE\r\n" + "\r\n"); - HttpParser.RequestHandler handler = new Handler(true); + HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler, -1, HttpCompliance.LEGACY); + parser.setHeaderCacheCaseSensitive(true); parseAll(parser, buffer); assertNull(_bad); assertEquals("GET", _methodOrVersion); @@ -876,7 +878,7 @@ public class HttpParserTest } @Test - public void testSplitHeaderParse() throws Exception + public void testSplitHeaderParse() { ByteBuffer buffer = BufferUtil.toBuffer( "XXXXSPLIT / HTTP/1.0\r\n" + @@ -929,19 +931,19 @@ public class HttpParserTest } @Test - public void testChunkParse() throws Exception + public void testChunkParse() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" - + "\r\n"); + "GET /chunk HTTP/1.0\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); @@ -959,19 +961,19 @@ public class HttpParserTest } @Test - public void testBadChunkParse() throws Exception + public void testBadChunkParse() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked, identity\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" - + "\r\n"); + "GET /chunk HTTP/1.0\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked, identity\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); @@ -979,24 +981,24 @@ public class HttpParserTest assertEquals("GET", _methodOrVersion); assertEquals("/chunk", _uriOrStatus); assertEquals("HTTP/1.0", _versionOrReason); - assertThat(_bad, containsString("Bad chunking")); + assertThat(_bad, containsString("Bad Transfer-Encoding")); } @Test - public void testChunkParseTrailer() throws Exception + public void testChunkParseTrailer() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" - + "Trailer: value\r\n" - + "\r\n"); + "GET /chunk HTTP/1.0\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + + "Trailer: value\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); @@ -1018,20 +1020,20 @@ public class HttpParserTest } @Test - public void testChunkParseTrailers() throws Exception + public void testChunkParseTrailers() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" - + "Trailer: value\r\n" - + "Foo: bar\r\n" - + "\r\n"); + "GET /chunk HTTP/1.0\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + + "Trailer: value\r\n" + + "Foo: bar\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); @@ -1056,19 +1058,19 @@ public class HttpParserTest } @Test - public void testChunkParseBadTrailer() throws Exception + public void testChunkParseBadTrailer() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" - + "Trailer: value"); + "GET /chunk HTTP/1.0\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + + "Trailer: value"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); @@ -1088,18 +1090,18 @@ public class HttpParserTest } @Test - public void testChunkParseNoTrailer() throws Exception + public void testChunkParseNoTrailer() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n"); + "GET /chunk HTTP/1.0\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parseAll(parser, buffer); @@ -1119,7 +1121,7 @@ public class HttpParserTest } @Test - public void testStartEOF() throws Exception + public void testStartEOF() { HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1127,17 +1129,17 @@ public class HttpParserTest parser.parseNext(BufferUtil.EMPTY_BUFFER); assertTrue(_early); - assertEquals(null, _bad); + assertNull(_bad); } @Test - public void testEarlyEOF() throws Exception + public void testEarlyEOF() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /uri HTTP/1.0\r\n" - + "Content-Length: 20\r\n" - + "\r\n" - + "0123456789"); + "GET /uri HTTP/1.0\r\n" + + "Content-Length: 20\r\n" + + "\r\n" + + "0123456789"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.atEOF(); @@ -1152,15 +1154,15 @@ public class HttpParserTest } @Test - public void testChunkEarlyEOF() throws Exception + public void testChunkEarlyEOF() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /chunk HTTP/1.0\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n"); + "GET /chunk HTTP/1.0\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.atEOF(); @@ -1178,34 +1180,34 @@ public class HttpParserTest } @Test - public void testMultiParse() throws Exception + public void testMultiParse() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET /mp HTTP/1.0\r\n" - + "Connection: Keep-Alive\r\n" - + "Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" + "GET /mp HTTP/1.0\r\n" + + "Connection: Keep-Alive\r\n" + + "Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + - + "\r\n" + "\r\n" + - + "POST /foo HTTP/1.0\r\n" - + "Connection: Keep-Alive\r\n" - + "Header2: value2\r\n" - + "Content-Length: 0\r\n" - + "\r\n" + "POST /foo HTTP/1.0\r\n" + + "Connection: Keep-Alive\r\n" + + "Header2: value2\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + - + "PUT /doodle HTTP/1.0\r\n" - + "Connection: close\r\n" - + "Header3: value3\r\n" - + "Content-Length: 10\r\n" - + "\r\n" - + "0123456789\r\n"); + "PUT /doodle HTTP/1.0\r\n" + + "Connection: close\r\n" + + "Header3: value3\r\n" + + "Content-Length: 10\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1227,7 +1229,7 @@ public class HttpParserTest assertEquals(2, _headers); assertEquals("Header2", _hdr[1]); assertEquals("value2", _val[1]); - assertEquals(null, _content); + assertNull(_content); parser.reset(); init(); @@ -1243,35 +1245,34 @@ public class HttpParserTest } @Test - public void testMultiParseEarlyEOF() throws Exception + public void testMultiParseEarlyEOF() { ByteBuffer buffer0 = BufferUtil.toBuffer( - "GET /mp HTTP/1.0\r\n" - + "Connection: Keep-Alive\r\n"); + "GET /mp HTTP/1.0\r\n" + + "Connection: Keep-Alive\r\n"); - ByteBuffer buffer1 = BufferUtil.toBuffer("Header1: value1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "a;\r\n" - + "0123456789\r\n" - + "1a\r\n" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" - + "0\r\n" + ByteBuffer buffer1 = BufferUtil.toBuffer("Header1: value1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "a;\r\n" + + "0123456789\r\n" + + "1a\r\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" + + "0\r\n" + - + "\r\n" + "\r\n" + - + "POST /foo HTTP/1.0\r\n" - + "Connection: Keep-Alive\r\n" - + "Header2: value2\r\n" - + "Content-Length: 0\r\n" - + "\r\n" + "POST /foo HTTP/1.0\r\n" + + "Connection: Keep-Alive\r\n" + + "Header2: value2\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + - + "PUT /doodle HTTP/1.0\r\n" - + "Connection: close\r\n" - + "Header3: value3\r\n" - + "Content-Length: 10\r\n" - + "\r\n" - + "0123456789\r\n"); + "PUT /doodle HTTP/1.0\r\n" + + "Connection: close\r\n" + "Header3: value3\r\n" + + "Content-Length: 10\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1295,7 +1296,7 @@ public class HttpParserTest assertEquals(2, _headers); assertEquals("Header2", _hdr[1]); assertEquals("value2", _val[1]); - assertEquals(null, _content); + assertNull(_content); parser.reset(); init(); @@ -1310,14 +1311,14 @@ public class HttpParserTest } @Test - public void testResponseParse0() throws Exception + public void testResponseParse0() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 200 Correct\r\n" - + "Content-Length: 10\r\n" - + "Content-Type: text/plain\r\n" - + "\r\n" - + "0123456789\r\n"); + "HTTP/1.1 200 Correct\r\n" + + "Content-Length: 10\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1331,12 +1332,12 @@ public class HttpParserTest } @Test - public void testResponseParse1() throws Exception + public void testResponseParse1() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 304 Not-Modified\r\n" - + "Connection: close\r\n" - + "\r\n"); + "HTTP/1.1 304 Not-Modified\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1349,18 +1350,18 @@ public class HttpParserTest } @Test - public void testResponseParse2() throws Exception + public void testResponseParse2() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 204 No-Content\r\n" - + "Header: value\r\n" - + "\r\n" + "HTTP/1.1 204 No-Content\r\n" + + "Header: value\r\n" + + "\r\n" + - + "HTTP/1.1 200 Correct\r\n" - + "Content-Length: 10\r\n" - + "Content-Type: text/plain\r\n" - + "\r\n" - + "0123456789\r\n"); + "HTTP/1.1 200 Correct\r\n" + + "Content-Length: 10\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1385,55 +1386,55 @@ public class HttpParserTest } @Test - public void testResponseParse3() throws Exception + public void testResponseParse3() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 200\r\n" - + "Content-Length: 10\r\n" - + "Content-Type: text/plain\r\n" - + "\r\n" - + "0123456789\r\n"); + "HTTP/1.1 200\r\n" + + "Content-Length: 10\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", _methodOrVersion); assertEquals("200", _uriOrStatus); - assertEquals(null, _versionOrReason); + assertNull(_versionOrReason); assertEquals(_content.length(), 10); assertTrue(_headerCompleted); assertTrue(_messageCompleted); } @Test - public void testResponseParse4() throws Exception + public void testResponseParse4() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 200 \r\n" - + "Content-Length: 10\r\n" - + "Content-Type: text/plain\r\n" - + "\r\n" - + "0123456789\r\n"); + "HTTP/1.1 200 \r\n" + + "Content-Length: 10\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", _methodOrVersion); assertEquals("200", _uriOrStatus); - assertEquals(null, _versionOrReason); + assertNull(_versionOrReason); assertEquals(_content.length(), 10); assertTrue(_headerCompleted); assertTrue(_messageCompleted); } @Test - public void testResponseEOFContent() throws Exception + public void testResponseEOFContent() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 200 \r\n" - + "Content-Type: text/plain\r\n" - + "\r\n" - + "0123456789\r\n"); + "HTTP/1.1 200 \r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1442,7 +1443,7 @@ public class HttpParserTest assertEquals("HTTP/1.1", _methodOrVersion); assertEquals("200", _uriOrStatus); - assertEquals(null, _versionOrReason); + assertNull(_versionOrReason); assertEquals(12, _content.length()); assertEquals("0123456789\r\n", _content); assertTrue(_headerCompleted); @@ -1450,12 +1451,12 @@ public class HttpParserTest } @Test - public void testResponse304WithContentLength() throws Exception + public void testResponse304WithContentLength() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 304 found\r\n" - + "Content-Length: 10\r\n" - + "\r\n"); + "HTTP/1.1 304 found\r\n" + + "Content-Length: 10\r\n" + + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1463,18 +1464,18 @@ public class HttpParserTest assertEquals("HTTP/1.1", _methodOrVersion); assertEquals("304", _uriOrStatus); assertEquals("found", _versionOrReason); - assertEquals(null, _content); + assertNull(_content); assertTrue(_headerCompleted); assertTrue(_messageCompleted); } @Test - public void testResponse101WithTransferEncoding() throws Exception + public void testResponse101WithTransferEncoding() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 101 switching protocols\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n"); + "HTTP/1.1 101 switching protocols\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1482,18 +1483,18 @@ public class HttpParserTest assertEquals("HTTP/1.1", _methodOrVersion); assertEquals("101", _uriOrStatus); assertEquals("switching protocols", _versionOrReason); - assertEquals(null, _content); + assertNull(_content); assertTrue(_headerCompleted); assertTrue(_messageCompleted); } @Test - public void testResponseReasonIso8859_1() throws Exception + public void testResponseReasonIso88591() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 302 déplacé temporairement\r\n" - + "Content-Length: 0\r\n" - + "\r\n", StandardCharsets.ISO_8859_1); + "HTTP/1.1 302 déplacé temporairement\r\n" + + "Content-Length: 0\r\n" + + "\r\n", StandardCharsets.ISO_8859_1); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1504,15 +1505,15 @@ public class HttpParserTest } @Test - public void testSeekEOF() throws Exception + public void testSeekEOF() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 200 OK\r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n" - + "\r\n" // extra CRLF ignored - + "HTTP/1.1 400 OK\r\n"); // extra data causes close ?? + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n" + + "\r\n" + // extra CRLF ignored + "HTTP/1.1 400 OK\r\n"); // extra data causes close ?? HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1521,7 +1522,7 @@ public class HttpParserTest assertEquals("HTTP/1.1", _methodOrVersion); assertEquals("200", _uriOrStatus); assertEquals("OK", _versionOrReason); - assertEquals(null, _content); + assertNull(_content); assertTrue(_headerCompleted); assertTrue(_messageCompleted); @@ -1536,19 +1537,19 @@ public class HttpParserTest } @Test - public void testNoURI() throws Exception + public void testNoURI() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET\r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("No URI", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1558,19 +1559,19 @@ public class HttpParserTest } @Test - public void testNoURI2() throws Exception + public void testNoURI2() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET \r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET \r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("No URI", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1580,19 +1581,19 @@ public class HttpParserTest } @Test - public void testUnknownReponseVersion() throws Exception + public void testUnknownReponseVersion() { ByteBuffer buffer = BufferUtil.toBuffer( - "HPPT/7.7 200 OK\r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "HPPT/7.7 200 OK\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("Unknown Version", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1602,19 +1603,19 @@ public class HttpParserTest } @Test - public void testNoStatus() throws Exception + public void testNoStatus() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1\r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "HTTP/1.1\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("No Status", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1624,19 +1625,19 @@ public class HttpParserTest } @Test - public void testNoStatus2() throws Exception + public void testNoStatus2() { ByteBuffer buffer = BufferUtil.toBuffer( - "HTTP/1.1 \r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "HTTP/1.1 \r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("No Status", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1646,19 +1647,19 @@ public class HttpParserTest } @Test - public void testBadRequestVersion() throws Exception + public void testBadRequestVersion() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HPPT/7.7\r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HPPT/7.7\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("Unknown Version", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1667,16 +1668,16 @@ public class HttpParserTest assertEquals(HttpParser.State.CLOSED, parser.getState()); buffer = BufferUtil.toBuffer( - "GET / HTTP/1.01\r\n" - + "Content-Length: 0\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.01\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"); handler = new Handler(); parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _methodOrVersion); + assertNull(_methodOrVersion); assertEquals("Unknown Version", _bad); assertFalse(buffer.hasRemaining()); assertEquals(HttpParser.State.CLOSE, parser.getState()); @@ -1686,13 +1687,13 @@ public class HttpParserTest } @Test - public void testBadCR() throws Exception + public void testBadCR() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" - + "Content-Length: 0\r" - + "Connection: close\r" - + "\r"); + "GET / HTTP/1.0\r\n" + + "Content-Length: 0\r" + + "Connection: close\r" + + "\r"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1706,10 +1707,10 @@ public class HttpParserTest assertEquals(HttpParser.State.CLOSED, parser.getState()); buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r" - + "Content-Length: 0\r" - + "Connection: close\r" - + "\r"); + "GET / HTTP/1.0\r" + + "Content-Length: 0\r" + + "Connection: close\r" + + "\r"); handler = new Handler(); parser = new HttpParser(handler); @@ -1724,13 +1725,13 @@ public class HttpParserTest } @Test - public void testBadContentLength0() throws Exception + public void testBadContentLength0() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" - + "Content-Length: abc\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.0\r\n" + + "Content-Length: abc\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1746,13 +1747,13 @@ public class HttpParserTest } @Test - public void testBadContentLength1() throws Exception + public void testBadContentLength1() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" - + "Content-Length: 9999999999999999999999999999999999999999999999\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.0\r\n" + + "Content-Length: 9999999999999999999999999999999999999999999999\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1768,13 +1769,13 @@ public class HttpParserTest } @Test - public void testBadContentLength2() throws Exception + public void testBadContentLength2() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\n" - + "Content-Length: 1.5\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.0\r\n" + + "Content-Length: 1.5\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1793,12 +1794,12 @@ public class HttpParserTest public void testMultipleContentLengthWithLargerThenCorrectValue() { ByteBuffer buffer = BufferUtil.toBuffer( - "POST / HTTP/1.1\r\n" - + "Content-Length: 2\r\n" - + "Content-Length: 1\r\n" - + "Connection: close\r\n" - + "\r\n" - + "X"); + "POST / HTTP/1.1\r\n" + + "Content-Length: 2\r\n" + + "Content-Length: 1\r\n" + + "Connection: close\r\n" + + "\r\n" + + "X"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1817,12 +1818,12 @@ public class HttpParserTest public void testMultipleContentLengthWithCorrectThenLargerValue() { ByteBuffer buffer = BufferUtil.toBuffer( - "POST / HTTP/1.1\r\n" - + "Content-Length: 1\r\n" - + "Content-Length: 2\r\n" - + "Connection: close\r\n" - + "\r\n" - + "X"); + "POST / HTTP/1.1\r\n" + + "Content-Length: 1\r\n" + + "Content-Length: 2\r\n" + + "Connection: close\r\n" + + "\r\n" + + "X"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1841,15 +1842,15 @@ public class HttpParserTest public void testTransferEncodingChunkedThenContentLength() { ByteBuffer buffer = BufferUtil.toBuffer( - "POST /chunk HTTP/1.1\r\n" - + "Host: localhost\r\n" - + "Transfer-Encoding: chunked\r\n" - + "Content-Length: 1\r\n" - + "\r\n" - + "1\r\n" - + "X\r\n" - + "0\r\n" - + "\r\n"); + "POST /chunk HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "Transfer-Encoding: chunked\r\n" + + "Content-Length: 1\r\n" + + "\r\n" + + "1\r\n" + + "X\r\n" + + "0\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY); @@ -1870,15 +1871,15 @@ public class HttpParserTest public void testContentLengthThenTransferEncodingChunked() { ByteBuffer buffer = BufferUtil.toBuffer( - "POST /chunk HTTP/1.1\r\n" - + "Host: localhost\r\n" - + "Content-Length: 1\r\n" - + "Transfer-Encoding: chunked\r\n" - + "\r\n" - + "1\r\n" - + "X\r\n" - + "0\r\n" - + "\r\n"); + "POST /chunk HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "Content-Length: 1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "1\r\n" + + "X\r\n" + + "0\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY); @@ -1896,13 +1897,13 @@ public class HttpParserTest } @Test - public void testHost() throws Exception + public void testHost() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: host\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: host\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1912,12 +1913,12 @@ public class HttpParserTest } @Test - public void testUriHost11() throws Exception + public void testUriHost11() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET http://host/ HTTP/1.1\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET http://host/ HTTP/1.1\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1928,11 +1929,11 @@ public class HttpParserTest } @Test - public void testUriHost10() throws Exception + public void testUriHost10() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET http://host/ HTTP/1.0\r\n" - + "\r\n"); + "GET http://host/ HTTP/1.0\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1943,12 +1944,12 @@ public class HttpParserTest } @Test - public void testNoHost() throws Exception + public void testNoHost() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1957,13 +1958,13 @@ public class HttpParserTest } @Test - public void testIPHost() throws Exception + public void testIPHost() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: 192.168.0.1\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: 192.168.0.1\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1973,14 +1974,14 @@ public class HttpParserTest } @Test - public void testIPv6Host() throws Exception + public void testIPv6Host() { Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable()); ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: [::1]\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: [::1]\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -1990,15 +1991,15 @@ public class HttpParserTest } @Test - public void testBadIPv6Host() throws Exception + public void testBadIPv6Host() { try (StacklessLogging s = new StacklessLogging(HttpParser.class)) { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: [::1\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: [::1\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -2008,13 +2009,13 @@ public class HttpParserTest } @Test - public void testHostPort() throws Exception + public void testHostPort() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: myhost:8888\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: myhost:8888\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -2024,13 +2025,13 @@ public class HttpParserTest } @Test - public void testHostBadPort() throws Exception + public void testHostBadPort() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: myhost:testBadPort\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: myhost:testBadPort\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -2039,13 +2040,13 @@ public class HttpParserTest } @Test - public void testIPHostPort() throws Exception + public void testIPHostPort() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: 192.168.0.1:8888\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: 192.168.0.1:8888\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -2055,14 +2056,14 @@ public class HttpParserTest } @Test - public void testIPv6HostPort() throws Exception + public void testIPv6HostPort() { Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable()); ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host: [::1]:8888\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host: [::1]:8888\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); @@ -2072,24 +2073,24 @@ public class HttpParserTest } @Test - public void testEmptyHostPort() throws Exception + public void testEmptyHostPort() { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.1\r\n" - + "Host:\r\n" - + "Connection: close\r\n" - + "\r\n"); + "GET / HTTP/1.1\r\n" + + "Host:\r\n" + + "Connection: close\r\n" + + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); - assertEquals(null, _host); - assertEquals(null, _bad); + assertNull(_host); + assertNull(_bad); } @Test @SuppressWarnings("ReferenceEquality") - public void testCachedField() throws Exception + public void testCachedField() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.1\r\n" + @@ -2104,11 +2105,11 @@ public class HttpParserTest buffer.position(0); parseAll(parser, buffer); - assertTrue(field == _fields.get(0)); + assertSame(field, _fields.get(0)); } @Test - public void testParseRequest() throws Exception + public void testParseRequest() { ByteBuffer buffer = BufferUtil.toBuffer( "GET / HTTP/1.1\r\n" + @@ -2137,7 +2138,7 @@ public class HttpParserTest } @Test - public void testHTTP2Preface() throws Exception + public void testHTTP2Preface() { ByteBuffer buffer = BufferUtil.toBuffer( "PRI * HTTP/2.0\r\n" + @@ -2155,7 +2156,663 @@ public class HttpParserTest assertEquals("*", _uriOrStatus); assertEquals("HTTP/2.0", _versionOrReason); assertEquals(-1, _headers); - assertEquals(null, _bad); + assertNull(_bad); + } + + @Test + public void testForHTTP09HeaderCompleteTrueDoesNotEmitContentComplete() + { + HttpParser.RequestHandler handler = new Handler() + { + @Override + public boolean headerComplete() + { + super.headerComplete(); + return true; + } + }; + + HttpParser parser = new HttpParser(handler, HttpCompliance.RFC2616_LEGACY); + ByteBuffer buffer = BufferUtil.toBuffer("GET /path\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + assertEquals("GET", _methodOrVersion); + assertEquals("/path", _uriOrStatus); + assertEquals("HTTP/0.9", _versionOrReason); + assertEquals(-1, _headers); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + } + + @Test + public void testForContentLengthZeroHeaderCompleteTrueDoesNotEmitContentComplete() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean headerComplete() + { + super.headerComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + } + + @Test + public void testForEmptyChunkedContentHeaderCompleteTrueDoesNotEmitContentComplete() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean headerComplete() + { + super.headerComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + } + + @Test + public void testForContentLengthZeroContentCompleteTrueDoesNotEmitMessageComplete() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(_messageCompleted); + } + + @Test + public void testForEmptyChunkedContentContentCompleteTrueDoesNotEmitMessageComplete() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Transfer-Encoding: chunked\r\n" + + "\r\n" + + "0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(_messageCompleted); + } + + @Test + public void testHeaderAfterContentLengthZeroContentCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + String header = "Header: Foobar\r\n"; + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + + header); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals(header, BufferUtil.toString(buffer)); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals(header, BufferUtil.toString(buffer)); + assertTrue(_messageCompleted); + } + + @Test + public void testSmallContentLengthContentCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + String header = "Header: Foobar\r\n"; + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 1\r\n" + + "\r\n" + + "0" + + header); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals(header, BufferUtil.toString(buffer)); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals(header, BufferUtil.toString(buffer)); + assertTrue(_messageCompleted); + } + + @Test + public void testHeaderAfterSmallContentLengthContentCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 1\r\n" + + "\r\n" + + "0"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_messageCompleted); + } + + @Test + public void testEOFContentContentCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "\r\n" + + "0"); + boolean handle = parser.parseNext(buffer); + assertFalse(handle); + assertFalse(buffer.hasRemaining()); + assertEquals("0", _content); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + parser.atEOF(); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_messageCompleted); + } + + @Test + public void testHEADRequestHeaderCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean headerComplete() + { + super.headerComplete(); + return true; + } + + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + parser.setHeadResponse(true); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_messageCompleted); + } + + @Test + public void testNoContentHeaderCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean headerComplete() + { + super.headerComplete(); + return true; + } + + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + // HTTP 304 does not have a body. + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 304 Not Modified\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_messageCompleted); + } + + @Test + public void testCRLFAfterResponseHeaderCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean headerComplete() + { + super.headerComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 304 Not Modified\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "HTTP/1.1 303 See Other\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("304", _uriOrStatus); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("200", _uriOrStatus); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertEquals("303", _uriOrStatus); + assertFalse(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + } + + @Test + public void testCRLFAfterResponseContentCompleteTrue() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean contentComplete() + { + super.contentComplete(); + return true; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 304 Not Modified\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "HTTP/1.1 303 See Other\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("304", _uriOrStatus); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("200", _uriOrStatus); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertTrue(buffer.hasRemaining()); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertEquals("303", _uriOrStatus); + assertTrue(_contentCompleted); + assertFalse(_messageCompleted); + + // Need to parse more to advance the parser. + handle = parser.parseNext(buffer); + assertTrue(handle); + assertFalse(buffer.hasRemaining()); + assertTrue(_messageCompleted); + } + + @Test + public void testCRLFAfterResponseMessageCompleteFalse() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean messageComplete() + { + super.messageComplete(); + return false; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 304 Not Modified\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "HTTP/1.1 303 See Other\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertFalse(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("304", _uriOrStatus); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertFalse(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("200", _uriOrStatus); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertFalse(handle); + assertFalse(buffer.hasRemaining()); + assertEquals("303", _uriOrStatus); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + } + + @Test + public void testSPAfterResponseMessageCompleteFalse() + { + HttpParser.ResponseHandler handler = new Handler() + { + @Override + public boolean messageComplete() + { + super.messageComplete(); + return false; + } + }; + HttpParser parser = new HttpParser(handler); + + ByteBuffer buffer = BufferUtil.toBuffer( + "HTTP/1.1 304 Not Modified\r\n" + + "\r\n" + + " " + // Single SP. + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + boolean handle = parser.parseNext(buffer); + assertFalse(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("304", _uriOrStatus); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertFalse(handle); + assertFalse(buffer.hasRemaining()); + assertNotNull(_bad); + + buffer = BufferUtil.toBuffer( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n" + + " " + // Single SP. + "HTTP/1.1 303 See Other\r\n" + + "Content-Length: 0\r\n" + + "\r\n"); + parser = new HttpParser(handler); + handle = parser.parseNext(buffer); + assertFalse(handle); + assertTrue(buffer.hasRemaining()); + assertEquals("200", _uriOrStatus); + assertTrue(_contentCompleted); + assertTrue(_messageCompleted); + + // Parse next response. + parser.reset(); + init(); + handle = parser.parseNext(buffer); + assertFalse(handle); + assertFalse(buffer.hasRemaining()); + assertNotNull(_bad); } @BeforeEach @@ -2170,6 +2827,7 @@ public class HttpParserTest _val = null; _headers = 0; _headerCompleted = false; + _contentCompleted = false; _messageCompleted = false; _complianceViolation.clear(); } @@ -2188,23 +2846,12 @@ public class HttpParserTest private int _headers; private boolean _early; private boolean _headerCompleted; + private boolean _contentCompleted; private boolean _messageCompleted; private final List _complianceViolation = new ArrayList<>(); private class Handler implements HttpParser.RequestHandler, HttpParser.ResponseHandler, ComplianceViolation.Listener { - private boolean _headerCacheCaseSensitive; - - public Handler() - { - this(false); - } - - public Handler(boolean headerCacheCaseSensitive) - { - _headerCacheCaseSensitive = headerCacheCaseSensitive; - } - @Override public boolean content(ByteBuffer ref) { @@ -2217,7 +2864,7 @@ public class HttpParserTest } @Override - public boolean startRequest(String method, String uri, HttpVersion version) + public void startRequest(String method, String uri, HttpVersion version) { _fields.clear(); _trailers.clear(); @@ -2230,7 +2877,6 @@ public class HttpParserTest _messageCompleted = false; _headerCompleted = false; _early = false; - return false; } @Override @@ -2265,6 +2911,7 @@ public class HttpParserTest @Override public boolean contentComplete() { + _contentCompleted = true; return false; } @@ -2283,7 +2930,7 @@ public class HttpParserTest } @Override - public boolean startResponse(HttpVersion version, int status, String reason) + public void startResponse(HttpVersion version, int status, String reason) { _fields.clear(); _trailers.clear(); @@ -2295,7 +2942,6 @@ public class HttpParserTest _val = new String[10]; _messageCompleted = false; _headerCompleted = false; - return false; } @Override @@ -2304,18 +2950,6 @@ public class HttpParserTest _early = true; } - @Override - public int getHeaderCacheSize() - { - return 4096; - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - return _headerCacheCaseSensitive; - } - @Override public void onComplianceViolation(ComplianceViolation.Mode mode, ComplianceViolation violation, String reason) { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpSchemeTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpSchemeTest.java index 018f9fbe286..0e5480a4c9a 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpSchemeTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpSchemeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java index 3e45cbb50d2..0b9b0782714 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURIParseTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURIParseTest.java index 1c272fcc6ee..b0710d3c16b 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURIParseTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURIParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java index ab1b78e5a78..b01e873219f 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -119,6 +119,7 @@ public class HttpURITest @Test public void testExtB() throws Exception { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck for (String value : new String[]{"a", "abcdABCD", "\u00C0", "\u697C", "\uD869\uDED5", "\uD840\uDC08"}) { HttpURI uri = new HttpURI("/path?value=" + URLEncoder.encode(value, "UTF-8")); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/MimeTypesTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/MimeTypesTest.java index 89720e31a6a..5d35e58d690 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/MimeTypesTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/MimeTypesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -29,13 +29,13 @@ import static org.junit.jupiter.api.Assertions.assertNull; public class MimeTypesTest { @Test - public void testGetMimeByExtension_Gzip() + public void testGetMimeByExtensionGzip() { assertMimeTypeByExtension("application/gzip", "test.gz"); } @Test - public void testGetMimeByExtension_Png() + public void testGetMimeByExtensionPng() { assertMimeTypeByExtension("image/png", "test.png"); assertMimeTypeByExtension("image/png", "TEST.PNG"); @@ -43,26 +43,26 @@ public class MimeTypesTest } @Test - public void testGetMimeByExtension_Png_MultiDot() + public void testGetMimeByExtensionPngMultiDot() { assertMimeTypeByExtension("image/png", "org.eclipse.jetty.Logo.png"); } @Test - public void testGetMimeByExtension_Png_DeepPath() + public void testGetMimeByExtensionPngDeepPath() { assertMimeTypeByExtension("image/png", "/org/eclipse/jetty/Logo.png"); } @Test - public void testGetMimeByExtension_Text() + public void testGetMimeByExtensionText() { assertMimeTypeByExtension("text/plain", "test.txt"); assertMimeTypeByExtension("text/plain", "TEST.TXT"); } @Test - public void testGetMimeByExtension_NoExtension() + public void testGetMimeByExtensionNoExtension() { MimeTypes mimetypes = new MimeTypes(); String contentType = mimetypes.getMimeByExtension("README"); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedCSVTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedCSVTest.java index 310750770c4..3f59510f163 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedCSVTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedCSVTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java index 67497db75df..79326d85b77 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -31,7 +31,7 @@ public class QuotedQualityCSVTest { @Test - public void test7231_5_3_2_example1() + public void test7231Sec532Example1() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue(" audio/*; q=0.2, audio/basic"); @@ -39,7 +39,7 @@ public class QuotedQualityCSVTest } @Test - public void test7231_5_3_2_example2() + public void test7231Sec532Example2() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("text/plain; q=0.5, text/html,"); @@ -48,7 +48,7 @@ public class QuotedQualityCSVTest } @Test - public void test7231_5_3_2_example3() + public void test7231Sec532Example3() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("text/*, text/plain, text/plain;format=flowed, */*"); @@ -58,7 +58,7 @@ public class QuotedQualityCSVTest } @Test - public void test7231_5_3_2_example3_most_specific() + public void test7231532Example3MostSpecific() { QuotedQualityCSV values = new QuotedQualityCSV(QuotedQualityCSV.MOST_SPECIFIC_MIME_ORDERING); values.addValue("text/*, text/plain, text/plain;format=flowed, */*"); @@ -67,7 +67,7 @@ public class QuotedQualityCSVTest } @Test - public void test7231_5_3_2_example4() + public void test7231Sec532Example4() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("text/*;q=0.3, text/html;q=0.7, text/html;level=1,"); @@ -82,7 +82,7 @@ public class QuotedQualityCSVTest } @Test - public void test7231_5_3_4_example1() + public void test7231Sec534Example1() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("compress, gzip"); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/SyntaxTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/SyntaxTest.java index 019aa158214..59cdf3ca5ab 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/SyntaxTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/SyntaxTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http; @@ -28,7 +28,7 @@ import static org.junit.jupiter.api.Assertions.fail; public class SyntaxTest { @Test - public void testRequireValidRFC2616Token_Good() + public void testRequireValidRFC2616TokenGood() { String[] tokens = { "name", @@ -50,7 +50,7 @@ public class SyntaxTest } @Test - public void testRequireValidRFC2616Token_Bad() + public void testRequireValidRFC2616TokenBad() { String[] tokens = { "\"name\"", @@ -81,7 +81,7 @@ public class SyntaxTest } @Test - public void testRequireValidRFC6265CookieValue_Good() + public void testRequireValidRFC6265CookieValueGood() { String[] values = { "value", @@ -102,7 +102,7 @@ public class SyntaxTest } @Test - public void testRequireValidRFC6265CookieValue_Bad() + public void testRequireValidRFC6265CookieValueBad() { String[] values = { "va\tlue", diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java index 018dc430f43..174a5ef8378 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; @@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck public class PathMappingsTest { private void assertMatch(PathMappings pathmap, String path, String expectedValue) @@ -231,6 +232,8 @@ public class PathMappingsTest assertTrue(!new ServletPathSpec("/foo/*").matches("/bar/anything"), "!match /foo/*"); assertTrue(new ServletPathSpec("*.foo").matches("anything.foo"), "match *.foo"); assertTrue(!new ServletPathSpec("*.foo").matches("anything.bar"), "!match *.foo"); + assertTrue(new ServletPathSpec("/On*").matches("/On*"), "match /On*"); + assertTrue(!new ServletPathSpec("/On*").matches("/One"), "!match /One"); assertEquals("10", p.getMatch("/").getResource(), "match / with ''"); @@ -287,7 +290,6 @@ public class PathMappingsTest @ValueSource(strings = { "*", "/foo/*/bar", - "/foo*", "*/foo", "*.foo/*" }) diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathSpecAssert.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathSpecAssert.java index 086a72d9ee9..6e729b3d140 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathSpecAssert.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathSpecAssert.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java index de09d9429cf..ff4715adaaf 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecMatchListTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecMatchListTest.java index 88c637b489b..cc3b469b6bb 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecMatchListTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecMatchListTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecOrderTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecOrderTest.java index 2859dcd0a1f..3ae6413d0c9 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecOrderTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecOrderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; @@ -56,6 +56,7 @@ public class ServletPathSpecOrderTest data.add(Arguments.of("/downloads/script.gz", "gzipped")); data.add(Arguments.of("/animal/arhive.gz", "animals")); data.add(Arguments.of("/Other/path", "default")); + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck data.add(Arguments.of("/\u20ACuro/path", "money")); data.add(Arguments.of("/", "root")); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java index 51d1c74509b..0bec63c3a2e 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecBadSpecsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecBadSpecsTest.java index 13d52dcd615..a649ec31b7b 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecBadSpecsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecBadSpecsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java index afc20b78301..7696b4600fc 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.pathmap; @@ -87,7 +87,7 @@ public class UriTemplatePathSpecTest } @Test - public void testExactPathSpec_TestWebapp() + public void testExactPathSpecTestWebapp() { UriTemplatePathSpec spec = new UriTemplatePathSpec("/deep.thought/"); assertEquals("/deep.thought/", spec.getDeclaration(), "Spec.pathSpec"); diff --git a/jetty-http/src/test/resources/jetty-logging.properties b/jetty-http/src/test/resources/jetty-logging.properties index 799aa62aed3..ab545e4ab63 100644 --- a/jetty-http/src/test/resources/jetty-logging.properties +++ b/jetty-http/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.server.LEVEL=DEBUG #org.eclipse.jetty.http.LEVEL=DEBUG diff --git a/jetty-http/src/test/resources/keystore b/jetty-http/src/test/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/jetty-http/src/test/resources/keystore and /dev/null differ diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index d8dcc21ccc3..7686d41dc5b 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -20,7 +20,8 @@ maven-surefire-plugin - @{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.http2.client=jetty.servlet.api --add-modules jetty.servlet.api + @{argLine} ${jetty.surefire.argLine} + --add-reads org.eclipse.jetty.http2.client=org.eclipse.jetty.http2.hpack @@ -38,7 +39,16 @@ jetty-alpn-client ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-http2/http2-client/src/main/java/module-info.java b/jetty-http2/http2-client/src/main/java/module-info.java index f892c10dad1..721a1f43a8d 100644 --- a/jetty-http2/http2-client/src/main/java/module-info.java +++ b/jetty-http2/http2-client/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.http2.client @@ -21,8 +21,6 @@ module org.eclipse.jetty.http2.client exports org.eclipse.jetty.http2.client; requires org.eclipse.jetty.alpn.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.http2.common; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.http2.common; + requires org.slf4j; } diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java index a058215190a..8ea720523c3 100644 --- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java +++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -115,6 +115,9 @@ public class HTTP2Client extends ContainerLifeCycle private int maxConcurrentPushedStreams = 32; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); + private long streamIdleTimeout; + private boolean useInputDirectByteBuffers = true; + private boolean useOutputDirectByteBuffers = true; public HTTP2Client() { @@ -194,6 +197,17 @@ public class HTTP2Client extends ContainerLifeCycle connector.setIdleTimeout(Duration.ofMillis(idleTimeout)); } + @ManagedAttribute("The stream idle timeout in milliseconds") + public long getStreamIdleTimeout() + { + return streamIdleTimeout; + } + + public void setStreamIdleTimeout(long streamIdleTimeout) + { + this.streamIdleTimeout = streamIdleTimeout; + } + @ManagedAttribute("The connect timeout in milliseconds") public long getConnectTimeout() { @@ -303,6 +317,28 @@ public class HTTP2Client extends ContainerLifeCycle this.maxSettingsKeys = maxSettingsKeys; } + @ManagedAttribute("Whether to use direct ByteBuffers for reading") + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + @ManagedAttribute("Whether to use direct ByteBuffers for writing") + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + public void connect(InetSocketAddress address, Session.Listener listener, Promise promise) { // Prior-knowledge clear-text HTTP/2 (h2c). @@ -323,7 +359,7 @@ public class HTTP2Client extends ContainerLifeCycle public void connect(SocketAddress address, ClientConnectionFactory factory, Session.Listener listener, Promise promise, Map context) { context = contextFrom(factory, listener, promise, context); - context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, new Promise.Wrapper<>(promise)); + context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, promise); connector.connect(address, context); } @@ -336,7 +372,7 @@ public class HTTP2Client extends ContainerLifeCycle public void accept(SocketChannel channel, ClientConnectionFactory factory, Session.Listener listener, Promise promise) { Map context = contextFrom(factory, listener, promise, null); - context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, new Promise.Wrapper<>(promise)); + context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, promise); connector.accept(channel, context); } diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java index 007507a8ee8..49f252e3f69 100644 --- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java +++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -51,30 +51,35 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory @Override public Connection newConnection(EndPoint endPoint, Map context) { - final HTTP2Client client = (HTTP2Client)context.get(CLIENT_CONTEXT_KEY); - final ByteBufferPool byteBufferPool = client.getByteBufferPool(); - final Executor executor = client.getExecutor(); - final Scheduler scheduler = client.getScheduler(); - final Session.Listener listener = (Session.Listener)context.get(SESSION_LISTENER_CONTEXT_KEY); + HTTP2Client client = (HTTP2Client)context.get(CLIENT_CONTEXT_KEY); + ByteBufferPool byteBufferPool = client.getByteBufferPool(); + Executor executor = client.getExecutor(); + Scheduler scheduler = client.getScheduler(); + Session.Listener listener = (Session.Listener)context.get(SESSION_LISTENER_CONTEXT_KEY); @SuppressWarnings("unchecked") - final Promise promise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY); + Promise promise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY); - final Generator generator = new Generator(byteBufferPool); - final FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy(); - final HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl); + Generator generator = new Generator(byteBufferPool); + FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy(); + HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl); session.setMaxRemoteStreams(client.getMaxConcurrentPushedStreams()); + long streamIdleTimeout = client.getStreamIdleTimeout(); + if (streamIdleTimeout > 0) + session.setStreamIdleTimeout(streamIdleTimeout); - final Parser parser = new Parser(byteBufferPool, session, 4096, 8192); + Parser parser = new Parser(byteBufferPool, session, 4096, 8192); parser.setMaxFrameLength(client.getMaxFrameLength()); parser.setMaxSettingsKeys(client.getMaxSettingsKeys()); - final HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint, + HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint, parser, session, client.getInputBufferSize(), promise, listener); - connection.addListener(connectionListener); + connection.setUseInputDirectByteBuffers(client.isUseInputDirectByteBuffers()); + connection.setUseOutputDirectByteBuffers(client.isUseOutputDirectByteBuffers()); + connection.addEventListener(connectionListener); return customize(connection, context); } - private class HTTP2ClientConnection extends HTTP2Connection implements Callback + private static class HTTP2ClientConnection extends HTTP2Connection implements Callback { private final HTTP2Client client; private final Promise promise; @@ -151,7 +156,7 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory } } - private class ConnectionListener implements Connection.Listener + private static class ConnectionListener implements Connection.Listener { @Override public void onOpened(Connection connection) diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java index 660ae6c205f..6aa7ae9eb4b 100644 --- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java +++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientSession.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -33,13 +33,13 @@ import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.generator.Generator; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HTTP2ClientSession extends HTTP2Session { - private static final Logger LOG = Log.getLogger(HTTP2ClientSession.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2ClientSession.class); private final AtomicLong streamsOpened = new AtomicLong(); private final AtomicLong streamsClosed = new AtomicLong(); @@ -145,7 +145,7 @@ public class HTTP2ClientSession extends HTTP2Session } else { - IStream pushStream = createRemoteStream(pushStreamId); + IStream pushStream = createRemoteStream(pushStreamId, frame.getMetaData()); if (pushStream != null) { pushStream.process(frame, Callback.NOOP); diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AbstractTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AbstractTest.java index 0d620a0ecee..b569943dfb5 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AbstractTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AbstractTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncIOTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncIOTest.java index a1e3050ce97..0332e1b610d 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncIOTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncIOTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -21,6 +21,8 @@ package org.eclipse.jetty.http2.client; import java.io.IOException; import java.io.InterruptedIOException; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -28,6 +30,7 @@ import javax.servlet.AsyncContext; import javax.servlet.ReadListener; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; +import javax.servlet.WriteListener; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -38,6 +41,8 @@ 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.SettingsFrame; +import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; import org.junit.jupiter.api.Test; @@ -217,6 +222,66 @@ public class AsyncIOTest extends AbstractTest assertEquals(2, count.get()); } + @Test + public void testDirectAsyncWriteThenComplete() throws Exception + { + // Use a small flow control window to stall the server writes. + int clientWindow = 16; + start(new EmptyHttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + AsyncContext asyncContext = request.startAsync(); + HttpOutput output = (HttpOutput)response.getOutputStream(); + output.setWriteListener(new WriteListener() + { + @Override + public void onWritePossible() throws IOException + { + // The write is too large and will stall. + output.write(ByteBuffer.wrap(new byte[2 * clientWindow])); + + // We can now call complete() now before checking for isReady(). + // This will asynchronously complete when the write is finished. + asyncContext.complete(); + } + + @Override + public void onError(Throwable t) + { + } + }); + } + }); + + Session session = newClient(new Session.Listener.Adapter() + { + @Override + public Map onPreface(Session session) + { + Map settings = new HashMap<>(); + settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, clientWindow); + return settings; + } + }); + + HttpFields fields = new HttpFields(); + MetaData.Request metaData = newRequest("GET", fields); + HeadersFrame frame = new HeadersFrame(metaData, null, true); + CountDownLatch latch = new CountDownLatch(1); + FuturePromise promise = new FuturePromise<>(); + session.newStream(frame, promise, new Stream.Listener.Adapter() + { + @Override + public void onClosed(Stream stream) + { + latch.countDown(); + } + }); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + private static void sleep(long ms) throws InterruptedIOException { try diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncServletTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncServletTest.java index f461659cafb..40a13912791 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncServletTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/AsyncServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -135,25 +135,28 @@ public class AsyncServletTest extends AbstractTest MetaData.Request metaData = newRequest("GET", fields); HeadersFrame frame = new HeadersFrame(metaData, null, true); FuturePromise promise = new FuturePromise<>(); - CountDownLatch clientLatch = new CountDownLatch(1); + CountDownLatch responseLatch = new CountDownLatch(1); + CountDownLatch resetLatch = new CountDownLatch(1); session.newStream(frame, promise, new Stream.Listener.Adapter() { @Override public void onHeaders(Stream stream, HeadersFrame frame) { - MetaData.Response response = (MetaData.Response)frame.getMetaData(); - if (response.getStatus() == HttpStatus.INTERNAL_SERVER_ERROR_500 && frame.isEndStream()) - clientLatch.countDown(); + responseLatch.countDown(); + } + + @Override + public void onReset(Stream stream, ResetFrame frame) + { + resetLatch.countDown(); } }); Stream stream = promise.get(5, TimeUnit.SECONDS); stream.setIdleTimeout(10 * idleTimeout); - // When the client closes, the server receives the - // corresponding frame and acts by notifying the failure, - // which sends back to the client the error response. assertTrue(serverLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS)); - assertTrue(clientLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS)); + assertFalse(responseLatch.await(idleTimeout + 1000, TimeUnit.MILLISECONDS)); + assertTrue(resetLatch.await(2 * idleTimeout, TimeUnit.MILLISECONDS)); } @Test diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/BufferingFlowControlStrategyTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/BufferingFlowControlStrategyTest.java index 45fd917f240..9a6eefb1086 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/BufferingFlowControlStrategyTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/BufferingFlowControlStrategyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTimeoutTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTimeoutTest.java index 9b8c6a3daa3..225cbdbfbd4 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTimeoutTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTunnelTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTunnelTest.java new file mode 100644 index 00000000000..c37fae48a4a --- /dev/null +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ConnectTunnelTest.java @@ -0,0 +1,151 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.client; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.http.HostPortHttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.api.Session; +import org.eclipse.jetty.http2.api.Stream; +import org.eclipse.jetty.http2.api.server.ServerSessionListener; +import org.eclipse.jetty.http2.frames.DataFrame; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.FuturePromise; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ConnectTunnelTest extends AbstractTest +{ + @Test + public void testCONNECT() throws Exception + { + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + // Verifies that the CONNECT request is well formed. + MetaData.Request request = (MetaData.Request)frame.getMetaData(); + assertEquals(HttpMethod.CONNECT.asString(), request.getMethod()); + HttpURI uri = request.getURI(); + assertNull(uri.getScheme()); + assertNull(uri.getPath()); + assertNotNull(uri.getAuthority()); + return new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + stream.data(frame, callback); + } + }; + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + + CountDownLatch latch = new CountDownLatch(1); + byte[] bytes = "HELLO".getBytes(StandardCharsets.UTF_8); + String host = "localhost"; + int port = connector.getLocalPort(); + String authority = host + ":" + port; + MetaData.Request request = new MetaData.Request(HttpMethod.CONNECT.asString(), null, new HostPortHttpField(authority), null, HttpVersion.HTTP_2, new HttpFields()); + FuturePromise streamPromise = new FuturePromise<>(); + client.newStream(new HeadersFrame(request, null, false), streamPromise, new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + if (frame.isEndStream()) + latch.countDown(); + } + }); + Stream stream = streamPromise.get(5, TimeUnit.SECONDS); + ByteBuffer data = ByteBuffer.wrap(bytes); + stream.data(new DataFrame(stream.getId(), data, true), Callback.NOOP); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testCONNECTWithProtocol() throws Exception + { + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + // Verifies that the CONNECT request is well formed. + MetaData.Request request = (MetaData.Request)frame.getMetaData(); + assertEquals(HttpMethod.CONNECT.asString(), request.getMethod()); + HttpURI uri = request.getURI(); + assertNotNull(uri.getScheme()); + assertNotNull(uri.getPath()); + assertNotNull(uri.getAuthority()); + assertNotNull(request.getProtocol()); + return new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + stream.data(frame, callback); + } + }; + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + + CountDownLatch latch = new CountDownLatch(1); + byte[] bytes = "HELLO".getBytes(StandardCharsets.UTF_8); + String host = "localhost"; + int port = connector.getLocalPort(); + String authority = host + ":" + port; + MetaData.Request request = new MetaData.ConnectRequest(HttpScheme.HTTP, new HostPortHttpField(authority), "/", new HttpFields(), "websocket"); + FuturePromise streamPromise = new FuturePromise<>(); + client.newStream(new HeadersFrame(request, null, false), streamPromise, new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + if (frame.isEndStream()) + latch.countDown(); + } + }); + Stream stream = streamPromise.get(5, TimeUnit.SECONDS); + ByteBuffer data = ByteBuffer.wrap(bytes); + stream.data(new DataFrame(stream.getId(), data, true), Callback.NOOP); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } +} diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DataDemandTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DataDemandTest.java new file mode 100644 index 00000000000..cc1a39f3389 --- /dev/null +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/DataDemandTest.java @@ -0,0 +1,386 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.client; + +import java.nio.ByteBuffer; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +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.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.FlowControlStrategy; +import org.eclipse.jetty.http2.HTTP2Session; +import org.eclipse.jetty.http2.ISession; +import org.eclipse.jetty.http2.api.Session; +import org.eclipse.jetty.http2.api.Stream; +import org.eclipse.jetty.http2.api.server.ServerSessionListener; +import org.eclipse.jetty.http2.frames.DataFrame; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.FuturePromise; +import org.eclipse.jetty.util.Promise; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class DataDemandTest extends AbstractTest +{ + @Test + public void testExplicitDemand() throws Exception + { + int length = FlowControlStrategy.DEFAULT_WINDOW_SIZE - 1; + AtomicReference serverStreamRef = new AtomicReference<>(); + Queue serverQueue = new ConcurrentLinkedQueue<>(); + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + serverStreamRef.set(stream); + return new Stream.Listener.Adapter() + { + @Override + public void onDataDemanded(Stream stream, DataFrame frame, Callback callback) + { + // Don't demand and don't complete callbacks. + serverQueue.offer(frame); + } + }; + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + MetaData.Request post = newRequest("POST", new HttpFields()); + FuturePromise promise = new FuturePromise<>(); + Queue clientQueue = new ConcurrentLinkedQueue<>(); + client.newStream(new HeadersFrame(post, null, false), promise, new Stream.Listener.Adapter() + { + @Override + public void onDataDemanded(Stream stream, DataFrame frame, Callback callback) + { + clientQueue.offer(frame); + } + }); + Stream clientStream = promise.get(5, TimeUnit.SECONDS); + // Send a single frame larger than the default frame size, + // so that it will be split on the server in multiple frames. + clientStream.data(new DataFrame(clientStream.getId(), ByteBuffer.allocate(length), true), Callback.NOOP); + + // The server should receive only 1 DATA frame because it does explicit demand. + // Wait a bit more to be sure it only receives 1 DATA frame. + Thread.sleep(1000); + assertEquals(1, serverQueue.size()); + + Stream serverStream = serverStreamRef.get(); + assertNotNull(serverStream); + + // Demand more DATA frames. + int count = 2; + serverStream.demand(count); + Thread.sleep(1000); + // The server should have received `count` more DATA frames. + assertEquals(1 + count, serverQueue.size()); + + // Demand all the rest. + serverStream.demand(Long.MAX_VALUE); + int loops = 0; + while (true) + { + if (++loops > 100) + fail(); + + Thread.sleep(100); + + long sum = serverQueue.stream() + .mapToLong(frame -> frame.getData().remaining()) + .sum(); + if (sum == length) + break; + } + + // Even if demanded, the flow control window should not have + // decreased because the callbacks have not been completed. + int recvWindow = ((ISession)serverStream.getSession()).updateRecvWindow(0); + assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE - length, recvWindow); + + // Send a large DATA frame to the client. + serverStream.data(new DataFrame(serverStream.getId(), ByteBuffer.allocate(length), true), Callback.NOOP); + + + // The client should receive only 1 DATA frame because it does explicit demand. + // Wait a bit more to be sure it only receives 1 DATA frame. + Thread.sleep(1000); + assertEquals(1, clientQueue.size()); + + // Demand more DATA frames. + clientStream.demand(count); + Thread.sleep(1000); + // The client should have received `count` more DATA frames. + assertEquals(1 + count, clientQueue.size()); + + // Demand all the rest. + clientStream.demand(Long.MAX_VALUE); + loops = 0; + while (true) + { + if (++loops > 100) + fail(); + + Thread.sleep(100); + + long sum = clientQueue.stream() + .mapToLong(frame -> frame.getData().remaining()) + .sum(); + if (sum == length) + break; + } + + // Both the client and server streams should be gone now. + assertNull(clientStream.getSession().getStream(clientStream.getId())); + assertNull(serverStream.getSession().getStream(serverStream.getId())); + } + + @Test + public void testOnBeforeData() throws Exception + { + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); + stream.headers(new HeadersFrame(stream.getId(), response, null, false), Callback.from(() -> sendData(stream), x -> {})); + return null; + } + + private void sendData(Stream stream) + { + stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(1024 * 1024), true), Callback.NOOP); + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + MetaData.Request post = newRequest("GET", new HttpFields()); + FuturePromise promise = new FuturePromise<>(); + CountDownLatch responseLatch = new CountDownLatch(1); + CountDownLatch beforeDataLatch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); + client.newStream(new HeadersFrame(post, null, true), promise, new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + responseLatch.countDown(); + } + + @Override + public void onBeforeData(Stream stream) + { + beforeDataLatch.countDown(); + // Don't demand. + } + + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + if (frame.isEndStream()) + latch.countDown(); + } + }); + Stream clientStream = promise.get(5, TimeUnit.SECONDS); + assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); + assertTrue(beforeDataLatch.await(5, TimeUnit.SECONDS)); + // Should not receive DATA frames until demanded. + assertFalse(latch.await(1, TimeUnit.SECONDS)); + // Now demand the first DATA frame. + clientStream.demand(1); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testDemandFromOnHeaders() throws Exception + { + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); + stream.headers(new HeadersFrame(stream.getId(), response, null, false), Callback.from(() -> sendData(stream), x -> {})); + return null; + } + + private void sendData(Stream stream) + { + stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(1024 * 1024), true), Callback.NOOP); + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + MetaData.Request post = newRequest("GET", new HttpFields()); + CountDownLatch latch = new CountDownLatch(1); + client.newStream(new HeadersFrame(post, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + stream.demand(1); + } + + @Override + public void onBeforeData(Stream stream) + { + // Do not demand from here, we have already demanded in onHeaders(). + } + + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + if (frame.isEndStream()) + latch.countDown(); + } + }); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testOnBeforeDataDoesNotReenter() throws Exception + { + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); + stream.headers(new HeadersFrame(stream.getId(), response, null, false), Callback.from(() -> sendData(stream), x -> {})); + return null; + } + + private void sendData(Stream stream) + { + stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(1024 * 1024), true), Callback.NOOP); + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + MetaData.Request post = newRequest("GET", new HttpFields()); + CountDownLatch latch = new CountDownLatch(1); + client.newStream(new HeadersFrame(post, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() + { + private boolean inBeforeData; + + @Override + public void onBeforeData(Stream stream) + { + inBeforeData = true; + stream.demand(1); + inBeforeData = false; + } + + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + assertFalse(inBeforeData); + callback.succeeded(); + if (frame.isEndStream()) + latch.countDown(); + } + }); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testSynchronousDemandDoesNotStackOverflow() throws Exception + { + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + return new Stream.Listener.Adapter() + { + @Override + public void onDataDemanded(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + stream.demand(1); + if (frame.isEndStream()) + { + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); + stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP); + } + } + }; + } + }); + + Session client = newClient(new Session.Listener.Adapter()); + MetaData.Request post = newRequest("POST", new HttpFields()); + FuturePromise promise = new FuturePromise<>(); + CountDownLatch latch = new CountDownLatch(1); + client.newStream(new HeadersFrame(post, null, false), promise, new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + if (frame.isEndStream()) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + latch.countDown(); + } + } + }); + Stream clientStream = promise.get(5, TimeUnit.SECONDS); + + // Generate a lot of small DATA frames and write them in a single + // write so that the server will continuously be notified and demand, + // which will test that it won't throw StackOverflowError. + MappedByteBufferPool byteBufferPool = new MappedByteBufferPool(); + Generator generator = new Generator(byteBufferPool); + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); + for (int i = 512; i >= 0; --i) + generator.data(lease, new DataFrame(clientStream.getId(), ByteBuffer.allocate(1), i == 0), 1); + + // Since this is a naked write, we need to wait that the + // client finishes writing the SETTINGS reply to the server + // during connection initialization, or we risk a WritePendingException. + Thread.sleep(1000); + ((HTTP2Session)clientStream.getSession()).getEndPoint().write(Callback.NOOP, lease.getByteBuffers().toArray(new ByteBuffer[0])); + + assertTrue(latch.await(15, TimeUnit.SECONDS)); + } +} diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/EmptyHttpServlet.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/EmptyHttpServlet.java index 630110034d3..a7520b54306 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/EmptyHttpServlet.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/EmptyHttpServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStalledTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStalledTest.java index cf8608d6748..3fa78b45dc6 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStalledTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStalledTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStrategyTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStrategyTest.java index 9fe509df5f2..fc4f6f6e369 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStrategyTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlStrategyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlWindowsTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlWindowsTest.java index 2b2bb275cd6..b9619728bea 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlWindowsTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/FlowControlWindowsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java index 132733ee8c2..8282dbb3407 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/HTTP2Test.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -25,9 +25,11 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.Random; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; +import java.util.concurrent.atomic.AtomicReference; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -39,13 +41,17 @@ import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Session; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.api.server.ServerSessionListener; import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.frames.GoAwayFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.frames.SettingsFrame; +import org.eclipse.jetty.http2.hpack.HpackException; +import org.eclipse.jetty.http2.parser.RateControl; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory; import org.eclipse.jetty.server.Connector; @@ -56,10 +62,16 @@ import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.Promise; +import org.eclipse.jetty.util.component.Graceful; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; public class HTTP2Test extends AbstractTest @@ -152,7 +164,7 @@ public class HTTP2Test extends AbstractTest start(new HttpServlet() { @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.getOutputStream().write(content); } @@ -200,7 +212,7 @@ public class HTTP2Test extends AbstractTest start(new EmptyHttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { IO.copy(request.getInputStream(), response.getOutputStream()); } @@ -244,7 +256,7 @@ public class HTTP2Test extends AbstractTest start(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { int download = request.getIntHeader(downloadBytes); byte[] content = new byte[download]; @@ -287,7 +299,7 @@ public class HTTP2Test extends AbstractTest start(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) { response.setStatus(status); } @@ -322,7 +334,7 @@ public class HTTP2Test extends AbstractTest start(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) { assertEquals(host, request.getServerName()); assertEquals(port, request.getServerPort()); @@ -459,7 +471,7 @@ public class HTTP2Test extends AbstractTest // The third stream must not be created. MetaData.Request request3 = newRequest("GET", new HttpFields()); CountDownLatch maxStreamsLatch = new CountDownLatch(1); - session.newStream(new HeadersFrame(request3, null, false), new Promise.Adapter() + session.newStream(new HeadersFrame(request3, null, false), new Promise.Adapter<>() { @Override public void failed(Throwable x) @@ -487,7 +499,7 @@ public class HTTP2Test extends AbstractTest // Create a fourth stream. MetaData.Request request4 = newRequest("GET", new HttpFields()); CountDownLatch exchangeLatch4 = new CountDownLatch(2); - session.newStream(new HeadersFrame(request4, null, true), new Promise.Adapter() + session.newStream(new HeadersFrame(request4, null, true), new Promise.Adapter<>() { @Override public void succeeded(Stream result) @@ -747,7 +759,7 @@ public class HTTP2Test extends AbstractTest RawHTTP2ServerConnectionFactory connectionFactory = new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), serverListener) { @Override - protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener) + protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl) { return super.newServerParser(connector, new ServerParser.Listener.Wrapper(listener) { @@ -757,7 +769,7 @@ public class HTTP2Test extends AbstractTest super.onGoAway(frame); goAwayLatch.countDown(); } - }); + }, rateControl); } }; prepareServer(connectionFactory); @@ -792,6 +804,219 @@ public class HTTP2Test extends AbstractTest assertTrue(goAwayLatch.await(5, TimeUnit.SECONDS)); } + @Test + public void testClientInvalidHeader() throws Exception + { + start(new EmptyHttpServlet()); + + // A bad header in the request should fail on the client. + Session session = newClient(new Session.Listener.Adapter()); + HttpFields requestFields = new HttpFields(); + requestFields.put(":custom", "special"); + MetaData.Request metaData = newRequest("GET", requestFields); + HeadersFrame request = new HeadersFrame(metaData, null, true); + FuturePromise promise = new FuturePromise<>(); + session.newStream(request, promise, new Stream.Listener.Adapter()); + ExecutionException x = assertThrows(ExecutionException.class, () -> promise.get(5, TimeUnit.SECONDS)); + assertThat(x.getCause(), instanceOf(HpackException.StreamException.class)); + } + + @Test + public void testServerInvalidHeader() throws Exception + { + start(new EmptyHttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) + { + response.setHeader(":custom", "special"); + } + }); + + // Good request with bad header in the response. + Session session = newClient(new Session.Listener.Adapter()); + MetaData.Request metaData = newRequest("GET", new HttpFields()); + HeadersFrame request = new HeadersFrame(metaData, null, true); + FuturePromise promise = new FuturePromise<>(); + CountDownLatch resetLatch = new CountDownLatch(1); + session.newStream(request, promise, new Stream.Listener.Adapter() + { + @Override + public void onReset(Stream stream, ResetFrame frame) + { + resetLatch.countDown(); + } + }); + Stream stream = promise.get(5, TimeUnit.SECONDS); + assertNotNull(stream); + + assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testServerInvalidHeaderFlushed() throws Exception + { + CountDownLatch serverFailure = new CountDownLatch(1); + start(new EmptyHttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setHeader(":custom", "special"); + try + { + response.flushBuffer(); + } + catch (IOException x) + { + assertThat(x.getCause(), instanceOf(HpackException.StreamException.class)); + serverFailure.countDown(); + throw x; + } + } + }); + + // Good request with bad header in the response. + Session session = newClient(new Session.Listener.Adapter()); + MetaData.Request metaData = newRequest("GET", "/flush", new HttpFields()); + HeadersFrame request = new HeadersFrame(metaData, null, true); + FuturePromise promise = new FuturePromise<>(); + CountDownLatch resetLatch = new CountDownLatch(1); + session.newStream(request, promise, new Stream.Listener.Adapter() + { + @Override + public void onReset(Stream stream, ResetFrame frame) + { + // Cannot receive a 500 because we force the flush on the server, so + // the response is committed even if the server was not able to write it. + resetLatch.countDown(); + } + }); + Stream stream = promise.get(5, TimeUnit.SECONDS); + assertNotNull(stream); + assertTrue(serverFailure.await(5, TimeUnit.SECONDS)); + assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testGracefulServerGoAway() throws Exception + { + AtomicReference serverSessionRef = new AtomicReference<>(); + CountDownLatch serverSessionLatch = new CountDownLatch(1); + CountDownLatch dataLatch = new CountDownLatch(2); + start(new ServerSessionListener.Adapter() + { + @Override + public void onAccept(Session session) + { + serverSessionRef.set(session); + serverSessionLatch.countDown(); + } + + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + return new Stream.Listener.Adapter() + { + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + dataLatch.countDown(); + if (frame.isEndStream()) + { + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); + stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP); + } + } + }; + } + }); + // Avoid aggressive idle timeout to allow the test verifications. + connector.setShutdownIdleTimeout(connector.getIdleTimeout()); + + CountDownLatch clientCloseLatch = new CountDownLatch(1); + Session clientSession = newClient(new Session.Listener.Adapter() + { + @Override + public void onClose(Session session, GoAwayFrame frame) + { + clientCloseLatch.countDown(); + } + }); + assertTrue(serverSessionLatch.await(5, TimeUnit.SECONDS)); + Session serverSession = serverSessionRef.get(); + + // Start 2 requests without completing them yet. + CountDownLatch responseLatch = new CountDownLatch(2); + MetaData.Request metaData1 = newRequest("GET", new HttpFields()); + HeadersFrame request1 = new HeadersFrame(metaData1, null, false); + FuturePromise promise1 = new FuturePromise<>(); + Stream.Listener.Adapter listener = new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + if (frame.isEndStream()) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + responseLatch.countDown(); + } + } + }; + clientSession.newStream(request1, promise1, listener); + Stream stream1 = promise1.get(5, TimeUnit.SECONDS); + stream1.data(new DataFrame(stream1.getId(), ByteBuffer.allocate(1), false), Callback.NOOP); + + MetaData.Request metaData2 = newRequest("GET", new HttpFields()); + HeadersFrame request2 = new HeadersFrame(metaData2, null, false); + FuturePromise promise2 = new FuturePromise<>(); + clientSession.newStream(request2, promise2, listener); + Stream stream2 = promise2.get(5, TimeUnit.SECONDS); + stream2.data(new DataFrame(stream2.getId(), ByteBuffer.allocate(1), false), Callback.NOOP); + + assertTrue(dataLatch.await(5, TimeUnit.SECONDS)); + + // Both requests are now on the server, shutdown gracefully the server session. + int port = connector.getLocalPort(); + CompletableFuture shutdown = Graceful.shutdown(server); + + // GOAWAY should not arrive to the client yet. + assertFalse(clientCloseLatch.await(1, TimeUnit.SECONDS)); + + // New requests should be immediately rejected. + HostPortHttpField authority3 = new HostPortHttpField("localhost" + ":" + port); + MetaData.Request metaData3 = new MetaData.Request("GET", HttpScheme.HTTP, authority3, servletPath, HttpVersion.HTTP_2, new HttpFields()); + HeadersFrame request3 = new HeadersFrame(metaData3, null, false); + FuturePromise promise3 = new FuturePromise<>(); + CountDownLatch resetLatch = new CountDownLatch(1); + clientSession.newStream(request3, promise3, new Stream.Listener.Adapter() + { + @Override + public void onReset(Stream stream, ResetFrame frame) + { + resetLatch.countDown(); + } + }); + Stream stream3 = promise3.get(5, TimeUnit.SECONDS); + stream3.data(new DataFrame(stream3.getId(), ByteBuffer.allocate(1), true), Callback.NOOP); + assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); + + // Finish the previous requests and expect the responses. + stream1.data(new DataFrame(stream1.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP); + stream2.data(new DataFrame(stream2.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP); + assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); + assertNull(shutdown.get(5, TimeUnit.SECONDS)); + + // Now GOAWAY should arrive to the client. + assertTrue(clientCloseLatch.await(5, TimeUnit.SECONDS)); + // Wait to process the GOAWAY frames and close the EndPoints. + Thread.sleep(1000); + assertFalse(((HTTP2Session)clientSession).getEndPoint().isOpen()); + assertFalse(((HTTP2Session)serverSession).getEndPoint().isOpen()); + } + private static void sleep(long time) { try diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java index aaf8a7af2b0..de1f2306e72 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/IdleTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -52,10 +52,10 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -565,7 +565,7 @@ public class IdleTimeoutTest extends AbstractTest while (true) { int read = input.read(buffer); - Log.getLogger(IdleTimeoutTest.class).info("Read {} bytes", read); + LoggerFactory.getLogger(IdleTimeoutTest.class).info("Read {} bytes", read); if (read < 0) break; sleep(delay); diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InterleavingTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InterleavingTest.java index 306278c822a..e6c5b1fefb1 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InterleavingTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InterleavingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -45,9 +45,9 @@ import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.lessThanOrEqualTo; @@ -188,7 +188,7 @@ public class InterleavingTest extends AbstractTest } groups.get(currentStream).add(currentLength); - Logger logger = Log.getLogger(getClass()); + Logger logger = LoggerFactory.getLogger(getClass()); logger.debug("frame lengths = {}", streamLengths); groups.forEach((stream, lengths) -> diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InvalidServerTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InvalidServerTest.java index 6aeca90b8bd..b82cd96b7ed 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InvalidServerTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/InvalidServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/MaxPushedStreamsTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/MaxPushedStreamsTest.java index 1890fd36458..77c2a8fa4df 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/MaxPushedStreamsTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/MaxPushedStreamsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PingTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PingTest.java index 61e4ef15a79..a1f8b1e8c0c 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PingTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java index 6177fd68b95..d3cfa1c893c 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PrefaceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PriorityTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PriorityTest.java index 25a80e45f54..5b6b593d818 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PriorityTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PriorityTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyProtocolTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyProtocolTest.java index e5557b1ae91..c87752ac5a1 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyProtocolTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyProtocolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -87,7 +87,7 @@ public class ProxyProtocolTest } @Test - public void test_PROXY_GET_v1() throws Exception + public void testProxyGetV1() throws Exception { startServer(new AbstractHandler() { @@ -139,7 +139,7 @@ public class ProxyProtocolTest } @Test - public void test_PROXY_GET_v2() throws Exception + public void testProxyGetV2() throws Exception { startServer(new AbstractHandler() { diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyTest.java index 1790ce2c1bd..10e3ea613b7 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/ProxyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java index 795ff56237a..05bb9178985 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/PushCacheFilterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/RawHTTP2ProxyTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/RawHTTP2ProxyTest.java index 2f5f47c6ecd..c8ee642159f 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/RawHTTP2ProxyTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/RawHTTP2ProxyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -53,18 +53,18 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class RawHTTP2ProxyTest { - private static final Logger LOGGER = Log.getLogger(RawHTTP2ProxyTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(RawHTTP2ProxyTest.class); private final List servers = new ArrayList<>(); private final List clients = new ArrayList<>(); diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SessionFailureTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SessionFailureTest.java index e0ea4b8b880..fa16449be1c 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SessionFailureTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SessionFailureTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SimpleFlowControlStrategyTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SimpleFlowControlStrategyTest.java index ba85d9148be..159dfb2bffd 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SimpleFlowControlStrategyTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SimpleFlowControlStrategyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SmallThreadPoolLoadTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SmallThreadPoolLoadTest.java index e6a682af0c8..386d6b07311 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SmallThreadPoolLoadTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/SmallThreadPoolLoadTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -46,13 +46,13 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.Scheduler; import org.hamcrest.Matchers; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -60,7 +60,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @Disabled public class SmallThreadPoolLoadTest extends AbstractTest { - private final Logger logger = Log.getLogger(SmallThreadPoolLoadTest.class); + private final Logger logger = LoggerFactory.getLogger(SmallThreadPoolLoadTest.class); private final AtomicLong requestIds = new AtomicLong(); @Override @@ -213,8 +213,8 @@ public class SmallThreadPoolLoadTest extends AbstractTest } case "POST": { - int content_length = request.getContentLength(); - ByteArrayOutputStream2 bout = new ByteArrayOutputStream2(content_length > 0 ? content_length : 16 * 1024); + int contentLength = request.getContentLength(); + ByteArrayOutputStream2 bout = new ByteArrayOutputStream2(contentLength > 0 ? contentLength : 16 * 1024); IO.copy(request.getInputStream(), bout); response.getOutputStream().write(bout.getBuf(), 0, bout.getCount()); break; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCloseTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCloseTest.java index bb2c05fee59..fd12feda890 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCloseTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCountTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCountTest.java index 5227219e067..33bf8940d40 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCountTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamCountTest.java @@ -1,28 +1,30 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; +import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpVersion; @@ -35,11 +37,14 @@ 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.http2.frames.SettingsFrame; +import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FuturePromise; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -81,7 +86,7 @@ public class StreamCountTest extends AbstractTest } }); - final CountDownLatch settingsLatch = new CountDownLatch(1); + CountDownLatch settingsLatch = new CountDownLatch(1); Session session = newClient(new Session.Listener.Adapter() { @Override @@ -97,7 +102,7 @@ public class StreamCountTest extends AbstractTest MetaData.Request metaData = newRequest("GET", fields); HeadersFrame frame1 = new HeadersFrame(metaData, null, false); FuturePromise streamPromise1 = new FuturePromise<>(); - final CountDownLatch responseLatch = new CountDownLatch(1); + CountDownLatch responseLatch = new CountDownLatch(1); session.newStream(frame1, streamPromise1, new Stream.Listener.Adapter() { @Override @@ -123,7 +128,6 @@ public class StreamCountTest extends AbstractTest @Test public void testServerAllowsOneStreamEnforcedByServer() throws Exception { - final CountDownLatch resetLatch = new CountDownLatch(1); start(new ServerSessionListener.Adapter() { @Override @@ -152,13 +156,21 @@ public class StreamCountTest extends AbstractTest } }); - Session session = newClient(new Session.Listener.Adapter()); + CountDownLatch sessionResetLatch = new CountDownLatch(2); + Session session = newClient(new Session.Listener.Adapter() + { + @Override + public void onReset(Session session, ResetFrame frame) + { + sessionResetLatch.countDown(); + } + }); HttpFields fields = new HttpFields(); MetaData.Request metaData = newRequest("GET", fields); HeadersFrame frame1 = new HeadersFrame(metaData, null, false); FuturePromise streamPromise1 = new FuturePromise<>(); - final CountDownLatch responseLatch = new CountDownLatch(1); + CountDownLatch responseLatch = new CountDownLatch(1); session.newStream(frame1, streamPromise1, new Stream.Listener.Adapter() { @Override @@ -173,17 +185,39 @@ public class StreamCountTest extends AbstractTest HeadersFrame frame2 = new HeadersFrame(metaData, null, false); FuturePromise streamPromise2 = new FuturePromise<>(); + AtomicReference resetLatch = new AtomicReference<>(new CountDownLatch(1)); session.newStream(frame2, streamPromise2, new Stream.Listener.Adapter() { @Override public void onReset(Stream stream, ResetFrame frame) { - resetLatch.countDown(); + resetLatch.get().countDown(); } }); - streamPromise2.get(5, TimeUnit.SECONDS); - assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); + Stream stream2 = streamPromise2.get(5, TimeUnit.SECONDS); + assertTrue(resetLatch.get().await(5, TimeUnit.SECONDS)); + + // Reset the latch and send a DATA frame, it should be dropped + // by the client because the stream has already been reset. + resetLatch.set(new CountDownLatch(1)); + stream2.data(new DataFrame(stream2.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP); + // Must not receive another RST_STREAM. + assertFalse(resetLatch.get().await(1, TimeUnit.SECONDS)); + + // Simulate a client sending both HEADERS and DATA frames at the same time. + // The server should send a RST_STREAM for the HEADERS. + // For the server, dropping the DATA frame is too costly so it sends another RST_STREAM. + int streamId3 = stream2.getId() + 2; + HeadersFrame frame3 = new HeadersFrame(streamId3, metaData, null, false); + DataFrame data3 = new DataFrame(streamId3, BufferUtil.EMPTY_BUFFER, true); + Generator generator = ((HTTP2Session)session).getGenerator(); + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(generator.getByteBufferPool()); + generator.control(lease, frame3); + generator.data(lease, data3, data3.remaining()); + ((HTTP2Session)session).getEndPoint().write(Callback.NOOP, lease.getByteBuffers().toArray(new ByteBuffer[0])); + // Expect 2 RST_STREAM frames. + assertTrue(sessionResetLatch.await(5, TimeUnit.SECONDS)); stream1.data(new DataFrame(stream1.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP); assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java index f025e90f38b..2ec076e8b70 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/StreamResetTest.java @@ -1,35 +1,41 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; import java.io.IOException; import java.io.InterruptedIOException; +import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.AsyncContext; @@ -40,7 +46,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.ErrorCode; @@ -54,12 +62,21 @@ import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.api.server.ServerSessionListener; import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.http2.frames.PrefaceFrame; import org.eclipse.jetty.http2.frames.ResetFrame; +import org.eclipse.jetty.http2.frames.SettingsFrame; +import org.eclipse.jetty.http2.frames.WindowUpdateFrame; +import org.eclipse.jetty.http2.generator.Generator; import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory; import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; +import org.eclipse.jetty.io.AbstractEndPoint; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.WriteFlusher; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpOutput; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -69,7 +86,6 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -833,4 +849,210 @@ public class StreamResetTest extends AbstractTest // Read on server should fail. assertTrue(failureLatch.await(5, TimeUnit.SECONDS)); } + + @Test + public void testResetAfterTCPCongestedWrite() throws Exception + { + AtomicReference flusherRef = new AtomicReference<>(); + CountDownLatch flusherLatch = new CountDownLatch(1); + CountDownLatch writeLatch1 = new CountDownLatch(1); + CountDownLatch writeLatch2 = new CountDownLatch(1); + start(new EmptyHttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException + { + Request jettyRequest = (Request)request; + flusherRef.set(((AbstractEndPoint)jettyRequest.getHttpChannel().getEndPoint()).getWriteFlusher()); + flusherLatch.countDown(); + + ServletOutputStream output = response.getOutputStream(); + try + { + // Large write, it blocks due to TCP congestion. + byte[] data = new byte[128 * 1024 * 1024]; + output.write(data); + } + catch (IOException x) + { + writeLatch1.countDown(); + try + { + // Try to write again, must fail immediately. + output.write(0xFF); + } + catch (IOException e) + { + writeLatch2.countDown(); + } + } + } + }); + + ByteBufferPool byteBufferPool = client.getByteBufferPool(); + try (SocketChannel socket = SocketChannel.open()) + { + String host = "localhost"; + int port = connector.getLocalPort(); + socket.connect(new InetSocketAddress(host, port)); + + Generator generator = new Generator(byteBufferPool); + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); + generator.control(lease, new PrefaceFrame()); + Map clientSettings = new HashMap<>(); + // Max stream HTTP/2 flow control window. + clientSettings.put(SettingsFrame.INITIAL_WINDOW_SIZE, Integer.MAX_VALUE); + generator.control(lease, new SettingsFrame(clientSettings, false)); + // Max session HTTP/2 flow control window. + generator.control(lease, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE)); + + HttpURI uri = new HttpURI("http", host, port, servletPath); + MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, new HttpFields()); + int streamId = 3; + HeadersFrame headersFrame = new HeadersFrame(streamId, request, null, true); + generator.control(lease, headersFrame); + + List buffers = lease.getByteBuffers(); + socket.write(buffers.toArray(new ByteBuffer[0])); + + // Wait until the server is TCP congested. + assertTrue(flusherLatch.await(5, TimeUnit.SECONDS)); + WriteFlusher flusher = flusherRef.get(); + waitUntilTCPCongested(flusher); + + lease.recycle(); + generator.control(lease, new ResetFrame(streamId, ErrorCode.CANCEL_STREAM_ERROR.code)); + buffers = lease.getByteBuffers(); + socket.write(buffers.toArray(new ByteBuffer[0])); + + assertTrue(writeLatch1.await(5, TimeUnit.SECONDS)); + assertTrue(writeLatch2.await(5, TimeUnit.SECONDS)); + } + } + + @Test + public void testResetSecondRequestAfterTCPCongestedWriteBeforeWrite() throws Exception + { + Exchanger exchanger = new Exchanger<>(); + CountDownLatch requestLatch1 = new CountDownLatch(1); + CountDownLatch requestLatch2 = new CountDownLatch(1); + CountDownLatch writeLatch1 = new CountDownLatch(1); + start(new EmptyHttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException + { + if (request.getPathInfo().equals("/1")) + service1(request, response); + else if (request.getPathInfo().equals("/2")) + service2(request, response); + else + throw new IllegalArgumentException(); + } + + private void service1(HttpServletRequest request, HttpServletResponse response) throws IOException + { + try + { + Request jettyRequest = (Request)request; + exchanger.exchange(((AbstractEndPoint)jettyRequest.getHttpChannel().getEndPoint()).getWriteFlusher()); + + ServletOutputStream output = response.getOutputStream(); + // Large write, it blocks due to TCP congestion. + output.write(new byte[128 * 1024 * 1024]); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + + private void service2(HttpServletRequest request, HttpServletResponse response) throws IOException + { + try + { + requestLatch1.countDown(); + requestLatch2.await(); + ServletOutputStream output = response.getOutputStream(); + int length = 512 * 1024; + AbstractHTTP2ServerConnectionFactory h2 = connector.getConnectionFactory(AbstractHTTP2ServerConnectionFactory.class); + if (h2 != null) + length = h2.getHttpConfiguration().getOutputAggregationSize(); + // Medium write so we don't aggregate it, must not block. + output.write(new byte[length * 2]); + } + catch (IOException x) + { + writeLatch1.countDown(); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + }); + + ByteBufferPool byteBufferPool = client.getByteBufferPool(); + try (SocketChannel socket = SocketChannel.open()) + { + String host = "localhost"; + int port = connector.getLocalPort(); + socket.connect(new InetSocketAddress(host, port)); + + Generator generator = new Generator(byteBufferPool); + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); + generator.control(lease, new PrefaceFrame()); + Map clientSettings = new HashMap<>(); + // Max stream HTTP/2 flow control window. + clientSettings.put(SettingsFrame.INITIAL_WINDOW_SIZE, Integer.MAX_VALUE); + generator.control(lease, new SettingsFrame(clientSettings, false)); + // Max session HTTP/2 flow control window. + generator.control(lease, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE)); + + HttpURI uri = new HttpURI("http", host, port, servletPath + "/1"); + MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, new HttpFields()); + HeadersFrame headersFrame = new HeadersFrame(3, request, null, true); + generator.control(lease, headersFrame); + + List buffers = lease.getByteBuffers(); + socket.write(buffers.toArray(new ByteBuffer[0])); + + waitUntilTCPCongested(exchanger.exchange(null)); + + // Send a second request. + uri = new HttpURI("http", host, port, servletPath + "/2"); + request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, new HttpFields()); + int streamId = 5; + headersFrame = new HeadersFrame(streamId, request, null, true); + generator.control(lease, headersFrame); + buffers = lease.getByteBuffers(); + socket.write(buffers.toArray(new ByteBuffer[0])); + assertTrue(requestLatch1.await(5, TimeUnit.SECONDS)); + + // Now reset the second request, which has not started writing yet. + lease.recycle(); + generator.control(lease, new ResetFrame(streamId, ErrorCode.CANCEL_STREAM_ERROR.code)); + buffers = lease.getByteBuffers(); + socket.write(buffers.toArray(new ByteBuffer[0])); + // Wait to be sure that the server processed the reset. + Thread.sleep(1000); + // Let the request write, it should not block. + requestLatch2.countDown(); + assertTrue(writeLatch1.await(5, TimeUnit.SECONDS)); + } + } + + private void waitUntilTCPCongested(WriteFlusher flusher) throws TimeoutException, InterruptedException + { + long start = System.nanoTime(); + while (!flusher.isPending()) + { + long elapsed = System.nanoTime() - start; + if (TimeUnit.NANOSECONDS.toSeconds(elapsed) > 15) + throw new TimeoutException(); + Thread.sleep(100); + } + // Wait for the selector to update the SelectionKey to OP_WRITE. + Thread.sleep(1000); + } } diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/TrailersTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/TrailersTest.java index 1c756042634..4426b71a70c 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/TrailersTest.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/TrailersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client; @@ -37,6 +37,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.HTTP2Session; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.api.server.ServerSessionListener; @@ -298,7 +299,34 @@ public class TrailersTest extends AbstractTest } @Test - public void testRequestTrailerInvalidHpack() throws Exception + public void testRequestTrailerInvalidHpackSent() throws Exception + { + start(new EmptyHttpServlet()); + + Session session = newClient(new Session.Listener.Adapter()); + MetaData.Request request = newRequest("POST", new HttpFields()); + HeadersFrame requestFrame = new HeadersFrame(request, null, false); + FuturePromise promise = new FuturePromise<>(); + session.newStream(requestFrame, promise, new Stream.Listener.Adapter()); + Stream stream = promise.get(5, TimeUnit.SECONDS); + ByteBuffer data = ByteBuffer.wrap(StringUtil.getUtf8Bytes("hello")); + Callback.Completable completable = new Callback.Completable(); + stream.data(new DataFrame(stream.getId(), data, false), completable); + CountDownLatch failureLatch = new CountDownLatch(1); + completable.thenRun(() -> + { + // Invalid trailer: cannot contain pseudo headers. + HttpFields trailerFields = new HttpFields(); + trailerFields.put(HttpHeader.C_METHOD, "GET"); + MetaData trailer = new MetaData(HttpVersion.HTTP_2, trailerFields); + HeadersFrame trailerFrame = new HeadersFrame(stream.getId(), trailer, null, true); + stream.headers(trailerFrame, Callback.from(Callback.NOOP::succeeded, x -> failureLatch.countDown())); + }); + assertTrue(failureLatch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testRequestTrailerInvalidHpackReceived() throws Exception { CountDownLatch serverLatch = new CountDownLatch(1); start(new HttpServlet() @@ -344,6 +372,8 @@ public class TrailersTest extends AbstractTest stream.data(new DataFrame(stream.getId(), data, false), completable); completable.thenRun(() -> { + // Disable checks for invalid headers. + ((HTTP2Session)session).getGenerator().setValidateHpackEncoding(false); // Invalid trailer: cannot contain pseudo headers. HttpFields trailerFields = new HttpFields(); trailerFields.put(HttpHeader.C_METHOD, "GET"); diff --git a/jetty-http2/http2-client/src/test/resources/jetty-logging.properties b/jetty-http2/http2-client/src/test/resources/jetty-logging.properties index 5304801a325..c94292482f0 100644 --- a/jetty-http2/http2-client/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-client/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.http2.LEVEL=DEBUG org.eclipse.jetty.http2.hpack.LEVEL=INFO diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 995a3b8d592..ed81bead357 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -16,12 +16,22 @@ http2-hpack ${project.version} + + org.slf4j + slf4j-api + + org.eclipse.jetty jetty-jmx ${project.version} true + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-http2/http2-common/src/main/java/module-info.java b/jetty-http2/http2-common/src/main/java/module-info.java index 956d06b679c..592d25f361e 100644 --- a/jetty-http2/http2-common/src/main/java/module-info.java +++ b/jetty-http2/http2-common/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.http2.common @@ -25,8 +25,6 @@ module org.eclipse.jetty.http2.common exports org.eclipse.jetty.http2.generator; exports org.eclipse.jetty.http2.parser; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.http2.hpack; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.http2.hpack; + requires org.slf4j; } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java index 80c66c2af0b..f4b2823b7fa 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -30,13 +30,13 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject public abstract class AbstractFlowControlStrategy implements FlowControlStrategy, Dumpable { - protected static final Logger LOG = Log.getLogger(FlowControlStrategy.class); + protected static final Logger LOG = LoggerFactory.getLogger(FlowControlStrategy.class); private final AtomicLong sessionStall = new AtomicLong(); private final AtomicLong sessionStallTime = new AtomicLong(); diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java index a5a57fa2666..20db018a96f 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -170,7 +170,7 @@ public class BufferingFlowControlStrategy extends AbstractFlowControlStrategy // and here we keep track of its max value. // Updating the max session recv window is done here - // so that if a peer decides to send an unilateral + // so that if a peer decides to send a unilateral // window update to enlarge the session window, // without the corresponding data consumption, here // we can track it. diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/CloseState.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/CloseState.java index 6b90b89165f..b00edb43a91 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/CloseState.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/CloseState.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java index dfe91e6c7c9..175f5dc8637 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -40,7 +40,7 @@ public enum ErrorCode */ INTERNAL_ERROR(2), /** - * Indicates a HTTP/2 flow control violation. + * Indicates an HTTP/2 flow control violation. */ FLOW_CONTROL_ERROR(3), /** @@ -68,7 +68,7 @@ public enum ErrorCode */ COMPRESSION_ERROR(9), /** - * Indicates that the connection established by a HTTP CONNECT was abnormally closed. + * Indicates that the connection established by an HTTP CONNECT was abnormally closed. */ HTTP_CONNECT_ERROR(10), /** diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/Flags.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/Flags.java index c2d9488a799..45ee4656869 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/Flags.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/Flags.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/FlowControlStrategy.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/FlowControlStrategy.java index 4faefa85a3c..91a69875f12 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/FlowControlStrategy.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/FlowControlStrategy.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Channel.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Channel.java new file mode 100644 index 00000000000..aa7f4c2329d --- /dev/null +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Channel.java @@ -0,0 +1,65 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2; + +import java.util.function.Consumer; + +import org.eclipse.jetty.http2.frames.DataFrame; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.util.Callback; + +/** + *

      A HTTP/2 specific handler of events for normal and tunneled exchanges.

      + */ +public interface HTTP2Channel +{ + /** + *

      A client specific handler for events that happen after + * a {@code HEADERS} response frame is received.

      + *

      {@code DATA} frames may be handled as response content + * or as opaque tunnelled data.

      + */ + public interface Client + { + public void onData(DataFrame frame, Callback callback); + + public boolean onTimeout(Throwable failure); + + public void onFailure(Throwable failure, Callback callback); + } + + /** + *

      A server specific handler for events that happen after + * a {@code HEADERS} request frame is received.

      + *

      {@code DATA} frames may be handled as request content + * or as opaque tunnelled data.

      + */ + public interface Server + { + public Runnable onData(DataFrame frame, Callback callback); + + public Runnable onTrailer(HeadersFrame frame); + + public boolean onTimeout(Throwable failure, Consumer consumer); + + public Runnable onFailure(Throwable failure, Callback callback); + + public boolean isIdle(); + } +} diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Cipher.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Cipher.java index 8d8d3379771..d287934fee2 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Cipher.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Cipher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java index 2e1238c1731..2f103d8d609 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -29,21 +29,22 @@ import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.parser.Parser; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.RetainableByteBuffer; import org.eclipse.jetty.io.WriteFlusher; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ExecutionStrategy; import org.eclipse.jetty.util.thread.TryExecutor; import org.eclipse.jetty.util.thread.strategy.EatWhatYouKill; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class HTTP2Connection extends AbstractConnection implements WriteFlusher.Listener +public class HTTP2Connection extends AbstractConnection implements WriteFlusher.Listener, Connection.UpgradeTo { - protected static final Logger LOG = Log.getLogger(HTTP2Connection.class); + protected static final Logger LOG = LoggerFactory.getLogger(HTTP2Connection.class); // TODO remove this once we are sure EWYK is OK for http2 private static final boolean PEC_MODE = Boolean.getBoolean("org.eclipse.jetty.http2.PEC_MODE"); @@ -56,6 +57,8 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. private final ISession session; private final int bufferSize; private final ExecutionStrategy strategy; + private boolean useInputDirectByteBuffers; + private boolean useOutputDirectByteBuffers; public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize) { @@ -93,12 +96,35 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. return parser; } - protected void setInputBuffer(ByteBuffer buffer) + @Override + public void onUpgradeTo(ByteBuffer buffer) { + if (LOG.isDebugEnabled()) + LOG.debug("HTTP2 onUpgradeTo {} {}", this, BufferUtil.toDetailString(buffer)); if (buffer != null) producer.setInputBuffer(buffer); } + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + @Override public void onOpen() { @@ -309,7 +335,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. if (currentBuffer == null) throw new IllegalStateException(); - if (currentBuffer.getBuffer().hasRemaining()) + if (currentBuffer.hasRemaining()) throw new IllegalStateException(); currentBuffer.release(); @@ -389,7 +415,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher. { private NetworkBuffer() { - super(byteBufferPool, bufferSize, false); + super(byteBufferPool, bufferSize, isUseInputDirectByteBuffers()); } private void put(ByteBuffer source) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java index 350751ead3c..bc249bd0b2c 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -30,17 +30,18 @@ import java.util.Set; import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; +import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HTTP2Flusher extends IteratingCallback implements Dumpable { - private static final Logger LOG = Log.getLogger(HTTP2Flusher.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2Flusher.class); private static final ByteBuffer[] EMPTY_BYTE_BUFFERS = new ByteBuffer[0]; private final Queue windows = new ArrayDeque<>(); @@ -207,6 +208,13 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable } } } + catch (HpackException.StreamException failure) + { + if (LOG.isDebugEnabled()) + LOG.debug("Failure generating " + entry, failure); + entry.failed(failure); + pending.remove(); + } catch (Throwable failure) { // Failure to generate the entry is catastrophic. @@ -397,7 +405,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable return 0; } - protected abstract boolean generate(ByteBufferPool.Lease lease); + protected abstract boolean generate(ByteBufferPool.Lease lease) throws HpackException; public abstract long onFlushed(long bytes) throws IOException; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java index 1ffafe92065..097fecb5a59 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java @@ -1,30 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; import java.io.IOException; +import java.net.InetSocketAddress; import java.nio.channels.ClosedChannelException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; @@ -33,6 +35,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.frames.DataFrame; @@ -43,12 +46,14 @@ import org.eclipse.jetty.http2.frames.FrameType; import org.eclipse.jetty.http2.frames.GoAwayFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.PingFrame; +import org.eclipse.jetty.http2.frames.PrefaceFrame; import org.eclipse.jetty.http2.frames.PriorityFrame; import org.eclipse.jetty.http2.frames.PushPromiseFrame; import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.http2.parser.Parser; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; @@ -57,22 +62,23 @@ import org.eclipse.jetty.util.AtomicBiInteger; import org.eclipse.jetty.util.Atomics; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.CountingCallback; +import org.eclipse.jetty.util.MathUtils; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.Retainable; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject public abstract class HTTP2Session extends ContainerLifeCycle implements ISession, Parser.Listener { - private static final Logger LOG = Log.getLogger(HTTP2Session.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2Session.class); private final ConcurrentMap streams = new ConcurrentHashMap<>(); + private final AtomicBiInteger streamCount = new AtomicBiInteger(); // Hi = closed, Lo = stream count private final AtomicInteger localStreamIds = new AtomicInteger(); private final AtomicInteger lastRemoteStreamId = new AtomicInteger(); private final AtomicInteger localStreamCount = new AtomicInteger(); @@ -93,8 +99,10 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio private int initialSessionRecvWindow; private int writeThreshold; private boolean pushEnabled; + private boolean connectProtocolEnabled; private long idleTime; private GoAwayFrame closeFrame; + private Callback.Completable shutdownCallback; public HTTP2Session(Scheduler scheduler, EndPoint endPoint, Generator generator, Session.Listener listener, FlowControlStrategy flowControl, int initialStreamId) { @@ -366,6 +374,14 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio generator.setMaxHeaderListSize(value); break; } + case SettingsFrame.ENABLE_CONNECT_PROTOCOL: + { + boolean enabled = value == 1; + if (LOG.isDebugEnabled()) + LOG.debug("{} CONNECT protocol for {}", enabled ? "Enabling" : "Disabling", this); + connectProtocolEnabled = enabled; + break; + } default: { if (LOG.isDebugEnabled()) @@ -423,31 +439,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio if (LOG.isDebugEnabled()) LOG.debug("Received {}", frame); - while (true) + if (closed.compareAndSet(CloseState.NOT_CLOSED, CloseState.REMOTELY_CLOSED)) { - CloseState current = closed.get(); - switch (current) - { - case NOT_CLOSED: - { - if (closed.compareAndSet(current, CloseState.REMOTELY_CLOSED)) - { - // We received a GO_AWAY, so try to write - // what's in the queue and then disconnect. - closeFrame = frame; - notifyClose(this, frame, new DisconnectCallback()); - return; - } - break; - } - default: - { - if (LOG.isDebugEnabled()) - LOG.debug("Ignored {}, already closed", frame); - return; - } - } + // We received a GO_AWAY, so try to write + // what's in the queue and then disconnect. + closeFrame = frame; + notifyClose(this, frame, new DisconnectCallback()); + return; } + + if (LOG.isDebugEnabled()) + LOG.debug("Ignored {}, already closed", frame); } @Override @@ -460,47 +462,33 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio int windowDelta = frame.getWindowDelta(); if (streamId > 0) { - if (windowDelta == 0) + IStream stream = getStream(streamId); + if (stream != null) { - reset(new ResetFrame(streamId, ErrorCode.PROTOCOL_ERROR.code), Callback.NOOP); - } - else - { - IStream stream = getStream(streamId); - if (stream != null) + int streamSendWindow = stream.updateSendWindow(0); + if (MathUtils.sumOverflows(streamSendWindow, windowDelta)) { - int streamSendWindow = stream.updateSendWindow(0); - if (sumOverflows(streamSendWindow, windowDelta)) - { - reset(new ResetFrame(streamId, ErrorCode.FLOW_CONTROL_ERROR.code), Callback.NOOP); - } - else - { - stream.process(frame, Callback.NOOP); - onWindowUpdate(stream, frame); - } + reset(new ResetFrame(streamId, ErrorCode.FLOW_CONTROL_ERROR.code), Callback.NOOP); } else { - if (!isRemoteStreamClosed(streamId)) - onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "unexpected_window_update_frame"); + stream.process(frame, Callback.NOOP); + onWindowUpdate(stream, frame); } } + else + { + if (!isRemoteStreamClosed(streamId)) + onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "unexpected_window_update_frame"); + } } else { - if (windowDelta == 0) - { - onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "invalid_window_update_frame"); - } + int sessionSendWindow = updateSendWindow(0); + if (MathUtils.sumOverflows(sessionSendWindow, windowDelta)) + onConnectionFailure(ErrorCode.FLOW_CONTROL_ERROR.code, "invalid_flow_control_window"); else - { - int sessionSendWindow = updateSendWindow(0); - if (sumOverflows(sessionSendWindow, windowDelta)) - onConnectionFailure(ErrorCode.FLOW_CONTROL_ERROR.code, "invalid_flow_control_window"); - else - onWindowUpdate(null, frame); - } + onWindowUpdate(null, frame); } } @@ -530,19 +518,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio callback.succeeded(); } - private boolean sumOverflows(int a, int b) - { - try - { - Math.addExact(a, b); - return false; - } - catch (ArithmeticException x) - { - return true; - } - } - @Override public void onConnectionFailure(int error, String reason) { @@ -551,7 +526,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio protected void onConnectionFailure(int error, String reason, Callback callback) { - notifyFailure(this, new IOException(String.format("%d/%s", error, reason)), new CloseCallback(error, reason, callback)); + notifyFailure(this, new IOException(String.format("%d/%s", error, reason)), new FailureCallback(error, reason, callback)); } @Override @@ -561,24 +536,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio { // Synchronization is necessary to atomically create // the stream id and enqueue the frame to be sent. + IStream stream; boolean queued; synchronized (this) { - int streamId = frame.getStreamId(); - if (streamId <= 0) - { - streamId = localStreamIds.getAndAdd(2); - PriorityFrame priority = frame.getPriority(); - priority = priority == null ? null : new PriorityFrame(streamId, priority.getParentStreamId(), - priority.getWeight(), priority.isExclusive()); - frame = new HeadersFrame(streamId, frame.getMetaData(), priority, frame.isEndStream()); - } - IStream stream = createLocalStream(streamId); + HeadersFrame[] frameOut = new HeadersFrame[1]; + stream = newStream(frame, frameOut); stream.setListener(listener); - - ControlEntry entry = new ControlEntry(frame, stream, new StreamPromiseCallback(promise, stream)); + ControlEntry entry = new ControlEntry(frameOut[0], stream, new StreamPromiseCallback(promise, stream)); queued = flusher.append(entry); } + stream.process(new PrefaceFrame(), Callback.NOOP); // Iterate outside the synchronized block. if (queued) flusher.iterate(); @@ -589,9 +557,36 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } } - protected IStream newStream(int streamId, boolean local) + /** + *

      Creates a new stream allocating a stream id if the given HEADERS frame does not have one.

      + *

      The new HEADERS frame with the newly allocated stream id is returned as the first element + * of the array parameter.

      + * + * @param frameIn the HEADERS frame that triggered the stream creation + * @param frameOut an array of size 1 to return the HEADERS frame with the newly + * allocated stream id, or null if not interested in the modified headers frame + * @return a new stream + */ + public IStream newStream(HeadersFrame frameIn, HeadersFrame[] frameOut) { - return new HTTP2Stream(scheduler, this, streamId, local); + HeadersFrame frame = frameIn; + int streamId = frameIn.getStreamId(); + if (streamId <= 0) + { + streamId = localStreamIds.getAndAdd(2); + PriorityFrame priority = frameIn.getPriority(); + priority = priority == null ? null : new PriorityFrame(streamId, priority.getParentStreamId(), + priority.getWeight(), priority.isExclusive()); + frame = new HeadersFrame(streamId, frameIn.getMetaData(), priority, frameIn.isEndStream()); + } + if (frameOut != null) + frameOut[0] = frame; + return createLocalStream(streamId, (MetaData.Request)frame.getMetaData()); + } + + protected IStream newStream(int streamId, MetaData.Request request, boolean local) + { + return new HTTP2Stream(scheduler, this, streamId, request, local); } @Override @@ -622,7 +617,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio int streamId = localStreamIds.getAndAdd(2); frame = new PushPromiseFrame(frame.getStreamId(), streamId, frame.getMetaData()); - IStream pushStream = createLocalStream(streamId); + IStream pushStream = createLocalStream(streamId, frame.getMetaData()); pushStream.setListener(listener); ControlEntry entry = new ControlEntry(frame, pushStream, new StreamPromiseCallback(promise, pushStream)); @@ -684,30 +679,42 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio @Override public boolean close(int error, String reason, Callback callback) { - while (true) + if (closed.compareAndSet(CloseState.NOT_CLOSED, CloseState.LOCALLY_CLOSED)) { - CloseState current = closed.get(); - switch (current) - { - case NOT_CLOSED: - { - if (closed.compareAndSet(current, CloseState.LOCALLY_CLOSED)) - { - closeFrame = newGoAwayFrame(CloseState.LOCALLY_CLOSED, error, reason); - control(null, callback, closeFrame); - return true; - } - break; - } - default: - { - if (LOG.isDebugEnabled()) - LOG.debug("Ignoring close {}/{}, already closed", error, reason); - callback.succeeded(); - return false; - } - } + if (LOG.isDebugEnabled()) + LOG.debug("Closing {}/{}", error, reason); + closeFrame = newGoAwayFrame(CloseState.LOCALLY_CLOSED, error, reason); + control(null, callback, closeFrame); + return true; } + + if (LOG.isDebugEnabled()) + LOG.debug("Ignoring close {}/{}, already closed", error, reason); + callback.succeeded(); + return false; + } + + @Override + public CompletableFuture shutdown() + { + if (closed.compareAndSet(CloseState.NOT_CLOSED, CloseState.LOCALLY_CLOSED)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Shutting down {}", this); + closeFrame = newGoAwayFrame(CloseState.LOCALLY_CLOSED, ErrorCode.NO_ERROR.code, "shutdown"); + shutdownCallback = new Callback.Completable(); + // Only send the close frame when we can flip Hi and Lo = 0, see onStreamClosed(). + if (streamCount.compareAndSet(0, 1, 0, 0)) + control(null, shutdownCallback, closeFrame); + return shutdownCallback; + } + + if (LOG.isDebugEnabled()) + LOG.debug("Ignoring shutdown, already closed"); + Callback.Completable result = shutdownCallback; + // Result may be null if the shutdown is in progress, + // don't wait and return a completed CompletableFuture. + return result != null ? result : CompletableFuture.completedFuture(null); } private GoAwayFrame newGoAwayFrame(CloseState closeState, int error, String reason) @@ -778,7 +785,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } } - protected IStream createLocalStream(int streamId) + protected IStream createLocalStream(int streamId, MetaData.Request request) { while (true) { @@ -791,7 +798,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio break; } - IStream stream = newStream(streamId, true); + IStream stream = newStream(streamId, request, true); if (streams.putIfAbsent(streamId, stream) == null) { stream.setIdleTimeout(getStreamIdleTimeout()); @@ -807,7 +814,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } } - protected IStream createRemoteStream(int streamId) + protected IStream createRemoteStream(int streamId, MetaData.Request request) { // SPEC: exceeding max concurrent streams is treated as stream error. while (true) @@ -818,6 +825,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio int maxCount = getMaxRemoteStreams(); if (maxCount >= 0 && remoteCount - remoteClosing >= maxCount) { + updateLastRemoteStreamId(streamId); reset(new ResetFrame(streamId, ErrorCode.REFUSED_STREAM_ERROR.code), Callback.NOOP); return null; } @@ -825,7 +833,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio break; } - IStream stream = newStream(streamId, false); + IStream stream = newStream(streamId, request, false); // SPEC: duplicate stream is treated as connection error. if (streams.putIfAbsent(streamId, stream) == null) @@ -884,6 +892,18 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio return streams.get(streamId); } + @Override + public InetSocketAddress getLocalAddress() + { + return endPoint.getLocalAddress(); + } + + @Override + public InetSocketAddress getRemoteAddress() + { + return endPoint.getRemoteAddress(); + } + @ManagedAttribute(value = "The flow control send window", readonly = true) public int getSendWindow() { @@ -915,6 +935,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio return pushEnabled; } + @ManagedAttribute(value = "Whether CONNECT requests supports a protocol", readonly = true) + public boolean isConnectProtocolEnabled() + { + return connectProtocolEnabled; + } + + public void setConnectProtocolEnabled(boolean connectProtocolEnabled) + { + this.connectProtocolEnabled = connectProtocolEnabled; + } + /** * A typical close by a remote peer involves a GO_AWAY frame followed by TCP FIN. * This method is invoked when the TCP FIN is received, or when an exception is @@ -1030,10 +1061,28 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio protected void onStreamOpened(IStream stream) { + streamCount.addAndGetLo(1); } protected void onStreamClosed(IStream stream) { + Callback callback = null; + while (true) + { + long encoded = streamCount.get(); + int closed = AtomicBiInteger.getHi(encoded); + int streams = AtomicBiInteger.getLo(encoded) - 1; + if (streams == 0 && closed == 0) + { + callback = shutdownCallback; + closed = 1; + } + if (streamCount.compareAndSet(encoded, closed, streams)) + break; + } + // Only send the close frame if we can flip Hi and Lo = 0, see shutdown(). + if (callback != null) + control(null, callback, closeFrame); } @Override @@ -1245,7 +1294,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } @Override - protected boolean generate(ByteBufferPool.Lease lease) + protected boolean generate(ByteBufferPool.Lease lease) throws HpackException { frameBytes = generator.control(lease, frame); beforeSend(); @@ -1310,8 +1359,9 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio { case HEADERS: { - onStreamOpened(stream); HeadersFrame headersFrame = (HeadersFrame)frame; + if (headersFrame.getMetaData().isRequest()) + onStreamOpened(stream); if (stream.updateClose(headersFrame.isEndStream(), CloseState.Event.AFTER_SEND)) removeStream(stream); break; @@ -1491,7 +1541,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } } - private class DataCallback extends Callback.Nested implements Retainable + private class DataCallback extends Callback.Nested { private final IStream stream; private final int flowControlLength; @@ -1503,14 +1553,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio this.flowControlLength = flowControlLength; } - @Override - public void retain() - { - Callback callback = getCallback(); - if (callback instanceof Retainable) - ((Retainable)callback).retain(); - } - @Override public void succeeded() { @@ -1556,6 +1598,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio @Override public void failed(Throwable x) { + if (LOG.isDebugEnabled()) + LOG.debug("Reset failed", x); complete(); } @@ -1576,6 +1620,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio @Override public void failed(Throwable x) { + if (LOG.isDebugEnabled()) + LOG.debug("OnReset failed", x); complete(); } @@ -1591,12 +1637,12 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } } - private class CloseCallback extends Callback.Nested + private class FailureCallback extends Callback.Nested { private final int error; private final String reason; - private CloseCallback(int error, String reason, Callback callback) + private FailureCallback(int error, String reason, Callback callback) { super(callback); this.error = error; @@ -1612,6 +1658,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio @Override public void failed(Throwable x) { + if (LOG.isDebugEnabled()) + LOG.debug("CloseCallback failed", x); complete(); } @@ -1632,6 +1680,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio @Override public void failed(Throwable x) { + if (LOG.isDebugEnabled()) + LOG.debug("DisconnectCallback failed", x); complete(); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java index 4da6aaa8d1f..3fefbdab6da 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -21,6 +21,8 @@ package org.eclipse.jetty.http2; import java.io.EOFException; import java.io.IOException; import java.nio.channels.WritePendingException; +import java.util.ArrayDeque; +import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; @@ -30,6 +32,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.frames.DataFrame; @@ -41,16 +44,20 @@ import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.io.IdleTimeout; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.MathUtils; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.AutoLock; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpable { - private static final Logger LOG = Log.getLogger(HTTP2Stream.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2Stream.class); + private final AutoLock lock = new AutoLock(); + private final Queue dataQueue = new ArrayDeque<>(); private final AtomicReference attachment = new AtomicReference<>(); private final AtomicReference> attributes = new AtomicReference<>(); private final AtomicReference closeState = new AtomicReference<>(CloseState.NOT_CLOSED); @@ -60,19 +67,25 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa private final long timeStamp = System.nanoTime(); private final ISession session; private final int streamId; + private final MetaData.Request request; private final boolean local; private boolean localReset; private Listener listener; private boolean remoteReset; private long dataLength; + private long dataDemand; + private boolean dataInitial; + private boolean dataProcess; - public HTTP2Stream(Scheduler scheduler, ISession session, int streamId, boolean local) + public HTTP2Stream(Scheduler scheduler, ISession session, int streamId, MetaData.Request request, boolean local) { super(scheduler); this.session = session; this.streamId = streamId; + this.request = request; this.local = local; this.dataLength = Long.MIN_VALUE; + this.dataInitial = true; } @Override @@ -237,6 +250,11 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa notIdle(); switch (frame.getType()) { + case PREFACE: + { + onNewStream(callback); + break; + } case HEADERS: { onHeaders((HeadersFrame)frame, callback); @@ -274,6 +292,12 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa } } + private void onNewStream(Callback callback) + { + notifyNewStream(this); + callback.succeeded(); + } + private void onHeaders(HeadersFrame frame, Callback callback) { MetaData metaData = frame.getMetaData(); @@ -281,7 +305,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa { HttpFields fields = metaData.getFields(); long length = -1; - if (fields != null) + if (fields != null && !HttpMethod.CONNECT.is(request.getMethod())) length = fields.getLongField(HttpHeader.CONTENT_LENGTH.asString()); dataLength = length >= 0 ? length : Long.MIN_VALUE; } @@ -298,7 +322,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa { // It's a bad client, it does not deserve to be // treated gently by just resetting the stream. - session.close(ErrorCode.FLOW_CONTROL_ERROR.code, "stream_window_exceeded", Callback.NOOP); + ((HTTP2Session)session).onConnectionFailure(ErrorCode.FLOW_CONTROL_ERROR.code, "stream_window_exceeded"); callback.failed(new IOException("stream_window_exceeded")); return; } @@ -329,10 +353,90 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa } } - if (updateClose(frame.isEndStream(), CloseState.Event.RECEIVED)) - session.removeStream(this); + boolean initial; + boolean proceed = false; + DataEntry entry = new DataEntry(frame, callback); + try (AutoLock l = lock.lock()) + { + dataQueue.offer(entry); + initial = dataInitial; + if (initial) + { + dataInitial = false; + // Fake that we are processing data so we return + // from onBeforeData() before calling onData(). + dataProcess = true; + } + else if (!dataProcess) + { + dataProcess = proceed = dataDemand > 0; + } + } + if (initial) + { + if (LOG.isDebugEnabled()) + LOG.debug("Starting data processing of {} for {}", frame, this); + notifyBeforeData(this); + try (AutoLock l = lock.lock()) + { + dataProcess = proceed = dataDemand > 0; + } + } + if (LOG.isDebugEnabled()) + LOG.debug("{} data processing of {} for {}", proceed ? "Proceeding" : "Stalling", frame, this); + if (proceed) + processData(); + } - notifyData(this, frame, callback); + @Override + public void demand(long n) + { + if (n <= 0) + throw new IllegalArgumentException("Invalid demand " + n); + long demand; + boolean proceed = false; + try (AutoLock l = lock.lock()) + { + demand = dataDemand = MathUtils.cappedAdd(dataDemand, n); + if (!dataProcess) + dataProcess = proceed = !dataQueue.isEmpty(); + } + if (LOG.isDebugEnabled()) + LOG.debug("Demand {}/{}, {} data processing for {}", n, demand, proceed ? "proceeding" : "stalling", this); + if (proceed) + processData(); + } + + private void processData() + { + while (true) + { + DataEntry dataEntry; + try (AutoLock l = lock.lock()) + { + if (dataQueue.isEmpty() || dataDemand == 0) + { + if (LOG.isDebugEnabled()) + LOG.debug("Stalling data processing for {}", this); + dataProcess = false; + return; + } + --dataDemand; + dataEntry = dataQueue.poll(); + } + DataFrame frame = dataEntry.frame; + if (updateClose(frame.isEndStream(), CloseState.Event.RECEIVED)) + session.removeStream(this); + notifyDataDemanded(this, frame, dataEntry.callback); + } + } + + private long demand() + { + try (AutoLock l = lock.lock()) + { + return dataDemand; + } } private void onReset(ResetFrame frame, Callback callback) @@ -543,14 +647,50 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa return writing.getAndSet(null); } - private void notifyData(Stream stream, DataFrame frame, Callback callback) + private void notifyNewStream(Stream stream) { Listener listener = this.listener; if (listener != null) { try { - listener.onData(stream, frame, callback); + listener.onNewStream(stream); + } + catch (Throwable x) + { + LOG.info("Failure while notifying listener " + listener, x); + } + } + } + + private void notifyBeforeData(Stream stream) + { + Listener listener = this.listener; + if (listener != null) + { + try + { + listener.onBeforeData(stream); + } + catch (Throwable x) + { + LOG.info("Failure while notifying listener " + listener, x); + } + } + else + { + stream.demand(1); + } + } + + private void notifyDataDemanded(Stream stream, DataFrame frame, Callback callback) + { + Listener listener = this.listener; + if (listener != null) + { + try + { + listener.onDataDemanded(stream, frame, callback); } catch (Throwable x) { @@ -561,6 +701,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa else { callback.succeeded(); + stream.demand(1); } } @@ -652,16 +793,29 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa @Override public String toString() { - return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b/%b,%s,age=%d,attachment=%s}", + return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,demand=%d,reset=%b/%b,%s,age=%d,attachment=%s}", getClass().getSimpleName(), hashCode(), getId(), sendWindow, recvWindow, + demand(), localReset, remoteReset, closeState, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - timeStamp), attachment); } + + private static class DataEntry + { + private final DataFrame frame; + private final Callback callback; + + private DataEntry(DataFrame frame, Callback callback) + { + this.frame = frame; + this.callback = callback; + } + } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2StreamEndPoint.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2StreamEndPoint.java new file mode 100644 index 00000000000..5c3e5bbc19e --- /dev/null +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2StreamEndPoint.java @@ -0,0 +1,659 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadPendingException; +import java.nio.channels.WritePendingException; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jetty.http2.frames.DataFrame; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.EofException; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.thread.Invocable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class HTTP2StreamEndPoint implements EndPoint +{ + private static final Logger LOG = LoggerFactory.getLogger(HTTP2StreamEndPoint.class); + + private final Deque dataQueue = new ArrayDeque<>(); + private final AtomicReference writeState = new AtomicReference<>(WriteState.IDLE); + private final AtomicReference readCallback = new AtomicReference<>(); + private final long created = System.currentTimeMillis(); + private final AtomicBoolean eof = new AtomicBoolean(); + private final AtomicBoolean closed = new AtomicBoolean(); + private final IStream stream; + private Connection connection; + + public HTTP2StreamEndPoint(IStream stream) + { + this.stream = stream; + } + + @Override + public InetSocketAddress getLocalAddress() + { + return stream.getSession().getLocalAddress(); + } + + @Override + public InetSocketAddress getRemoteAddress() + { + return stream.getSession().getRemoteAddress(); + } + + @Override + public boolean isOpen() + { + return !closed.get(); + } + + @Override + public long getCreatedTimeStamp() + { + return created; + } + + @Override + public void shutdownOutput() + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case OSHUTTING: + if (!writeState.compareAndSet(current, WriteState.OSHUT)) + break; + stream.data(new DataFrame(stream.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.from(this::oshutSuccess, this::oshutFailure)); + return; + case PENDING: + if (!writeState.compareAndSet(current, WriteState.OSHUTTING)) + break; + return; + case OSHUT: + case FAILED: + return; + } + } + } + + private void oshutSuccess() + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case PENDING: + case OSHUTTING: + throw new IllegalStateException(); + case OSHUT: + case FAILED: + break; + } + } + + private void oshutFailure(Throwable failure) + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case PENDING: + case OSHUTTING: + throw new IllegalStateException(); + case OSHUT: + if (!writeState.compareAndSet(current, new WriteState(WriteState.State.FAILED, failure))) + break; + return; + case FAILED: + return; + } + } + } + + @Override + public boolean isOutputShutdown() + { + WriteState.State state = writeState.get().state; + return state == WriteState.State.OSHUTTING || state == WriteState.State.OSHUT; + } + + @Override + public boolean isInputShutdown() + { + return eof.get(); + } + + @Override + public void close(Throwable cause) + { + if (closed.compareAndSet(false, true)) + { + if (LOG.isDebugEnabled()) + LOG.debug("closing {}, cause: {}", this, cause); + shutdownOutput(); + stream.close(); + onClose(cause); + } + } + + @Override + public int fill(ByteBuffer sink) throws IOException + { + Entry entry; + synchronized (this) + { + entry = dataQueue.poll(); + } + + if (LOG.isDebugEnabled()) + LOG.debug("filled {} on {}", entry, this); + + if (entry == null) + return 0; + if (entry.isEOF()) + { + entry.succeed(); + return shutdownInput(); + } + IOException failure = entry.ioFailure(); + if (failure != null) + { + entry.fail(failure); + throw failure; + } + + int sinkPosition = BufferUtil.flipToFill(sink); + ByteBuffer source = entry.buffer; + int sourceLength = source.remaining(); + int length = Math.min(sourceLength, sink.remaining()); + int sourceLimit = source.limit(); + source.limit(source.position() + length); + sink.put(source); + source.limit(sourceLimit); + BufferUtil.flipToFlush(sink, sinkPosition); + + if (source.hasRemaining()) + { + synchronized (this) + { + dataQueue.offerFirst(entry); + } + } + else + { + entry.succeed(); + } + return length; + } + + private int shutdownInput() + { + eof.set(true); + return -1; + } + + @Override + public boolean flush(ByteBuffer... buffers) throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("flushing {} on {}", BufferUtil.toDetailString(buffers), this); + if (buffers == null || buffers.length == 0) + { + return true; + } + else + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + if (!writeState.compareAndSet(current, WriteState.PENDING)) + break; + // We must copy the buffers because, differently from + // write(), the semantic of flush() is that it does not + // own them, but stream.data() needs to own them. + ByteBuffer buffer = coalesce(buffers, true); + Callback.Completable callback = new Callback.Completable(Invocable.InvocationType.NON_BLOCKING); + stream.data(new DataFrame(stream.getId(), buffer, false), callback); + callback.whenComplete((nothing, failure) -> + { + if (failure == null) + flushSuccess(); + else + flushFailure(failure); + }); + return callback.isDone(); + case PENDING: + return false; + case OSHUTTING: + case OSHUT: + throw new EofException("Output shutdown"); + case FAILED: + Throwable failure = current.failure; + if (failure instanceof IOException) + throw (IOException)failure; + throw new IOException(failure); + } + } + } + } + + private void flushSuccess() + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case OSHUT: + throw new IllegalStateException(); + case PENDING: + if (!writeState.compareAndSet(current, WriteState.IDLE)) + break; + return; + case OSHUTTING: + shutdownOutput(); + return; + case FAILED: + return; + } + } + } + + private void flushFailure(Throwable failure) + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case OSHUT: + throw new IllegalStateException(); + case PENDING: + if (!writeState.compareAndSet(current, new WriteState(WriteState.State.FAILED, failure))) + break; + return; + case OSHUTTING: + shutdownOutput(); + return; + case FAILED: + return; + } + } + } + + @Override + public Object getTransport() + { + return stream; + } + + @Override + public long getIdleTimeout() + { + return stream.getIdleTimeout(); + } + + @Override + public void setIdleTimeout(long idleTimeout) + { + stream.setIdleTimeout(idleTimeout); + } + + @Override + public void fillInterested(Callback callback) throws ReadPendingException + { + if (!tryFillInterested(callback)) + throw new ReadPendingException(); + } + + @Override + public boolean tryFillInterested(Callback callback) + { + boolean result = readCallback.compareAndSet(null, callback); + if (result) + process(); + return result; + } + + @Override + public boolean isFillInterested() + { + return readCallback.get() != null; + } + + @Override + public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException + { + if (LOG.isDebugEnabled()) + LOG.debug("writing {} on {}", BufferUtil.toDetailString(buffers), this); + if (buffers == null || buffers.length == 0 || remaining(buffers) == 0) + { + callback.succeeded(); + } + else + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + if (!writeState.compareAndSet(current, WriteState.PENDING)) + break; + // TODO: we really need a Stream primitive to write multiple frames. + ByteBuffer result = coalesce(buffers, false); + stream.data(new DataFrame(stream.getId(), result, false), Callback.from(() -> writeSuccess(callback), x -> writeFailure(x, callback))); + return; + case PENDING: + callback.failed(new WritePendingException()); + return; + case OSHUTTING: + case OSHUT: + callback.failed(new EofException("Output shutdown")); + return; + case FAILED: + callback.failed(current.failure); + return; + } + } + } + } + + private void writeSuccess(Callback callback) + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case OSHUT: + callback.failed(new IllegalStateException()); + return; + case PENDING: + if (!writeState.compareAndSet(current, WriteState.IDLE)) + break; + callback.succeeded(); + return; + case OSHUTTING: + callback.succeeded(); + shutdownOutput(); + return; + case FAILED: + callback.failed(current.failure); + return; + } + } + } + + private void writeFailure(Throwable failure, Callback callback) + { + while (true) + { + WriteState current = writeState.get(); + switch (current.state) + { + case IDLE: + case OSHUT: + callback.failed(new IllegalStateException(failure)); + return; + case PENDING: + case OSHUTTING: + if (!writeState.compareAndSet(current, new WriteState(WriteState.State.FAILED, failure))) + break; + callback.failed(failure); + return; + case FAILED: + return; + } + } + } + + private long remaining(ByteBuffer... buffers) + { + long total = 0; + for (ByteBuffer buffer : buffers) + { + total += buffer.remaining(); + } + return total; + } + + private ByteBuffer coalesce(ByteBuffer[] buffers, boolean forceCopy) + { + if (buffers.length == 1 && !forceCopy) + return buffers[0]; + long capacity = remaining(buffers); + if (capacity > Integer.MAX_VALUE) + throw new BufferOverflowException(); + ByteBuffer result = BufferUtil.allocateDirect((int)capacity); + for (ByteBuffer buffer : buffers) + { + BufferUtil.append(result, buffer); + } + return result; + } + + @Override + public Connection getConnection() + { + return connection; + } + + @Override + public void setConnection(Connection connection) + { + this.connection = connection; + } + + @Override + public void onOpen() + { + if (LOG.isDebugEnabled()) + LOG.debug("onOpen {}", this); + } + + @Override + public void onClose(Throwable cause) + { + if (LOG.isDebugEnabled()) + LOG.debug("onClose {}", this); + } + + @Override + public void upgrade(Connection newConnection) + { + Connection oldConnection = getConnection(); + + ByteBuffer buffer = null; + if (oldConnection instanceof Connection.UpgradeFrom) + buffer = ((Connection.UpgradeFrom)oldConnection).onUpgradeFrom(); + + if (oldConnection != null) + oldConnection.onClose(null); + + if (LOG.isDebugEnabled()) + LOG.debug("upgrading from {} to {} with data {} on {}", oldConnection, newConnection, BufferUtil.toDetailString(buffer), this); + + setConnection(newConnection); + if (newConnection instanceof Connection.UpgradeTo && buffer != null) + ((Connection.UpgradeTo)newConnection).onUpgradeTo(buffer); + + newConnection.onOpen(); + } + + protected void offerData(DataFrame frame, Callback callback) + { + ByteBuffer buffer = frame.getData(); + if (LOG.isDebugEnabled()) + LOG.debug("offering {} on {}", frame, this); + if (frame.isEndStream()) + { + if (buffer.hasRemaining()) + offer(buffer, Callback.from(Callback.NOOP::succeeded, callback::failed), null); + offer(BufferUtil.EMPTY_BUFFER, callback, Entry.EOF); + } + else + { + if (buffer.hasRemaining()) + offer(buffer, callback, null); + else + callback.succeeded(); + } + process(); + } + + protected void offerFailure(Throwable failure) + { + offer(BufferUtil.EMPTY_BUFFER, Callback.NOOP, failure); + process(); + } + + private void offer(ByteBuffer buffer, Callback callback, Throwable failure) + { + synchronized (this) + { + dataQueue.offer(new Entry(buffer, callback, failure)); + } + } + + protected void process() + { + boolean empty; + synchronized (this) + { + empty = dataQueue.isEmpty(); + } + if (!empty) + { + Callback callback = readCallback.getAndSet(null); + if (callback != null) + callback.succeeded(); + } + } + + @Override + public String toString() + { + // Do not call Stream.toString() because it stringifies the attachment, + // which could be this instance, therefore causing a StackOverflowError. + return String.format("%s@%x[%s@%x#%d][w=%s]", getClass().getSimpleName(), hashCode(), + stream.getClass().getSimpleName(), stream.hashCode(), stream.getId(), + writeState); + } + + private static class Entry + { + private static final Throwable EOF = new Throwable(); + + private final ByteBuffer buffer; + private final Callback callback; + private final Throwable failure; + + private Entry(ByteBuffer buffer, Callback callback, Throwable failure) + { + this.buffer = buffer; + this.callback = callback; + this.failure = failure; + } + + private boolean isEOF() + { + return failure == EOF; + } + + private IOException ioFailure() + { + if (failure == null || isEOF()) + return null; + return failure instanceof IOException ? (IOException)failure : new IOException(failure); + } + + private void succeed() + { + callback.succeeded(); + } + + private void fail(Throwable failure) + { + callback.failed(failure); + } + + @Override + public String toString() + { + return String.format("%s@%x[b=%s,eof=%b,f=%s]", getClass().getSimpleName(), hashCode(), + BufferUtil.toDetailString(buffer), isEOF(), isEOF() ? null : failure); + } + } + + private static class WriteState + { + public static final WriteState IDLE = new WriteState(State.IDLE); + public static final WriteState PENDING = new WriteState(State.PENDING); + public static final WriteState OSHUTTING = new WriteState(State.OSHUTTING); + public static final WriteState OSHUT = new WriteState(State.OSHUT); + + private final State state; + private final Throwable failure; + + private WriteState(State state) + { + this(state, null); + } + + private WriteState(State state, Throwable failure) + { + this.state = state; + this.failure = failure; + } + + @Override + public String toString() + { + return state.toString(); + } + + private enum State + { + IDLE, PENDING, OSHUTTING, OSHUT, FAILED + } + } +} diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ISession.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ISession.java index 4e4d483009f..4ad49b481f8 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ISession.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ISession.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; import java.io.IOException; +import java.util.concurrent.CompletableFuture; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.api.Stream; @@ -30,7 +31,7 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; /** - *

      The SPI interface for implementing a HTTP/2 session.

      + *

      The SPI interface for implementing an HTTP/2 session.

      *

      This class extends {@link Session} by adding the methods required to * implement the HTTP/2 session functionalities.

      */ @@ -151,4 +152,14 @@ public interface ISession extends Session * @param callback the callback to notify when the frame has been processed */ public void onData(DataFrame frame, Callback callback); + + /** + *

      Gracefully closes the session, returning a {@code CompletableFuture} that + * is completed when all the streams currently being processed are completed.

      + *

      Implementation is idempotent, i.e. calling this method a second time + * or concurrently results in a no-operation.

      + * + * @return a {@code CompletableFuture} that is completed when all the streams are completed + */ + public CompletableFuture shutdown(); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java index cca02086afb..893cfdbdd04 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; @@ -25,7 +25,7 @@ import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.util.Callback; /** - *

      The SPI interface for implementing a HTTP/2 stream.

      + *

      The SPI interface for implementing an HTTP/2 stream.

      *

      This class extends {@link Stream} by adding the methods required to * implement the HTTP/2 stream functionalities.

      */ diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/SimpleFlowControlStrategy.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/SimpleFlowControlStrategy.java index 430a79b1fe3..d597d7e5ad3 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/SimpleFlowControlStrategy.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/SimpleFlowControlStrategy.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Session.java index 39888cd8613..5b5aa5c6ade 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Session.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Session.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.api; +import java.net.InetSocketAddress; import java.util.Collection; import java.util.Map; @@ -32,7 +33,7 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; /** - *

      A {@link Session} represents the client-side endpoint of a HTTP/2 connection to a single origin server.

      + *

      A {@link Session} represents the client-side endpoint of an HTTP/2 connection to a single origin server.

      *

      Once a {@link Session} has been obtained, it can be used to open HTTP/2 streams:

      *
        * Session session = ...;
      @@ -125,9 +126,21 @@ public interface Session
            */
           public Stream getStream(int streamId);
       
      +    /**
      +     * @return the local network address this session is bound to,
      +     * or {@code null} if this session is not bound to a network address
      +     */
      +    public InetSocketAddress getLocalAddress();
      +
      +    /**
      +     * @return the remote network address this session is connected to,
      +     * or {@code null} if this session is not connected to a network address
      +     */
      +    public InetSocketAddress getRemoteAddress();
      +
           /**
            * 

      A {@link Listener} is the passive counterpart of a {@link Session} and - * receives events happening on a HTTP/2 connection.

      + * receives events happening on an HTTP/2 connection.

      * * @see Session */ @@ -151,9 +164,9 @@ public interface Session /** *

      Callback method invoked when a new stream is being created upon - * receiving a HEADERS frame representing a HTTP request.

      + * receiving a HEADERS frame representing an HTTP request.

      *

      Applications should implement this method to process HTTP requests, - * typically providing a HTTP response via + * typically providing an HTTP response via * {@link Stream#headers(HeadersFrame, Callback)}.

      *

      Applications can detect whether request DATA frames will be arriving * by testing {@link HeadersFrame#isEndStream()}. If the application is diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java index 6f02b828825..cfba9e089e9 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.api; @@ -29,8 +29,8 @@ import org.eclipse.jetty.util.Promise; *

      A {@link Stream} represents a bidirectional exchange of data on top of a {@link Session}.

      *

      Differently from socket streams, where the input and output streams are permanently associated * with the socket (and hence with the connection that the socket represents), there can be multiple - * HTTP/2 streams present concurrent for a HTTP/2 session.

      - *

      A {@link Stream} maps to a HTTP request/response cycle, and after the request/response cycle is + * HTTP/2 streams present concurrently for an HTTP/2 session.

      + *

      A {@link Stream} maps to an HTTP request/response cycle, and after the request/response cycle is * completed, the stream is closed and removed from the session.

      *

      Like {@link Session}, {@link Stream} is the active part and by calling its API applications * can generate events on the stream; conversely, {@link Stream.Listener} is the passive part, and @@ -51,7 +51,7 @@ public interface Stream public Session getSession(); /** - *

      Sends the given HEADERS {@code frame} representing a HTTP response.

      + *

      Sends the given HEADERS {@code frame} representing an HTTP response.

      * * @param frame the HEADERS frame to send * @param callback the callback that gets notified when the frame has been sent @@ -129,14 +129,40 @@ public interface Stream */ public void setIdleTimeout(long idleTimeout); + /** + *

      Demands {@code n} more {@code DATA} frames for this stream.

      + * + * @param n the increment of the demand, must be greater than zero + * @see Listener#onDataDemanded(Stream, DataFrame, Callback) + */ + public void demand(long n); + /** *

      A {@link Stream.Listener} is the passive counterpart of a {@link Stream} and receives - * events happening on a HTTP/2 stream.

      + * events happening on an HTTP/2 stream.

      + *

      HTTP/2 data is flow controlled - this means that only a finite number of data events + * are delivered, until the flow control window is exhausted.

      + *

      Applications control the delivery of data events by requesting them via + * {@link Stream#demand(long)}; the first event is always delivered, while subsequent + * events must be explicitly demanded.

      + *

      Applications control the HTTP/2 flow control by completing the callback associated + * with data events - this allows the implementation to recycle the data buffer and + * eventually to enlarge the flow control window so that the sender can send more data.

      * * @see Stream */ public interface Listener { + /** + *

      Callback method invoked when a stream is created locally by + * {@link Session#newStream(HeadersFrame, Promise, Listener)}.

      + * + * @param stream the newly created stream + */ + public default void onNewStream(Stream stream) + { + } + /** *

      Callback method invoked when a HEADERS frame representing the HTTP response has been received.

      * @@ -154,15 +180,42 @@ public interface Stream */ public Listener onPush(Stream stream, PushPromiseFrame frame); + /** + *

      Callback method invoked before notifying the first DATA frame.

      + *

      The default implementation initializes the demand for DATA frames.

      + * + * @param stream the stream + */ + public default void onBeforeData(Stream stream) + { + stream.demand(1); + } + /** *

      Callback method invoked when a DATA frame has been received.

      * * @param stream the stream * @param frame the DATA frame received * @param callback the callback to complete when the bytes of the DATA frame have been consumed + * @see #onDataDemanded(Stream, DataFrame, Callback) */ public void onData(Stream stream, DataFrame frame, Callback callback); + /** + *

      Callback method invoked when a DATA frame has been demanded.

      + *

      Implementations of this method must arrange to call (within the + * method or otherwise asynchronously) {@link #demand(long)}.

      + * + * @param stream the stream + * @param frame the DATA frame received + * @param callback the callback to complete when the bytes of the DATA frame have been consumed + */ + public default void onDataDemanded(Stream stream, DataFrame frame, Callback callback) + { + onData(stream, frame, callback); + stream.demand(1); + } + /** *

      Callback method invoked when a RST_STREAM frame has been received for this stream.

      * diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/server/ServerSessionListener.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/server/ServerSessionListener.java index d11e3251d0a..d02174f1a08 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/server/ServerSessionListener.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/server/ServerSessionListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.api.server; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ContinuationFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ContinuationFrame.java new file mode 100644 index 00000000000..fda0ad84a65 --- /dev/null +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ContinuationFrame.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.frames; + +public class ContinuationFrame extends Frame +{ + private final int streamId; + private final boolean endHeaders; + + public ContinuationFrame(int streamId, boolean endHeaders) + { + super(FrameType.CONTINUATION); + this.streamId = streamId; + this.endHeaders = endHeaders; + } + + public int getStreamId() + { + return streamId; + } + + public boolean isEndHeaders() + { + return endHeaders; + } + + @Override + public String toString() + { + return String.format("%s#%d{end=%b}", super.toString(), getStreamId(), isEndHeaders()); + } +} diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java index 5f0c95b62b5..c44b3bc74be 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DisconnectFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DisconnectFrame.java index b2a590f9d5b..8531d4c1735 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DisconnectFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/DisconnectFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FailureFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FailureFrame.java index 17b913c05f4..1f889a50069 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FailureFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FailureFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/Frame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/Frame.java index bca3f38a9bd..26c2e47921c 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/Frame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/Frame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FrameType.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FrameType.java index 3ab19fec249..6af30bf6c5a 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FrameType.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/FrameType.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java index 64b855f2d2e..1b006eef4c3 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java index d3868f7c782..c72b4933628 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PingFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PingFrame.java index 450b0aa5434..91f4b1e0b18 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PingFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PingFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PrefaceFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PrefaceFrame.java index e1aff2b723c..7bb022de790 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PrefaceFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PrefaceFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PriorityFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PriorityFrame.java index b2bd59a491a..a7fad1a5129 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PriorityFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PriorityFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PushPromiseFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PushPromiseFrame.java index b6a0d9faf4a..4d7d9f2e6cd 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PushPromiseFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/PushPromiseFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; @@ -24,9 +24,9 @@ public class PushPromiseFrame extends Frame { private final int streamId; private final int promisedStreamId; - private final MetaData metaData; + private final MetaData.Request metaData; - public PushPromiseFrame(int streamId, int promisedStreamId, MetaData metaData) + public PushPromiseFrame(int streamId, int promisedStreamId, MetaData.Request metaData) { super(FrameType.PUSH_PROMISE); this.streamId = streamId; @@ -44,7 +44,7 @@ public class PushPromiseFrame extends Frame return promisedStreamId; } - public MetaData getMetaData() + public MetaData.Request getMetaData() { return metaData; } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java index 672c030883b..d8d2c6d2fbb 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java index c4f78e1371a..dc5c10c38d0 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; @@ -30,6 +30,7 @@ public class SettingsFrame extends Frame public static final int INITIAL_WINDOW_SIZE = 4; public static final int MAX_FRAME_SIZE = 5; public static final int MAX_HEADER_LIST_SIZE = 6; + public static final int ENABLE_CONNECT_PROTOCOL = 8; private final Map settings; private final boolean reply; @@ -54,6 +55,6 @@ public class SettingsFrame extends Frame @Override public String toString() { - return String.format("%s,reply=%b:%s", super.toString(), reply, settings); + return String.format("%s,reply=%b,params=%s", super.toString(), reply, settings); } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/UnknownFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/UnknownFrame.java new file mode 100644 index 00000000000..a4affaa7127 --- /dev/null +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/UnknownFrame.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.frames; + +public class UnknownFrame extends Frame +{ + private final int frameType; + + public UnknownFrame(int frameType) + { + super(null); + this.frameType = frameType; + } + + @Override + public String toString() + { + return String.format("%s,t=%d", super.toString(), frameType); + } +} diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/WindowUpdateFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/WindowUpdateFrame.java index 0ad323d3afe..da9abf7c026 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/WindowUpdateFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/WindowUpdateFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DataGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DataGenerator.java index 284f41fb517..d5139e73753 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DataGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DataGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DisconnectGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DisconnectGenerator.java index 7085f71d786..db374b78125 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DisconnectGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/DisconnectGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/FrameGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/FrameGenerator.java index 0194beccc27..2b3aa464a73 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/FrameGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/FrameGenerator.java @@ -1,27 +1,30 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; import java.nio.ByteBuffer; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.FrameType; +import org.eclipse.jetty.http2.hpack.HpackEncoder; +import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.io.ByteBufferPool; public abstract class FrameGenerator @@ -33,7 +36,7 @@ public abstract class FrameGenerator this.headerGenerator = headerGenerator; } - public abstract int generate(ByteBufferPool.Lease lease, Frame frame); + public abstract int generate(ByteBufferPool.Lease lease, Frame frame) throws HpackException; protected ByteBuffer generateHeader(ByteBufferPool.Lease lease, FrameType frameType, int length, int flags, int streamId) { @@ -44,4 +47,24 @@ public abstract class FrameGenerator { return headerGenerator.getMaxFrameSize(); } + + public boolean isUseDirectByteBuffers() + { + return headerGenerator.isUseDirectByteBuffers(); + } + + protected ByteBuffer encode(HpackEncoder encoder, ByteBufferPool.Lease lease, MetaData metaData, int maxFrameSize) throws HpackException + { + ByteBuffer hpacked = lease.acquire(maxFrameSize, isUseDirectByteBuffers()); + try + { + encoder.encode(hpacked, metaData); + return hpacked; + } + catch (HpackException x) + { + lease.release(hpacked); + throw x; + } + } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java index b7288d3897a..61daf3056ea 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; @@ -22,6 +22,7 @@ import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.FrameType; import org.eclipse.jetty.http2.hpack.HpackEncoder; +import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.io.ByteBufferPool; public class Generator @@ -38,10 +39,15 @@ public class Generator } public Generator(ByteBufferPool byteBufferPool, int maxDynamicTableSize, int maxHeaderBlockFragment) + { + this(byteBufferPool, true, maxDynamicTableSize, maxHeaderBlockFragment); + } + + public Generator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers, int maxDynamicTableSize, int maxHeaderBlockFragment) { this.byteBufferPool = byteBufferPool; - headerGenerator = new HeaderGenerator(); + headerGenerator = new HeaderGenerator(useDirectByteBuffers); hpackEncoder = new HpackEncoder(maxDynamicTableSize); this.generators = new FrameGenerator[FrameType.values().length]; @@ -65,6 +71,11 @@ public class Generator return byteBufferPool; } + public void setValidateHpackEncoding(boolean validateEncoding) + { + hpackEncoder.setValidateEncoding(validateEncoding); + } + public void setHeaderTableSize(int headerTableSize) { hpackEncoder.setRemoteMaxDynamicTableSize(headerTableSize); @@ -75,7 +86,7 @@ public class Generator headerGenerator.setMaxFrameSize(maxFrameSize); } - public int control(ByteBufferPool.Lease lease, Frame frame) + public int control(ByteBufferPool.Lease lease, Frame frame) throws HpackException { return generators[frame.getType().getType()].generate(lease, frame); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/GoAwayGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/GoAwayGenerator.java index 1e04094fc0b..2775033c268 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/GoAwayGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/GoAwayGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeaderGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeaderGenerator.java index 33283a72389..debd94f64f8 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeaderGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeaderGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; @@ -27,10 +27,26 @@ import org.eclipse.jetty.io.ByteBufferPool; public class HeaderGenerator { private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH; + private final boolean useDirectByteBuffers; + + public HeaderGenerator() + { + this(true); + } + + public HeaderGenerator(boolean useDirectByteBuffers) + { + this.useDirectByteBuffers = useDirectByteBuffers; + } + + public boolean isUseDirectByteBuffers() + { + return useDirectByteBuffers; + } public ByteBuffer generate(ByteBufferPool.Lease lease, FrameType frameType, int capacity, int length, int flags, int streamId) { - ByteBuffer header = lease.acquire(capacity, true); + ByteBuffer header = lease.acquire(capacity, isUseDirectByteBuffers()); header.put((byte)((length & 0x00_FF_00_00) >>> 16)); header.put((byte)((length & 0x00_00_FF_00) >>> 8)); header.put((byte)((length & 0x00_00_00_FF))); diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeadersGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeadersGenerator.java index 4ff03bd28e5..93ac1db9916 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeadersGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeadersGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; @@ -27,6 +27,7 @@ import org.eclipse.jetty.http2.frames.FrameType; import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.PriorityFrame; import org.eclipse.jetty.http2.hpack.HpackEncoder; +import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; @@ -50,13 +51,13 @@ public class HeadersGenerator extends FrameGenerator } @Override - public int generate(ByteBufferPool.Lease lease, Frame frame) + public int generate(ByteBufferPool.Lease lease, Frame frame) throws HpackException { HeadersFrame headersFrame = (HeadersFrame)frame; return generateHeaders(lease, headersFrame.getStreamId(), headersFrame.getMetaData(), headersFrame.getPriority(), headersFrame.isEndStream()); } - public int generateHeaders(ByteBufferPool.Lease lease, int streamId, MetaData metaData, PriorityFrame priority, boolean endStream) + public int generateHeaders(ByteBufferPool.Lease lease, int streamId, MetaData metaData, PriorityFrame priority, boolean endStream) throws HpackException { if (streamId < 0) throw new IllegalArgumentException("Invalid stream id: " + streamId); @@ -66,10 +67,7 @@ public class HeadersGenerator extends FrameGenerator if (priority != null) flags = Flags.PRIORITY; - int maxFrameSize = getMaxFrameSize(); - ByteBuffer hpacked = lease.acquire(maxFrameSize, false); - BufferUtil.clearToFill(hpacked); - encoder.encode(hpacked, metaData); + ByteBuffer hpacked = encode(encoder, lease, metaData, getMaxFrameSize()); int hpackedLength = hpacked.position(); BufferUtil.flipToFlush(hpacked, 0); diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PingGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PingGenerator.java index 99ac42b47a6..a681f107f7b 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PingGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PingGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PrefaceGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PrefaceGenerator.java index 76cf4694bbc..20b721bb365 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PrefaceGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PrefaceGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PriorityGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PriorityGenerator.java index 9b72800d562..95dd1a37ff0 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PriorityGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PriorityGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PushPromiseGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PushPromiseGenerator.java index d4fe2640ef9..c6906ad9ee3 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PushPromiseGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/PushPromiseGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; @@ -26,6 +26,7 @@ import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.FrameType; import org.eclipse.jetty.http2.frames.PushPromiseFrame; import org.eclipse.jetty.http2.hpack.HpackEncoder; +import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; @@ -40,13 +41,13 @@ public class PushPromiseGenerator extends FrameGenerator } @Override - public int generate(ByteBufferPool.Lease lease, Frame frame) + public int generate(ByteBufferPool.Lease lease, Frame frame) throws HpackException { PushPromiseFrame pushPromiseFrame = (PushPromiseFrame)frame; return generatePushPromise(lease, pushPromiseFrame.getStreamId(), pushPromiseFrame.getPromisedStreamId(), pushPromiseFrame.getMetaData()); } - public int generatePushPromise(ByteBufferPool.Lease lease, int streamId, int promisedStreamId, MetaData metaData) + public int generatePushPromise(ByteBufferPool.Lease lease, int streamId, int promisedStreamId, MetaData metaData) throws HpackException { if (streamId < 0) throw new IllegalArgumentException("Invalid stream id: " + streamId); @@ -58,9 +59,7 @@ public class PushPromiseGenerator extends FrameGenerator int extraSpace = 4; maxFrameSize -= extraSpace; - ByteBuffer hpacked = lease.acquire(maxFrameSize, false); - BufferUtil.clearToFill(hpacked); - encoder.encode(hpacked, metaData); + ByteBuffer hpacked = encode(encoder, lease, metaData, maxFrameSize); int hpackedLength = hpacked.position(); BufferUtil.flipToFlush(hpacked, 0); diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/ResetGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/ResetGenerator.java index 2a0533a8f08..e85d6d9174b 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/ResetGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/ResetGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/SettingsGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/SettingsGenerator.java index dcb9831ff14..aae1e95a413 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/SettingsGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/SettingsGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/WindowUpdateGenerator.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/WindowUpdateGenerator.java index cd7a265caf8..8a9bc8f8a47 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/WindowUpdateGenerator.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/generator/WindowUpdateGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.generator; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java index 82d18f96a84..2c06fd20e90 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -32,8 +32,8 @@ import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      The base parser for the frame body of HTTP/2 frames.

      @@ -44,7 +44,7 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class BodyParser { - protected static final Logger LOG = Log.getLogger(BodyParser.class); + protected static final Logger LOG = LoggerFactory.getLogger(BodyParser.class); private final HeaderParser headerParser; private final Parser.Listener listener; @@ -96,6 +96,11 @@ public abstract class BodyParser return headerParser.getLength(); } + protected int getFrameType() + { + return headerParser.getFrameType(); + } + protected void notifyData(DataFrame frame) { try @@ -223,9 +228,10 @@ public abstract class BodyParser } } - protected void streamFailure(int streamId, int error, String reason) + protected boolean streamFailure(int streamId, int error, String reason) { notifyStreamFailure(streamId, error, reason); + return false; } private void notifyStreamFailure(int streamId, int error, String reason) @@ -239,4 +245,9 @@ public abstract class BodyParser LOG.info("Failure while notifying listener " + listener, x); } } + + protected boolean rateControlOnEvent(Object o) + { + return headerParser.getRateControl().onEvent(o); + } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java index 65e47d1c827..f19e7272fe9 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -23,6 +23,7 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.Flags; +import org.eclipse.jetty.http2.frames.ContinuationFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; public class ContinuationBodyParser extends BodyParser @@ -43,7 +44,15 @@ public class ContinuationBodyParser extends BodyParser protected void emptyBody(ByteBuffer buffer) { if (hasFlag(Flags.END_HEADERS)) - onHeaders(); + { + onHeaders(buffer); + } + else + { + ContinuationFrame frame = new ContinuationFrame(getStreamId(), hasFlag(Flags.END_HEADERS)); + if (!rateControlOnEvent(frame)) + connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); + } } @Override @@ -81,7 +90,7 @@ public class ContinuationBodyParser extends BodyParser headerBlockFragments.storeFragment(buffer, length, last); reset(); if (last) - return onHeaders(); + return onHeaders(buffer); return true; } } @@ -94,15 +103,21 @@ public class ContinuationBodyParser extends BodyParser return false; } - private boolean onHeaders() + private boolean onHeaders(ByteBuffer buffer) { ByteBuffer headerBlock = headerBlockFragments.complete(); MetaData metaData = headerBlockParser.parse(headerBlock, headerBlock.remaining()); + headerBlockFragments.getByteBufferPool().release(headerBlock); + if (metaData == null) + return true; if (metaData == HeaderBlockParser.SESSION_FAILURE) return false; - if (metaData == null || metaData == HeaderBlockParser.STREAM_FAILURE) - return true; HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, headerBlockFragments.getPriorityFrame(), headerBlockFragments.isEndStream()); + if (metaData == HeaderBlockParser.STREAM_FAILURE) + { + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_continuation_frame_rate"); + } notifyHeaders(frame); return true; } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/DataBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/DataBodyParser.java index ac9e7bab991..b46a320a284 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/DataBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/DataBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -48,9 +48,17 @@ public class DataBodyParser extends BodyParser protected void emptyBody(ByteBuffer buffer) { if (isPadding()) + { connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_data_frame"); + } else - onData(BufferUtil.EMPTY_BUFFER, false, 0); + { + DataFrame frame = new DataFrame(getStreamId(), BufferUtil.EMPTY_BUFFER, isEndStream()); + if (!isEndStream() && !rateControlOnEvent(frame)) + connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_data_frame_rate"); + else + onData(frame); + } } @Override @@ -134,7 +142,11 @@ public class DataBodyParser extends BodyParser private void onData(ByteBuffer buffer, boolean fragment, int padding) { - DataFrame frame = new DataFrame(getStreamId(), buffer, !fragment && isEndStream(), padding); + onData(new DataFrame(getStreamId(), buffer, !fragment && isEndStream(), padding)); + } + + private void onData(DataFrame frame) + { notifyData(frame); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/GoAwayBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/GoAwayBodyParser.java index b84e229fc11..31d9591adfd 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/GoAwayBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/GoAwayBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java index 71ca1b3814d..7011bd7d9e1 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -21,20 +21,33 @@ package org.eclipse.jetty.http2.parser; import java.nio.ByteBuffer; import org.eclipse.jetty.http2.frames.PriorityFrame; +import org.eclipse.jetty.io.ByteBufferPool; public class HeaderBlockFragments { + private final ByteBufferPool byteBufferPool; private PriorityFrame priorityFrame; private boolean endStream; private int streamId; private ByteBuffer storage; + public HeaderBlockFragments(ByteBufferPool byteBufferPool) + { + this.byteBufferPool = byteBufferPool; + } + + public ByteBufferPool getByteBufferPool() + { + return byteBufferPool; + } + public void storeFragment(ByteBuffer fragment, int length, boolean last) { if (storage == null) { int space = last ? length : length * 2; - storage = ByteBuffer.allocate(space); + storage = byteBufferPool.acquire(space, fragment.isDirect()); + storage.clear(); } // Grow the storage if necessary. @@ -42,9 +55,11 @@ public class HeaderBlockFragments { int space = last ? length : length * 2; int capacity = storage.position() + space; - ByteBuffer newStorage = ByteBuffer.allocate(capacity); + ByteBuffer newStorage = byteBufferPool.acquire(capacity, storage.isDirect()); + newStorage.clear(); storage.flip(); newStorage.put(storage); + byteBufferPool.release(storage); storage = newStorage; } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java index 54e4661da67..11a922a81ce 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -27,14 +27,14 @@ import org.eclipse.jetty.http2.hpack.HpackDecoder; import org.eclipse.jetty.http2.hpack.HpackException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HeaderBlockParser { public static final MetaData STREAM_FAILURE = new MetaData(HttpVersion.HTTP_2, null); public static final MetaData SESSION_FAILURE = new MetaData(HttpVersion.HTTP_2, null); - private static final Logger LOG = Log.getLogger(HeaderBlockParser.class); + private static final Logger LOG = LoggerFactory.getLogger(HeaderBlockParser.class); private final HeaderParser headerParser; private final ByteBufferPool byteBufferPool; @@ -73,7 +73,7 @@ public class HeaderBlockParser { if (blockBuffer == null) { - blockBuffer = byteBufferPool.acquire(blockLength, false); + blockBuffer = byteBufferPool.acquire(blockLength, buffer.isDirect()); BufferUtil.clearToFill(blockBuffer); } blockBuffer.put(buffer); @@ -102,21 +102,21 @@ public class HeaderBlockParser catch (HpackException.StreamException x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Stream error, stream={}", headerParser.getStreamId(), x); notifier.streamFailure(headerParser.getStreamId(), ErrorCode.PROTOCOL_ERROR.code, "invalid_hpack_block"); return STREAM_FAILURE; } catch (HpackException.CompressionException x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Compression error, buffer={}", BufferUtil.toDetailString(buffer), x); notifier.connectionFailure(buffer, ErrorCode.COMPRESSION_ERROR.code, "invalid_hpack_block"); return SESSION_FAILURE; } catch (HpackException.SessionException x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Session error, buffer={}", BufferUtil.toDetailString(buffer), x); notifier.connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_hpack_block"); return SESSION_FAILURE; } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java index 0e4d2dc5e9e..e24802f29f0 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -30,14 +30,24 @@ import org.eclipse.jetty.http2.frames.FrameType; */ public class HeaderParser { + private final RateControl rateControl; private State state = State.LENGTH; private int cursor; - private int length; private int type; private int flags; private int streamId; + public HeaderParser(RateControl rateControl) + { + this.rateControl = rateControl; + } + + public RateControl getRateControl() + { + return rateControl; + } + protected void reset() { state = State.LENGTH; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java index febdefb6c25..3d15959c28c 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -61,17 +61,23 @@ public class HeadersBodyParser extends BodyParser @Override protected void emptyBody(ByteBuffer buffer) { - if (hasFlag(Flags.END_HEADERS)) + if (hasFlag(Flags.PRIORITY)) + { + connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_priority_frame"); + } + else if (hasFlag(Flags.END_HEADERS)) { MetaData metaData = headerBlockParser.parse(BufferUtil.EMPTY_BUFFER, 0); - onHeaders(0, 0, false, metaData); + HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, null, isEndStream()); + if (!rateControlOnEvent(frame)) + connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); + else + onHeaders(frame); } else { headerBlockFragments.setStreamId(getStreamId()); headerBlockFragments.setEndStream(isEndStream()); - if (hasFlag(Flags.PRIORITY)) - connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_priority_frame"); } } @@ -179,7 +185,15 @@ public class HeadersBodyParser extends BodyParser state = State.PADDING; loop = paddingLength == 0; if (metaData != HeaderBlockParser.STREAM_FAILURE) + { onHeaders(parentStreamId, weight, exclusive, metaData); + } + else + { + HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, null, isEndStream()); + if (!rateControlOnEvent(frame)) + connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_headers_frame_rate"); + } } } else @@ -230,6 +244,11 @@ public class HeadersBodyParser extends BodyParser if (hasFlag(Flags.PRIORITY)) priorityFrame = new PriorityFrame(getStreamId(), parentStreamId, weight, exclusive); HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, priorityFrame, isEndStream()); + onHeaders(frame); + } + + private void onHeaders(HeadersFrame frame) + { notifyHeaders(frame); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java index 6ac14471695..5997c00d199 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -36,8 +36,8 @@ import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.frames.WindowUpdateFrame; import org.eclipse.jetty.http2.hpack.HpackDecoder; import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      The HTTP/2 protocol parser.

      @@ -46,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class Parser { - private static final Logger LOG = Log.getLogger(Parser.class); + private static final Logger LOG = LoggerFactory.getLogger(Parser.class); private final ByteBufferPool byteBufferPool; private final Listener listener; @@ -54,18 +54,22 @@ public class Parser private final HpackDecoder hpackDecoder; private final BodyParser[] bodyParsers; private UnknownBodyParser unknownBodyParser; - private int maxFrameLength; + private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; private boolean continuation; private State state = State.HEADER; public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize) + { + this(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, RateControl.NO_RATE_CONTROL); + } + + public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl) { this.byteBufferPool = byteBufferPool; this.listener = listener; - this.headerParser = new HeaderParser(); + this.headerParser = new HeaderParser(rateControl == null ? RateControl.NO_RATE_CONTROL : rateControl); this.hpackDecoder = new HpackDecoder(maxDynamicTableSize, maxHeaderSize); - this.maxFrameLength = Frame.DEFAULT_MAX_LENGTH; this.bodyParsers = new BodyParser[FrameType.values().length]; } @@ -74,7 +78,7 @@ public class Parser Listener listener = wrapper.apply(this.listener); unknownBodyParser = new UnknownBodyParser(headerParser, listener); HeaderBlockParser headerBlockParser = new HeaderBlockParser(headerParser, byteBufferPool, hpackDecoder, unknownBodyParser); - HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(); + HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(byteBufferPool); bodyParsers[FrameType.DATA.getType()] = new DataBodyParser(headerParser, listener); bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments); bodyParsers[FrameType.PRIORITY.getType()] = new PriorityBodyParser(headerParser, listener); @@ -134,7 +138,7 @@ public class Parser catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Parse failed", x); connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR, "parser_error"); } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PingBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PingBodyParser.java index 8cee350e91e..ff6014f4426 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PingBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PingBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -66,7 +66,7 @@ public class PingBodyParser extends BodyParser if (buffer.remaining() >= 8) { buffer.get(payload); - return onPing(payload); + return onPing(buffer, payload); } else { @@ -80,7 +80,7 @@ public class PingBodyParser extends BodyParser payload[8 - cursor] = buffer.get(); --cursor; if (cursor == 0) - return onPing(payload); + return onPing(buffer, payload); break; } default: @@ -92,9 +92,11 @@ public class PingBodyParser extends BodyParser return false; } - private boolean onPing(byte[] payload) + private boolean onPing(ByteBuffer buffer, byte[] payload) { PingFrame frame = new PingFrame(payload, hasFlag(Flags.ACK)); + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_ping_frame_rate"); reset(); notifyPing(frame); return true; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PrefaceParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PrefaceParser.java index 3a6058878a4..0dc6a052d3d 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PrefaceParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PrefaceParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -23,12 +23,12 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.frames.PrefaceFrame; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PrefaceParser { - private static final Logger LOG = Log.getLogger(PrefaceParser.class); + private static final Logger LOG = LoggerFactory.getLogger(PrefaceParser.class); private final Parser.Listener listener; private int cursor; @@ -42,7 +42,7 @@ public class PrefaceParser *

      Advances this parser after the {@link PrefaceFrame#PREFACE_PREAMBLE_BYTES}.

      *

      This allows the HTTP/1.1 parser to parse the preamble of the preface, * which is a legal HTTP/1.1 request, and this parser will parse the remaining - * bytes, that are not parseable by a HTTP/1.1 parser.

      + * bytes, that are not parseable by an HTTP/1.1 parser.

      */ protected void directUpgrade() { diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PriorityBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PriorityBodyParser.java index a9d11398987..d9e4fdcef69 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PriorityBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PriorityBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -103,7 +103,7 @@ public class PriorityBodyParser extends BodyParser if (getStreamId() == parentStreamId) return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_priority_frame"); int weight = (buffer.get() & 0xFF) + 1; - return onPriority(parentStreamId, weight, exclusive); + return onPriority(buffer, parentStreamId, weight, exclusive); } default: { @@ -114,9 +114,11 @@ public class PriorityBodyParser extends BodyParser return false; } - private boolean onPriority(int parentStreamId, int weight, boolean exclusive) + private boolean onPriority(ByteBuffer buffer, int parentStreamId, int weight, boolean exclusive) { PriorityFrame frame = new PriorityFrame(getStreamId(), parentStreamId, weight, exclusive); + if (!rateControlOnEvent(frame)) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_priority_frame_rate"); reset(); notifyPriority(frame); return true; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java index 9e4341acb00..2b712431424 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -124,7 +124,7 @@ public class PushPromiseBodyParser extends BodyParser } case HEADERS: { - MetaData metaData = headerBlockParser.parse(buffer, length); + MetaData.Request metaData = (MetaData.Request)headerBlockParser.parse(buffer, length); if (metaData == HeaderBlockParser.SESSION_FAILURE) return false; if (metaData != null) @@ -157,7 +157,7 @@ public class PushPromiseBodyParser extends BodyParser return false; } - private void onPushPromise(int streamId, MetaData metaData) + private void onPushPromise(int streamId, MetaData.Request metaData) { PushPromiseFrame frame = new PushPromiseFrame(getStreamId(), streamId, metaData); notifyPushPromise(frame); diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/RateControl.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/RateControl.java new file mode 100644 index 00000000000..2d716e07a49 --- /dev/null +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/RateControl.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.parser; + +import org.eclipse.jetty.io.EndPoint; + +/** + * Controls rate of events via {@link #onEvent(Object)}. + */ +public interface RateControl +{ + public static final RateControl NO_RATE_CONTROL = event -> true; + + /** + *

      Applications should call this method when they want to signal an + * event that is subject to rate control.

      + *

      Implementations should return true if the event does not exceed + * the desired rate, or false to signal that the event exceeded the + * desired rate.

      + * + * @param event the event subject to rate control. + * @return true IFF the rate is within limits + */ + public boolean onEvent(Object event); + + /** + * Factory to create RateControl instances. + */ + public interface Factory + { + /** + * @return a new RateControl instance for the given EndPoint + * @param endPoint the EndPoint for which the RateControl is created + */ + public default RateControl newRateControl(EndPoint endPoint) + { + return NO_RATE_CONTROL; + } + } +} diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java index 45d99104d18..062aecb79c9 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java index 1b17ddfa73c..21aaf5aa6cd 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -25,21 +25,21 @@ import org.eclipse.jetty.http2.Flags; import org.eclipse.jetty.http2.frames.FrameType; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ServerParser extends Parser { - private static final Logger LOG = Log.getLogger(ServerParser.class); + private static final Logger LOG = LoggerFactory.getLogger(ServerParser.class); private final Listener listener; private final PrefaceParser prefaceParser; private State state = State.PREFACE; private boolean notifyPreface = true; - public ServerParser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize) + public ServerParser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl) { - super(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize); + super(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, rateControl); this.listener = listener; this.prefaceParser = new PrefaceParser(listener); } @@ -124,7 +124,7 @@ public class ServerParser extends Parser } catch (Throwable x) { - LOG.debug(x); + LOG.debug("Parse error", x); BufferUtil.clear(buffer); notifyConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "parser_error"); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java index 741dd95981d..1854ab3371d 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; import java.nio.ByteBuffer; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -27,12 +28,12 @@ import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.Flags; import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.SettingsFrame; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SettingsBodyParser extends BodyParser { - private static final Logger LOG = Log.getLogger(SettingsBodyParser.class); + private static final Logger LOG = LoggerFactory.getLogger(SettingsBodyParser.class); private final int maxKeys; private State state = State.PREPARE; @@ -72,11 +73,21 @@ public class SettingsBodyParser extends BodyParser @Override protected void emptyBody(ByteBuffer buffer) { - onSettings(buffer, new HashMap<>()); + boolean isReply = hasFlag(Flags.ACK); + SettingsFrame frame = new SettingsFrame(Collections.emptyMap(), isReply); + if (!isReply && !rateControlOnEvent(frame)) + connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_settings_frame_rate"); + else + onSettings(frame); } @Override public boolean parse(ByteBuffer buffer) + { + return parse(buffer, getStreamId(), getBodyLength()); + } + + private boolean parse(ByteBuffer buffer, int streamId, int bodyLength) { while (buffer.hasRemaining()) { @@ -85,9 +96,9 @@ public class SettingsBodyParser extends BodyParser case PREPARE: { // SPEC: wrong streamId is treated as connection error. - if (getStreamId() != 0) + if (streamId != 0) return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_frame"); - length = getBodyLength(); + length = bodyLength; settings = new HashMap<>(); state = State.SETTING_ID; break; @@ -200,47 +211,44 @@ public class SettingsBodyParser extends BodyParser return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_settings_max_frame_size"); SettingsFrame frame = new SettingsFrame(settings, hasFlag(Flags.ACK)); + return onSettings(frame); + } + + private boolean onSettings(SettingsFrame frame) + { reset(); notifySettings(frame); return true; } + /** + *

      Parses the given buffer containing the whole body of a {@code SETTINGS} frame + * (without header bytes), typically from the {@code HTTP2-Settings} header.

      + * + * @param buffer the buffer containing the body of {@code SETTINGS} frame + * @return the {@code SETTINGS} frame from the parsed body bytes + */ public static SettingsFrame parseBody(final ByteBuffer buffer) { - final int bodyLength = buffer.remaining(); - final AtomicReference frameRef = new AtomicReference<>(); - SettingsBodyParser parser = new SettingsBodyParser(null, null) + AtomicReference frameRef = new AtomicReference<>(); + SettingsBodyParser parser = new SettingsBodyParser(new HeaderParser(RateControl.NO_RATE_CONTROL), new Parser.Listener.Adapter() { @Override - protected int getStreamId() + public void onSettings(SettingsFrame frame) { - return 0; + frameRef.set(frame); } @Override - protected int getBodyLength() - { - return bodyLength; - } - - @Override - protected boolean onSettings(ByteBuffer buffer, Map settings) - { - frameRef.set(new SettingsFrame(settings, false)); - return true; - } - - @Override - protected boolean connectionFailure(ByteBuffer buffer, int error, String reason) + public void onConnectionFailure(int error, String reason) { frameRef.set(null); - return false; } - }; - if (bodyLength == 0) - parser.emptyBody(buffer); + }); + if (buffer.hasRemaining()) + parser.parse(buffer, 0, buffer.remaining()); else - parser.parse(buffer); + parser.emptyBody(buffer); return frameRef.get(); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java index dbb29bfede2..61f226d7ee5 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java @@ -1,25 +1,28 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; import java.nio.ByteBuffer; +import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.frames.UnknownFrame; + public class UnknownBodyParser extends BodyParser { private int cursor; @@ -34,7 +37,11 @@ public class UnknownBodyParser extends BodyParser { int length = cursor == 0 ? getBodyLength() : cursor; cursor = consume(buffer, length); - return cursor == 0; + boolean parsed = cursor == 0; + if (parsed && !rateControlOnEvent(new UnknownFrame(getFrameType()))) + return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_unknown_frame_rate"); + + return parsed; } private int consume(ByteBuffer buffer, int length) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowRateControl.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowRateControl.java new file mode 100644 index 00000000000..da8e2e46ea6 --- /dev/null +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowRateControl.java @@ -0,0 +1,103 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.parser; + +import java.time.Duration; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jetty.io.EndPoint; + +/** + *

      An implementation of {@link RateControl} that limits the number of + * events within a time period.

      + *

      Events are kept in a queue and for each event the queue is first + * drained of the old events outside the time window, and then the new + * event is added to the queue. The size of the queue is maintained + * separately in an AtomicInteger and if it exceeds the max + * number of events then {@link #onEvent(Object)} returns {@code false}.

      + */ +public class WindowRateControl implements RateControl +{ + private final Queue events = new ConcurrentLinkedQueue<>(); + private final AtomicInteger size = new AtomicInteger(); + private final int maxEvents; + private final long window; + + public static WindowRateControl fromEventsPerSecond(int maxEvents) + { + return new WindowRateControl(maxEvents, Duration.ofSeconds(1)); + } + + public WindowRateControl(int maxEvents, Duration window) + { + this.maxEvents = maxEvents; + this.window = window.toNanos(); + if (this.window == 0) + throw new IllegalArgumentException("Invalid duration " + window); + } + + public int getEventsPerSecond() + { + try + { + long rate = maxEvents * 1_000_000_000L / window; + return Math.toIntExact(rate); + } + catch (ArithmeticException x) + { + return Integer.MAX_VALUE; + } + } + + @Override + public boolean onEvent(Object event) + { + long now = System.nanoTime(); + while (true) + { + Long time = events.peek(); + if (time == null) + break; + if (now < time) + break; + if (events.remove(time)) + size.decrementAndGet(); + } + events.add(now + window); + return size.incrementAndGet() <= maxEvents; + } + + public static class Factory implements RateControl.Factory + { + private final int maxEventRate; + + public Factory(int maxEventRate) + { + this.maxEventRate = maxEventRate; + } + + @Override + public RateControl newRateControl(EndPoint endPoint) + { + return WindowRateControl.fromEventsPerSecond(maxEventRate); + } + } +} diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java index 78505540939..adb00e82f6c 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.parser; @@ -61,7 +61,7 @@ public class WindowUpdateBodyParser extends BodyParser if (buffer.remaining() >= 4) { windowDelta = buffer.getInt() & 0x7F_FF_FF_FF; - return onWindowUpdate(windowDelta); + return onWindowUpdate(buffer, windowDelta); } else { @@ -78,7 +78,7 @@ public class WindowUpdateBodyParser extends BodyParser if (cursor == 0) { windowDelta &= 0x7F_FF_FF_FF; - return onWindowUpdate(windowDelta); + return onWindowUpdate(buffer, windowDelta); } break; } @@ -91,9 +91,17 @@ public class WindowUpdateBodyParser extends BodyParser return false; } - private boolean onWindowUpdate(int windowDelta) + private boolean onWindowUpdate(ByteBuffer buffer, int windowDelta) { - WindowUpdateFrame frame = new WindowUpdateFrame(getStreamId(), windowDelta); + int streamId = getStreamId(); + if (windowDelta == 0) + { + if (streamId == 0) + return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_window_update_frame"); + else + return streamFailure(streamId, ErrorCode.PROTOCOL_ERROR.code, "invalid_window_update_frame"); + } + WindowUpdateFrame frame = new WindowUpdateFrame(streamId, windowDelta); reset(); notifyWindowUpdate(frame); return true; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java index 4db00c3db4b..3a6d00aa356 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java index 3b018233a83..195744f8c74 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java new file mode 100644 index 00000000000..36f33ae1217 --- /dev/null +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java @@ -0,0 +1,161 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.frames; + +import java.nio.ByteBuffer; +import java.time.Duration; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.UnaryOperator; + +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.Flags; +import org.eclipse.jetty.http2.hpack.HpackEncoder; +import org.eclipse.jetty.http2.parser.Parser; +import org.eclipse.jetty.http2.parser.WindowRateControl; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.lessThan; + +public class FrameFloodTest +{ + private final ByteBufferPool byteBufferPool = new MappedByteBufferPool(); + + // Frame structure: + // | Len0 | Len1 | Len2 | Type | Flags | StreamID0 |StreamID1 |StreamID2 |StreamID3 | Payload... | + + private byte[] frameFrom(int length, int frameType, int flags, int streamId, byte[] payload) + { + byte[] result = new byte[3 + 1 + 1 + 4 + payload.length]; + result[0] = (byte)((length >>> 16) & 0xFF); + result[1] = (byte)((length >>> 8) & 0xFF); + result[2] = (byte)(length & 0xFF); + result[3] = (byte)frameType; + result[4] = (byte)flags; + result[5] = (byte)((streamId >>> 24) & 0xFF); + result[6] = (byte)((streamId >>> 16) & 0xFF); + result[7] = (byte)((streamId >>> 8) & 0xFF); + result[8] = (byte)(streamId & 0xFF); + System.arraycopy(payload, 0, result, 9, payload.length); + return result; + } + + @Test + public void testDataFrameFlood() + { + byte[] payload = new byte[0]; + testFrameFlood(null, frameFrom(payload.length, FrameType.DATA.getType(), 0, 13, payload)); + } + + @Test + public void testHeadersFrameFlood() + { + byte[] payload = new byte[0]; + testFrameFlood(null, frameFrom(payload.length, FrameType.HEADERS.getType(), Flags.END_HEADERS, 13, payload)); + } + + @Test + public void testInvalidHeadersFrameFlood() throws Exception + { + // Invalid MetaData (no method, no scheme, etc). + MetaData.Request metadata = new MetaData.Request(null, (String)null, null, null, HttpVersion.HTTP_2, null, -1); + HpackEncoder encoder = new HpackEncoder(); + ByteBuffer buffer = ByteBuffer.allocate(1024); + encoder.encode(buffer, metadata); + buffer.flip(); + byte[] payload = new byte[buffer.remaining()]; + buffer.get(payload); + testFrameFlood(null, frameFrom(payload.length, FrameType.HEADERS.getType(), Flags.END_HEADERS, 13, payload)); + } + + @Test + public void testPriorityFrameFlood() + { + byte[] payload = new byte[]{0, 0, 0, 7, 0}; + testFrameFlood(null, frameFrom(payload.length, FrameType.PRIORITY.getType(), 0, 13, payload)); + } + + @Test + public void testSettingsFrameFlood() + { + byte[] payload = new byte[0]; + testFrameFlood(null, frameFrom(payload.length, FrameType.SETTINGS.getType(), 0, 0, payload)); + } + + @Test + public void testPingFrameFlood() + { + byte[] payload = {0, 0, 0, 0, 0, 0, 0, 0}; + testFrameFlood(null, frameFrom(payload.length, FrameType.PING.getType(), 0, 0, payload)); + } + + @Test + public void testContinuationFrameFlood() + { + int streamId = 13; + byte[] headersPayload = new byte[0]; + byte[] headersBytes = frameFrom(headersPayload.length, FrameType.HEADERS.getType(), 0, streamId, headersPayload); + byte[] continuationPayload = new byte[0]; + testFrameFlood(headersBytes, frameFrom(continuationPayload.length, FrameType.CONTINUATION.getType(), 0, streamId, continuationPayload)); + } + + @Test + public void testUnknownFrameFlood() + { + byte[] payload = {0, 0, 0, 0}; + testFrameFlood(null, frameFrom(payload.length, 64, 0, 0, payload)); + } + + private void testFrameFlood(byte[] preamble, byte[] bytes) + { + AtomicBoolean failed = new AtomicBoolean(); + Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() + { + @Override + public void onConnectionFailure(int error, String reason) + { + failed.set(true); + } + }, 4096, 8192, new WindowRateControl(8, Duration.ofSeconds(1))); + parser.init(UnaryOperator.identity()); + + if (preamble != null) + { + ByteBuffer buffer = ByteBuffer.wrap(preamble); + while (buffer.hasRemaining()) + { + parser.parse(buffer); + } + } + + int count = 0; + while (!failed.get()) + { + ByteBuffer buffer = ByteBuffer.wrap(bytes); + while (buffer.hasRemaining()) + { + parser.parse(buffer); + } + assertThat("too many frames allowed", ++count, lessThan(1024)); + } + } +} diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java index 0cc7e37c870..d4036427586 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java index b67fe45d589..fbf03eb9180 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java index 43a97f0da81..d15de77a83f 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java index 0b7c31f9674..4d1200523c5 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java index ecbdd10caf8..25ce0a0b499 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java index 3d6d8db2938..886d6e3a4fd 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java index 4a2f9a35d8e..2fb731da3e0 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java index 9fcdb743dc6..ca4f81f9791 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java index 9f81bfed88d..a9e4a5583ef 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java index 04825a5e7a6..693cbb22905 100644 --- a/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java +++ b/jetty-http2/http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.frames; diff --git a/jetty-http2/http2-common/src/test/resources/jetty-logging.properties b/jetty-http2/http2-common/src/test/resources/jetty-logging.properties index b4e43807801..874ebdbc1eb 100644 --- a/jetty-http2/http2-common/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-common/src/test/resources/jetty-logging.properties @@ -1,2 +1,2 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl org.eclipse.jetty.http2.LEVEL=INFO diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 6f154432a16..0c49d1bb8fc 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -48,6 +48,10 @@ jetty-io ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty.tests @@ -55,6 +59,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-http2/http2-hpack/src/main/java/module-info.java b/jetty-http2/http2-hpack/src/main/java/module-info.java index 93025628c09..53ae65a0873 100644 --- a/jetty-http2/http2-hpack/src/main/java/module-info.java +++ b/jetty-http2/http2-hpack/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.http.HttpFieldPreEncoder; @@ -23,8 +23,8 @@ module org.eclipse.jetty.http2.hpack { exports org.eclipse.jetty.http2.hpack; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.http; + requires org.slf4j; provides HttpFieldPreEncoder with HpackFieldPreEncoder; } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/AuthorityHttpField.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/AuthorityHttpField.java index 712b4853694..574c84ad0f8 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/AuthorityHttpField.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/AuthorityHttpField.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java index 675d8269e94..546066dd610 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -32,8 +32,8 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.util.ArrayTernaryTrie; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * HPACK - Header Compression for HTTP/2 @@ -45,7 +45,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HpackContext { - public static final Logger LOG = Log.getLogger(HpackContext.class); + public static final Logger LOG = LoggerFactory.getLogger(HpackContext.class); private static final String EMPTY = ""; public static final String[][] STATIC_TABLE = { @@ -261,7 +261,7 @@ public class HpackContext _dynamicTableSizeInBytes += size; _dynamicTable.add(entry); _fieldMap.put(field, entry); - _nameMap.put(StringUtil.asciiToLowerCase(field.getName()), entry); + _nameMap.put(field.getLowerCaseName(), entry); if (LOG.isDebugEnabled()) LOG.debug(String.format("HdrTbl[%x] added %s", hashCode(), entry)); @@ -383,7 +383,7 @@ public class HpackContext _dynamicTableSizeInBytes -= entry.getSize(); entry._slot = -1; _fieldMap.remove(entry.getHttpField()); - String lc = StringUtil.asciiToLowerCase(entry.getHttpField().getName()); + String lc = entry.getHttpField().getLowerCaseName(); if (entry == _nameMap.get(lc)) _nameMap.remove(lc); } @@ -461,6 +461,8 @@ public class HpackContext if (value != null && value.length() > 0) { int huffmanLen = Huffman.octetsNeeded(value); + if (huffmanLen < 0) + throw new IllegalStateException("bad value"); int lenLen = NBitInteger.octectsNeeded(7, huffmanLen); _huffmanValue = new byte[1 + lenLen + huffmanLen]; ByteBuffer buffer = ByteBuffer.wrap(_huffmanValue); diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java index 34c47201932..ab07b75b27c 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -22,11 +22,12 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpTokens; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.hpack.HpackContext.Entry; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.BufferUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Hpack Decoder @@ -34,7 +35,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HpackDecoder { - public static final Logger LOG = Log.getLogger(HpackDecoder.class); + public static final Logger LOG = LoggerFactory.getLogger(HpackDecoder.class); public static final HttpField.LongValueHttpField CONTENT_LENGTH_0 = new HttpField.LongValueHttpField(HttpHeader.CONTENT_LENGTH, 0L); @@ -76,13 +77,8 @@ public class HpackDecoder while (buffer.hasRemaining()) { - if (LOG.isDebugEnabled() && buffer.hasArray()) - { - int l = Math.min(buffer.remaining(), 32); - LOG.debug("decode {}{}", - TypeUtil.toHexString(buffer.array(), buffer.arrayOffset() + buffer.position(), l), - l < buffer.remaining() ? "..." : ""); - } + if (LOG.isDebugEnabled()) + LOG.debug("decode {}", BufferUtil.toHexString(buffer)); byte b = buffer.get(); if (b < 0) @@ -175,14 +171,35 @@ public class HpackDecoder name = Huffman.decode(buffer, length); else name = toASCIIString(buffer, length); - for (int i = 0; i < name.length(); i++) + check: + for (int i = name.length(); i-- > 0; ) { char c = name.charAt(i); - if (c >= 'A' && c <= 'Z') + if (c > 0xff) { - _builder.streamException("Uppercase header name %s", name); + _builder.streamException("Illegal header name %s", name); break; } + HttpTokens.Token token = HttpTokens.TOKENS[0xFF & c]; + switch (token.getType()) + { + case ALPHA: + if (c >= 'A' && c <= 'Z') + { + _builder.streamException("Uppercase header name %s", name); + break check; + } + break; + + case COLON: + case TCHAR: + case DIGIT: + break; + + default: + _builder.streamException("Illegal header name %s", name); + break check; + } } header = HttpHeader.CACHE.get(name); } @@ -258,14 +275,9 @@ public class HpackDecoder public static String toASCIIString(ByteBuffer buffer, int length) { StringBuilder builder = new StringBuilder(length); - int position = buffer.position(); - int start = buffer.arrayOffset() + position; - int end = start + length; - buffer.position(position + length); - byte[] array = buffer.array(); - for (int i = start; i < end; i++) + for (int i = 0; i < length; ++i) { - builder.append((char)(0x7f & array[i])); + builder.append((char)(0x7F & buffer.get())); } return builder.toString(); } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java index eaa17a53ee4..d3b6a70e96b 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java @@ -1,31 +1,34 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.EnumMap; import java.util.EnumSet; +import java.util.HashSet; import java.util.Set; -import java.util.stream.Collectors; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; @@ -33,24 +36,22 @@ import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.PreEncodedHttpField; import org.eclipse.jetty.http2.hpack.HpackContext.Entry; import org.eclipse.jetty.http2.hpack.HpackContext.StaticEntry; -import org.eclipse.jetty.util.ArrayTrie; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.Trie; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HpackEncoder { - public static final Logger LOG = Log.getLogger(HpackEncoder.class); - private static final HttpField[] __status = new HttpField[599]; - static final EnumSet __DO_NOT_HUFFMAN = + private static final Logger LOG = LoggerFactory.getLogger(HpackEncoder.class); + private static final HttpField[] STATUSES = new HttpField[599]; + static final EnumSet DO_NOT_HUFFMAN = EnumSet.of( HttpHeader.AUTHORIZATION, HttpHeader.CONTENT_MD5, HttpHeader.PROXY_AUTHENTICATE, HttpHeader.PROXY_AUTHORIZATION); - static final EnumSet __DO_NOT_INDEX = + static final EnumSet DO_NOT_INDEX = EnumSet.of( // HttpHeader.C_PATH, // TODO more data needed // HttpHeader.DATE, // TODO more data needed @@ -70,23 +71,28 @@ public class HpackEncoder HttpHeader.LAST_MODIFIED, HttpHeader.SET_COOKIE, HttpHeader.SET_COOKIE2); - static final EnumSet __NEVER_INDEX = + static final EnumSet NEVER_INDEX = EnumSet.of( HttpHeader.AUTHORIZATION, HttpHeader.SET_COOKIE, HttpHeader.SET_COOKIE2); - private static final PreEncodedHttpField CONNECTION_TE = new PreEncodedHttpField(HttpHeader.CONNECTION, "te"); + private static final EnumSet IGNORED_HEADERS = EnumSet.of(HttpHeader.CONNECTION, HttpHeader.KEEP_ALIVE, + HttpHeader.PROXY_CONNECTION, HttpHeader.TRANSFER_ENCODING, HttpHeader.UPGRADE); private static final PreEncodedHttpField TE_TRAILERS = new PreEncodedHttpField(HttpHeader.TE, "trailers"); - private static final Trie specialHopHeaders = new ArrayTrie<>(6); + private static final PreEncodedHttpField C_SCHEME_HTTP = new PreEncodedHttpField(HttpHeader.C_SCHEME, "http"); + private static final PreEncodedHttpField C_SCHEME_HTTPS = new PreEncodedHttpField(HttpHeader.C_SCHEME, "https"); + private static final EnumMap C_METHODS = new EnumMap<>(HttpMethod.class); static { for (HttpStatus.Code code : HttpStatus.Code.values()) { - __status[code.getCode()] = new PreEncodedHttpField(HttpHeader.C_STATUS, Integer.toString(code.getCode())); + STATUSES[code.getCode()] = new PreEncodedHttpField(HttpHeader.C_STATUS, Integer.toString(code.getCode())); + } + for (HttpMethod method : HttpMethod.values()) + { + C_METHODS.put(method, new PreEncodedHttpField(HttpHeader.C_METHOD, method.asString())); } - specialHopHeaders.put("close", true); - specialHopHeaders.put("te", true); } private final HpackContext _context; @@ -95,6 +101,7 @@ public class HpackEncoder private int _localMaxDynamicTableSize; private int _maxHeaderListSize; private int _headerListSize; + private boolean _validateEncoding = true; public HpackEncoder() { @@ -145,76 +152,134 @@ public class HpackEncoder _localMaxDynamicTableSize = localMaxDynamicTableSize; } - public void encode(ByteBuffer buffer, MetaData metadata) + public boolean isValidateEncoding() { - if (LOG.isDebugEnabled()) - LOG.debug(String.format("CtxTbl[%x] encoding", _context.hashCode())); + return _validateEncoding; + } - _headerListSize = 0; - int pos = buffer.position(); + public void setValidateEncoding(boolean validateEncoding) + { + _validateEncoding = validateEncoding; + } - // Check the dynamic table sizes! - int maxDynamicTableSize = Math.min(_remoteMaxDynamicTableSize, _localMaxDynamicTableSize); - if (maxDynamicTableSize != _context.getMaxDynamicTableSize()) - encodeMaxDynamicTableSize(buffer, maxDynamicTableSize); - - // Add Request/response meta fields - if (metadata.isRequest()) + public void encode(ByteBuffer buffer, MetaData metadata) throws HpackException + { + try { - MetaData.Request request = (MetaData.Request)metadata; - - // TODO optimise these to avoid HttpField creation - String scheme = request.getURI().getScheme(); - encode(buffer, new HttpField(HttpHeader.C_SCHEME, scheme == null ? HttpScheme.HTTP.asString() : scheme)); - encode(buffer, new HttpField(HttpHeader.C_METHOD, request.getMethod())); - encode(buffer, new HttpField(HttpHeader.C_AUTHORITY, request.getURI().getAuthority())); - encode(buffer, new HttpField(HttpHeader.C_PATH, request.getURI().getPathQuery())); - } - else if (metadata.isResponse()) - { - MetaData.Response response = (MetaData.Response)metadata; - int code = response.getStatus(); - HttpField status = code < __status.length ? __status[code] : null; - if (status == null) - status = new HttpField.IntValueHttpField(HttpHeader.C_STATUS, code); - encode(buffer, status); - } - - // Add all non-connection fields. - HttpFields fields = metadata.getFields(); - if (fields != null) - { - Set hopHeaders = fields.getCSV(HttpHeader.CONNECTION, false).stream() - .filter(v -> specialHopHeaders.get(v) == Boolean.TRUE) - .map(StringUtil::asciiToLowerCase) - .collect(Collectors.toSet()); - for (HttpField field : fields) - { - if (field.getHeader() == HttpHeader.CONNECTION) - continue; - if (!hopHeaders.isEmpty() && hopHeaders.contains(StringUtil.asciiToLowerCase(field.getName()))) - continue; - if (field.getHeader() == HttpHeader.TE) - { - if (!field.contains("trailers")) - continue; - encode(buffer, CONNECTION_TE); - encode(buffer, TE_TRAILERS); - } - encode(buffer, field); - } - } - - // Check size - if (_maxHeaderListSize > 0 && _headerListSize > _maxHeaderListSize) - { - LOG.warn("Header list size too large {} > {} for {}", _headerListSize, _maxHeaderListSize); if (LOG.isDebugEnabled()) - LOG.debug("metadata={}", metadata); - } + LOG.debug(String.format("CtxTbl[%x] encoding", _context.hashCode())); - if (LOG.isDebugEnabled()) - LOG.debug(String.format("CtxTbl[%x] encoded %d octets", _context.hashCode(), buffer.position() - pos)); + HttpFields fields = metadata.getFields(); + // Verify that we can encode without errors. + if (isValidateEncoding() && fields != null) + { + for (HttpField field : fields) + { + String name = field.getName(); + char firstChar = name.charAt(0); + if (firstChar <= ' ' || firstChar == ':') + throw new HpackException.StreamException("Invalid header name: '%s'", name); + } + } + + _headerListSize = 0; + int pos = buffer.position(); + + // Check the dynamic table sizes! + int maxDynamicTableSize = Math.min(_remoteMaxDynamicTableSize, _localMaxDynamicTableSize); + if (maxDynamicTableSize != _context.getMaxDynamicTableSize()) + encodeMaxDynamicTableSize(buffer, maxDynamicTableSize); + + // Add Request/response meta fields + if (metadata.isRequest()) + { + MetaData.Request request = (MetaData.Request)metadata; + + String method = request.getMethod(); + HttpMethod httpMethod = method == null ? null : HttpMethod.fromString(method); + HttpField methodField = C_METHODS.get(httpMethod); + encode(buffer, methodField == null ? new HttpField(HttpHeader.C_METHOD, method) : methodField); + encode(buffer, new HttpField(HttpHeader.C_AUTHORITY, request.getURI().getAuthority())); + boolean isConnect = HttpMethod.CONNECT.is(request.getMethod()); + String protocol = request.getProtocol(); + if (!isConnect || protocol != null) + { + String scheme = request.getURI().getScheme(); + encode(buffer, HttpScheme.HTTPS.is(scheme) ? C_SCHEME_HTTPS : C_SCHEME_HTTP); + encode(buffer, new HttpField(HttpHeader.C_PATH, request.getURI().getPathQuery())); + if (protocol != null) + encode(buffer,new HttpField(HttpHeader.C_PROTOCOL,protocol)); + } + } + else if (metadata.isResponse()) + { + MetaData.Response response = (MetaData.Response)metadata; + int code = response.getStatus(); + HttpField status = code < STATUSES.length ? STATUSES[code] : null; + if (status == null) + status = new HttpField.IntValueHttpField(HttpHeader.C_STATUS, code); + encode(buffer, status); + } + + // Remove fields as specified in RFC 7540, 8.1.2.2. + if (fields != null) + { + // For example: Connection: Close, TE, Upgrade, Custom. + Set hopHeaders = null; + for (String value : fields.getCSV(HttpHeader.CONNECTION, false)) + { + if (hopHeaders == null) + hopHeaders = new HashSet<>(); + hopHeaders.add(StringUtil.asciiToLowerCase(value)); + } + for (HttpField field : fields) + { + HttpHeader header = field.getHeader(); + if (header != null && IGNORED_HEADERS.contains(header)) + continue; + if (header == HttpHeader.TE) + { + if (field.contains("trailers")) + encode(buffer, TE_TRAILERS); + continue; + } + String name = field.getLowerCaseName(); + if (hopHeaders != null && hopHeaders.contains(name)) + continue; + encode(buffer, field); + } + } + + // Check size + if (_maxHeaderListSize > 0 && _headerListSize > _maxHeaderListSize) + { + LOG.warn("Header list size too large {} > {} for {}", _headerListSize, _maxHeaderListSize); + if (LOG.isDebugEnabled()) + LOG.debug("metadata={}", metadata); + } + + if (LOG.isDebugEnabled()) + LOG.debug(String.format("CtxTbl[%x] encoded %d octets", _context.hashCode(), buffer.position() - pos)); + } + catch (HpackException x) + { + throw x; + } + catch (Throwable x) + { + HpackException.SessionException failure = new HpackException.SessionException("Could not hpack encode %s", metadata); + failure.initCause(x); + throw failure; + } + } + + public void encodeMaxDynamicTableSize(ByteBuffer buffer, int maxDynamicTableSize) + { + if (maxDynamicTableSize > _remoteMaxDynamicTableSize) + throw new IllegalArgumentException(); + buffer.put((byte)0x20); + NBitInteger.encode(buffer, 5, maxDynamicTableSize); + _context.resize(maxDynamicTableSize); } public void encode(ByteBuffer buffer, HttpField field) @@ -225,8 +290,6 @@ public class HpackEncoder int fieldSize = field.getName().length() + field.getValue().length(); _headerListSize += fieldSize + 32; - final int p = _debug ? buffer.position() : -1; - String encoding = null; // Is there an entry for the field? @@ -310,12 +373,12 @@ public class HpackEncoder if (_debug) encoding = indexed ? "PreEncodedIdx" : "PreEncoded"; } - else if (__DO_NOT_INDEX.contains(header)) + else if (DO_NOT_INDEX.contains(header)) { // Non indexed field indexed = false; - boolean neverIndex = __NEVER_INDEX.contains(header); - boolean huffman = !__DO_NOT_HUFFMAN.contains(header); + boolean neverIndex = NEVER_INDEX.contains(header); + boolean huffman = !DO_NOT_HUFFMAN.contains(header); encodeName(buffer, neverIndex ? (byte)0x10 : (byte)0x00, 4, header.asString(), name); encodeValue(buffer, huffman, field.getValue()); @@ -338,7 +401,7 @@ public class HpackEncoder { // indexed indexed = true; - boolean huffman = !__DO_NOT_HUFFMAN.contains(header); + boolean huffman = !DO_NOT_HUFFMAN.contains(header); encodeName(buffer, (byte)0x40, 6, header.asString(), name); encodeValue(buffer, huffman, field.getValue()); if (_debug) @@ -354,21 +417,11 @@ public class HpackEncoder if (_debug) { - int e = buffer.position(); if (LOG.isDebugEnabled()) - LOG.debug("encode {}:'{}' to '{}'", encoding, field, TypeUtil.toHexString(buffer.array(), buffer.arrayOffset() + p, e - p)); + LOG.debug("encode {}:'{}' to '{}'", encoding, field, BufferUtil.toHexString(buffer.duplicate().flip())); } } - public void encodeMaxDynamicTableSize(ByteBuffer buffer, int maxDynamicTableSize) - { - if (maxDynamicTableSize > _remoteMaxDynamicTableSize) - throw new IllegalArgumentException(); - buffer.put((byte)0x20); - NBitInteger.encode(buffer, 5, maxDynamicTableSize); - _context.resize(maxDynamicTableSize); - } - private void encodeName(ByteBuffer buffer, byte mask, int bits, String name, Entry entry) { buffer.put(mask); @@ -392,19 +445,38 @@ public class HpackEncoder { // huffman literal value buffer.put((byte)0x80); - NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(value)); - Huffman.encode(buffer, value); + + int needed = Huffman.octetsNeeded(value); + if (needed >= 0) + { + NBitInteger.encode(buffer, 7, needed); + Huffman.encode(buffer, value); + } + else + { + // Not iso_8859_1 + byte[] bytes = value.getBytes(StandardCharsets.UTF_8); + NBitInteger.encode(buffer, 7, Huffman.octetsNeeded(bytes)); + Huffman.encode(buffer, bytes); + } } else { // add literal assuming iso_8859_1 - buffer.put((byte)0x00); + buffer.put((byte)0x00).mark(); NBitInteger.encode(buffer, 7, value.length()); for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); if (c < ' ' || c > 127) - throw new IllegalArgumentException(); + { + // Not iso_8859_1, so re-encode as UTF-8 + buffer.reset(); + byte[] bytes = value.getBytes(StandardCharsets.UTF_8); + NBitInteger.encode(buffer, 7, bytes.length); + buffer.put(bytes, 0, bytes.length); + return; + } buffer.put((byte)c); } } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java index 0a3e254b514..51204d4bd5c 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java index 2b3d30dc345..040c61c221e 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -31,22 +31,16 @@ import org.eclipse.jetty.util.BufferUtil; public class HpackFieldPreEncoder implements HttpFieldPreEncoder { - /** - * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getHttpVersion() - */ @Override public HttpVersion getHttpVersion() { return HttpVersion.HTTP_2; } - /** - * @see org.eclipse.jetty.http.HttpFieldPreEncoder#getEncodedField(org.eclipse.jetty.http.HttpHeader, java.lang.String, java.lang.String) - */ @Override public byte[] getEncodedField(HttpHeader header, String name, String value) { - boolean notIndexed = HpackEncoder.__DO_NOT_INDEX.contains(header); + boolean notIndexed = HpackEncoder.DO_NOT_INDEX.contains(header); ByteBuffer buffer = BufferUtil.allocate(name.length() + value.length() + 10); BufferUtil.clearToFill(buffer); @@ -56,8 +50,8 @@ public class HpackFieldPreEncoder implements HttpFieldPreEncoder if (notIndexed) { // Non indexed field - boolean neverIndex = HpackEncoder.__NEVER_INDEX.contains(header); - huffman = !HpackEncoder.__DO_NOT_HUFFMAN.contains(header); + boolean neverIndex = HpackEncoder.NEVER_INDEX.contains(header); + huffman = !HpackEncoder.DO_NOT_HUFFMAN.contains(header); buffer.put(neverIndex ? (byte)0x10 : (byte)0x00); bits = 4; } @@ -72,7 +66,7 @@ public class HpackFieldPreEncoder implements HttpFieldPreEncoder { // indexed buffer.put((byte)0x40); - huffman = !HpackEncoder.__DO_NOT_HUFFMAN.contains(header); + huffman = !HpackEncoder.DO_NOT_HUFFMAN.contains(header); bits = 6; } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java index 0bbe4f661d4..1e55f49720e 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java @@ -1,25 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; import java.nio.ByteBuffer; +import org.eclipse.jetty.util.Utf8StringBuilder; + public class Huffman { @@ -358,7 +360,7 @@ public class Huffman public static String decode(ByteBuffer buffer, int length) throws HpackException.CompressionException { - StringBuilder out = new StringBuilder(length * 2); + Utf8StringBuilder utf8 = new Utf8StringBuilder(length * 2); int node = 0; int current = 0; int bits = 0; @@ -378,7 +380,7 @@ public class Huffman throw new HpackException.CompressionException("EOS in content"); // terminal node - out.append(rowsym[node]); + utf8.append((byte)(0xFF & rowsym[node])); bits -= rowbits[node]; node = 0; } @@ -411,7 +413,7 @@ public class Huffman break; } - out.append(rowsym[node]); + utf8.append((byte)(0xFF & rowsym[node])); bits -= rowbits[node]; node = 0; } @@ -419,7 +421,27 @@ public class Huffman if (node != 0) throw new HpackException.CompressionException("Bad termination"); - return out.toString(); + return utf8.toString(); + } + + public static int octetsNeeded(String s) + { + return octetsNeeded(CODES, s); + } + + public static int octetsNeeded(byte[] b) + { + return octetsNeeded(CODES, b); + } + + public static void encode(ByteBuffer buffer, String s) + { + encode(CODES, buffer, s); + } + + public static void encode(ByteBuffer buffer, byte[] b) + { + encode(CODES, buffer, b); } public static int octetsNeededLC(String s) @@ -432,11 +454,6 @@ public class Huffman encode(LCCODES, buffer, s); } - public static int octetsNeeded(String s) - { - return octetsNeeded(CODES, s); - } - private static int octetsNeeded(final int[][] table, String s) { int needed = 0; @@ -445,18 +462,30 @@ public class Huffman { char c = s.charAt(i); if (c >= 128 || c < ' ') - throw new IllegalArgumentException(); + return -1; needed += table[c][1]; } return (needed + 7) / 8; } - public static void encode(ByteBuffer buffer, String s) + private static int octetsNeeded(final int[][] table, byte[] b) { - encode(CODES, buffer, s); + int needed = 0; + int len = b.length; + for (int i = 0; i < len; i++) + { + int c = 0xFF & b[i]; + needed += table[c][1]; + } + return (needed + 7) / 8; } + /** + * @param table The table to encode by + * @param buffer The buffer to encode to + * @param s The string to encode + */ private static void encode(final int[][] table, ByteBuffer buffer, String s) { long current = 0; @@ -488,4 +517,35 @@ public class Huffman buffer.put((byte)(current)); } } + + private static void encode(final int[][] table, ByteBuffer buffer, byte[] b) + { + long current = 0; + int n = 0; + + int len = b.length; + for (int i = 0; i < len; i++) + { + int c = 0xFF & b[i]; + int code = table[c][0]; + int bits = table[c][1]; + + current <<= bits; + current |= code; + n += bits; + + while (n >= 8) + { + n -= 8; + buffer.put((byte)(current >> n)); + } + } + + if (n > 0) + { + current <<= (8 - n); + current |= (0xFF >>> n); + buffer.put((byte)(current)); + } + } } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java index 8afb5d5344a..31146eefd5b 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -22,6 +22,7 @@ import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; @@ -36,6 +37,7 @@ public class MetaDataBuilder private HttpScheme _scheme; private HostPortHttpField _authority; private String _path; + private String _protocol; private long _contentLength = Long.MIN_VALUE; private HttpFields _fields = new HttpFields(); private HpackException.StreamException _streamException; @@ -74,11 +76,13 @@ public class MetaDataBuilder { HttpHeader header = field.getHeader(); String name = field.getName(); + if (name == null || name.length() == 0) + throw new HpackException.SessionException("Header size 0"); String value = field.getValue(); int fieldSize = name.length() + (value == null ? 0 : value.length()); _size += fieldSize + 32; if (_size > _maxSize) - throw new HpackException.SessionException("Header Size %d > %d", _size, _maxSize); + throw new HpackException.SessionException("Header size %d > %d", _size, _maxSize); if (field instanceof StaticTableHttpField) { @@ -140,6 +144,23 @@ public class MetaDataBuilder _request = true; break; + case C_PATH: + if (checkPseudoHeader(header, _path)) + { + if (value != null && value.length() > 0) + _path = value; + else + streamException("No Path"); + } + _request = true; + break; + + case C_PROTOCOL: + if (checkPseudoHeader(header, _protocol)) + _protocol = value; + _request = true; + break; + case HOST: // :authority fields must come first. If we have one, ignore the host header as far as authority goes. if (_authority == null) @@ -152,17 +173,6 @@ public class MetaDataBuilder _fields.add(field); break; - case C_PATH: - if (checkPseudoHeader(header, _path)) - { - if (value != null && value.length() > 0) - _path = value; - else - streamException("No Path"); - } - _request = true; - break; - case CONTENT_LENGTH: _contentLength = field.getLongValue(); _fields.add(field); @@ -239,11 +249,18 @@ public class MetaDataBuilder { if (_method == null) throw new HpackException.StreamException("No Method"); - if (_scheme == null) - throw new HpackException.StreamException("No Scheme"); - if (_path == null) - throw new HpackException.StreamException("No Path"); - return new MetaData.Request(_method, _scheme, _authority, _path, HttpVersion.HTTP_2, fields, _contentLength); + boolean isConnect = HttpMethod.CONNECT.is(_method); + if (!isConnect || _protocol != null) + { + if (_scheme == null) + throw new HpackException.StreamException("No Scheme"); + if (_path == null) + throw new HpackException.StreamException("No Path"); + } + if (isConnect) + return new MetaData.ConnectRequest(_scheme, _authority, _path, fields, _protocol); + else + return new MetaData.Request(_method, _scheme, _authority, _path, HttpVersion.HTTP_2, fields, _contentLength); } if (_response) { @@ -264,6 +281,7 @@ public class MetaDataBuilder _scheme = null; _authority = null; _path = null; + _protocol = null; _size = 0; _contentLength = Long.MIN_VALUE; } diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java index 7d700cd4338..11c45b343d8 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/NBitInteger.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/StaticTableHttpField.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/StaticTableHttpField.java index 56bd4bc4be6..a879ebdcca1 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/StaticTableHttpField.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/StaticTableHttpField.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java index ed4ac09d86a..9242b9f31d2 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -104,7 +104,7 @@ public class HpackContextTest new HttpField("name", "v3"), new HttpField("name", "v4"), new HttpField("name", "v5"), - }; + }; Entry[] entry = new Entry[field.length]; @@ -197,7 +197,7 @@ public class HpackContextTest new HttpField("fo8", "b8r"), new HttpField("fo9", "b9r"), new HttpField("foA", "bAr"), - }; + }; Entry[] entry = new Entry[100]; @@ -324,7 +324,7 @@ public class HpackContextTest new HttpField("fo8", "b8r"), new HttpField("fo9", "b9r"), new HttpField("foA", "bAr"), - }; + }; Entry[] entry = new Entry[field.length]; // Add 5 entries diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java index 12526186674..9598b7180b2 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -26,6 +26,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.hpack.HpackException.CompressionException; +import org.eclipse.jetty.http2.hpack.HpackException.SessionException; import org.eclipse.jetty.http2.hpack.HpackException.StreamException; import org.eclipse.jetty.util.TypeUtil; import org.hamcrest.Matchers; @@ -43,8 +44,23 @@ import static org.junit.jupiter.api.Assertions.fail; public class HpackDecoderTest { + /* + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | 0 | 0 | 0 | 0 | 0 | + +---+---+-----------------------+ + | H | Name Length (7+) | + +---+---------------------------+ + | Name String (Length octets) | + +---+---------------------------+ + | H | Value Length (7+) | + +---+---------------------------+ + | Value String (Length octets) | + +-------------------------------+ + */ + @Test - public void testDecodeD_3() throws Exception + public void testDecodeD3() throws Exception { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -92,7 +108,7 @@ public class HpackDecoderTest } @Test - public void testDecodeD_4() throws Exception + public void testDecodeD4() throws Exception { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -253,15 +269,15 @@ public class HpackDecoderTest decoder.decode(buffer); fail(); } - catch (HpackException.SessionException e) + catch (SessionException e) { assertThat(e.getMessage(), Matchers.startsWith("Unknown index")); } } /* 8.1.2.1. Pseudo-Header Fields */ - @Test() - public void test8_1_2_1_PsuedoHeaderFields() throws Exception + @Test + public void test8121PseudoHeaderFields() throws Exception { // 1:Sends a HEADERS frame that contains a unknown pseudo-header field MetaDataBuilder mdb = new MetaDataBuilder(4096); @@ -312,8 +328,8 @@ public class HpackDecoderTest } } - @Test() - public void test8_1_2_2_ConnectionSpecificHeaderFields() throws Exception + @Test + public void test8122ConnectionSpecificHeaderFields() throws Exception { MetaDataBuilder mdb; @@ -349,8 +365,8 @@ public class HpackDecoderTest assertNotNull(mdb.build()); } - @Test() - public void test8_1_2_3_RequestPseudoHeaderFields() throws Exception + @Test + public void test8123RequestPseudoHeaderFields() throws Exception { { MetaDataBuilder mdb = new MetaDataBuilder(4096); @@ -368,7 +384,7 @@ public class HpackDecoderTest mdb.emit(new HttpField(HttpHeader.C_SCHEME, "http")); mdb.emit(new HttpField(HttpHeader.C_AUTHORITY, "localhost:8080")); mdb.emit(new HttpField(HttpHeader.C_PATH, "")); - StreamException ex = assertThrows(StreamException.class, () -> mdb.build()); + StreamException ex = assertThrows(StreamException.class, mdb::build); assertThat(ex.getMessage(), Matchers.containsString("No Path")); } @@ -378,7 +394,7 @@ public class HpackDecoderTest mdb.emit(new HttpField(HttpHeader.C_SCHEME, "http")); mdb.emit(new HttpField(HttpHeader.C_AUTHORITY, "localhost:8080")); mdb.emit(new HttpField(HttpHeader.C_PATH, "/")); - StreamException ex = assertThrows(StreamException.class, () -> mdb.build()); + StreamException ex = assertThrows(StreamException.class, mdb::build); assertThat(ex.getMessage(), Matchers.containsString("No Method")); } @@ -388,7 +404,7 @@ public class HpackDecoderTest mdb.emit(new HttpField(HttpHeader.C_METHOD, "GET")); mdb.emit(new HttpField(HttpHeader.C_AUTHORITY, "localhost:8080")); mdb.emit(new HttpField(HttpHeader.C_PATH, "/")); - StreamException ex = assertThrows(StreamException.class, () -> mdb.build()); + StreamException ex = assertThrows(StreamException.class, mdb::build); assertThat(ex.getMessage(), Matchers.containsString("No Scheme")); } @@ -398,7 +414,7 @@ public class HpackDecoderTest mdb.emit(new HttpField(HttpHeader.C_METHOD, "GET")); mdb.emit(new HttpField(HttpHeader.C_SCHEME, "http")); mdb.emit(new HttpField(HttpHeader.C_AUTHORITY, "localhost:8080")); - StreamException ex = assertThrows(StreamException.class, () -> mdb.build()); + StreamException ex = assertThrows(StreamException.class, mdb::build); assertThat(ex.getMessage(), Matchers.containsString("No Path")); } @@ -410,7 +426,7 @@ public class HpackDecoderTest mdb.emit(new HttpField(HttpHeader.C_SCHEME, "http")); mdb.emit(new HttpField(HttpHeader.C_AUTHORITY, "localhost:8080")); mdb.emit(new HttpField(HttpHeader.C_PATH, "/")); - StreamException ex = assertThrows(StreamException.class, () -> mdb.build()); + StreamException ex = assertThrows(StreamException.class, mdb::build); assertThat(ex.getMessage(), Matchers.containsString("Duplicate")); } @@ -423,12 +439,12 @@ public class HpackDecoderTest mdb.emit(new HttpField(HttpHeader.C_AUTHORITY, "localhost:8080")); mdb.emit(new HttpField(HttpHeader.C_PATH, "/")); - StreamException ex = assertThrows(StreamException.class, () -> mdb.build()); + StreamException ex = assertThrows(StreamException.class, mdb::build); assertThat(ex.getMessage(), Matchers.containsString("Duplicate")); } } - @Test() + @Test public void testHuffmanEncodedStandard() throws Exception { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -446,8 +462,8 @@ public class HpackDecoderTest } /* 5.2.1: Sends a Huffman-encoded string literal representation with padding longer than 7 bits */ - @Test() - public void testHuffmanEncodedExtraPadding() throws Exception + @Test + public void testHuffmanEncodedExtraPadding() { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -458,8 +474,8 @@ public class HpackDecoderTest } /* 5.2.2: Sends a Huffman-encoded string literal representation padded by zero */ - @Test() - public void testHuffmanEncodedZeroPadding() throws Exception + @Test + public void testHuffmanEncodedZeroPadding() { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -471,8 +487,8 @@ public class HpackDecoderTest } /* 5.2.3: Sends a Huffman-encoded string literal representation containing the EOS symbol */ - @Test() - public void testHuffmanEncodedWithEOS() throws Exception + @Test + public void testHuffmanEncodedWithEOS() { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -483,8 +499,8 @@ public class HpackDecoderTest assertThat(ex.getMessage(), Matchers.containsString("EOS in content")); } - @Test() - public void testHuffmanEncodedOneIncompleteOctet() throws Exception + @Test + public void testHuffmanEncodedOneIncompleteOctet() { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -495,8 +511,8 @@ public class HpackDecoderTest assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); } - @Test() - public void testHuffmanEncodedTwoIncompleteOctet() throws Exception + @Test + public void testHuffmanEncodedTwoIncompleteOctet() { HpackDecoder decoder = new HpackDecoder(4096, 8192); @@ -506,4 +522,49 @@ public class HpackDecoderTest CompressionException ex = assertThrows(CompressionException.class, () -> decoder.decode(buffer)); assertThat(ex.getMessage(), Matchers.containsString("Bad termination")); } + + @Test + public void testZeroLengthName() + { + HpackDecoder decoder = new HpackDecoder(4096, 8192); + + String encoded = "00000130"; + ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); + SessionException ex = assertThrows(SessionException.class, () -> decoder.decode(buffer)); + assertThat(ex.getMessage(), Matchers.containsString("Header size 0")); + } + + @Test + public void testZeroLengthValue() throws Exception + { + HpackDecoder decoder = new HpackDecoder(4096, 8192); + + String encoded = "00016800"; + ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); + MetaData metaData = decoder.decode(buffer); + assertThat(metaData.getFields().size(), is(1)); + assertThat(metaData.getFields().get("h"), is("")); + } + + @Test + public void testUpperCaseName() + { + HpackDecoder decoder = new HpackDecoder(4096, 8192); + + String encoded = "0001480130"; + ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); + StreamException ex = assertThrows(StreamException.class, () -> decoder.decode(buffer)); + assertThat(ex.getMessage(), Matchers.containsString("Uppercase header")); + } + + @Test + public void testWhiteSpaceName() + { + HpackDecoder decoder = new HpackDecoder(4096, 8192); + + String encoded = "0001200130"; + ByteBuffer buffer = ByteBuffer.wrap(TypeUtil.fromHexString(encoded)); + StreamException ex = assertThrows(StreamException.class, () -> decoder.decode(buffer)); + assertThat(ex.getMessage(), Matchers.containsString("Illegal header")); + } } diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java index d9a59639950..4d29aae6c87 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -32,13 +32,10 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; -/** - * - */ public class HpackEncoderTest { @Test - public void testUnknownFieldsContextManagement() + public void testUnknownFieldsContextManagement() throws Exception { HpackEncoder encoder = new HpackEncoder(38 * 5); HttpFields fields = new HttpFields(); @@ -56,7 +53,7 @@ public class HpackEncoderTest new HttpField("fo8", "b8r"), new HttpField("fo9", "b9r"), new HttpField("foA", "bAr"), - }; + }; // Add 4 entries for (int i = 0; i <= 3; i++) @@ -149,7 +146,7 @@ public class HpackEncoderTest } @Test - public void testNeverIndexSetCookie() + public void testNeverIndexSetCookie() throws Exception { HpackEncoder encoder = new HpackEncoder(38 * 5); ByteBuffer buffer = BufferUtil.allocate(4096); @@ -181,7 +178,7 @@ public class HpackEncoderTest } @Test - public void testFieldLargerThanTable() + public void testFieldLargerThanTable() throws Exception { HttpFields fields = new HttpFields(); @@ -199,6 +196,7 @@ public class HpackEncoderTest BufferUtil.flipToFlush(buffer1, pos); encoder = new HpackEncoder(128); + encoder.setValidateEncoding(false); fields.add(new HttpField(":path", "This is a very large field, whose size is larger than the dynamic table so it should not be indexed as it will not fit in the table ever!" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " + @@ -210,6 +208,7 @@ public class HpackEncoderTest BufferUtil.flipToFlush(buffer2, pos); encoder = new HpackEncoder(128); + encoder.setValidateEncoding(false); fields.add(new HttpField("host", "somehost")); ByteBuffer buffer = BufferUtil.allocate(4096); pos = BufferUtil.flipToFill(buffer); @@ -243,7 +242,7 @@ public class HpackEncoderTest } @Test - public void testResize() + public void testResize() throws Exception { HttpFields fields = new HttpFields(); fields.add("host", "localhost0"); diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java index 959a064eafb..bfb43a16865 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java @@ -1,26 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; import java.io.File; import java.io.FileReader; -import java.io.FilenameFilter; import java.nio.ByteBuffer; import java.util.Map; @@ -34,6 +33,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class HpackPerfTest { int _maxDynamicTableSize = 4 * 1024; @@ -56,28 +57,25 @@ public class HpackPerfTest @Test public void simpleTest() throws Exception { - runStories(_maxDynamicTableSize); + runStories(); } - private void runStories(int maxDynamicTableSize) throws Exception + private void runStories() throws Exception { // Find files File data = MavenTestingUtils.getTestResourceDir("data"); - String[] files = data.list(new FilenameFilter() - { - @Override - public boolean accept(File dir, String name) - { - return name.startsWith("story_"); - } - }); + String[] files = data.list((dir, name) -> name.startsWith("story_")); + assertNotNull(files); // Parse JSON + @SuppressWarnings("unchecked") Map[] stories = new Map[files.length]; int i = 0; - for (String story : files) + for (String file : files) { - stories[i++] = (Map)JSON.parse(new FileReader(new File(data, story))); + @SuppressWarnings("unchecked") + var story = (Map)new JSON().fromJSON(new FileReader(new File(data, file))); + stories[i++] = story; } ByteBuffer buffer = BufferUtil.allocate(256 * 1024); @@ -100,18 +98,20 @@ public class HpackPerfTest if (type.equals(story.get("context"))) { HpackEncoder encoder = new HpackEncoder(_maxDynamicTableSize, _maxDynamicTableSize); + encoder.setValidateEncoding(false); - // System.err.println(story); Object[] cases = (Object[])story.get("cases"); for (Object c : cases) { - // System.err.println(" "+c); - Object[] headers = (Object[])((Map)c).get("headers"); + @SuppressWarnings("unchecked") + var kase = (Map)c; + Object[] headers = (Object[])kase.get("headers"); // System.err.println(" "+headers); HttpFields fields = new HttpFields(); for (Object header : headers) { - Map h = (Map)header; + @SuppressWarnings("unchecked") + var h = (Map)header; Map.Entry e = h.entrySet().iterator().next(); fields.add(e.getKey(), e.getValue()); _unencodedSize += e.getKey().length() + e.getValue().length(); diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java index 7b9218d3585..329827897cb 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -36,6 +36,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.fail; public class HpackTest @@ -67,7 +68,7 @@ public class HpackTest BufferUtil.flipToFlush(buffer, 0); Response decoded0 = (Response)decoder.decode(buffer); original0.getFields().put(new HttpField(HttpHeader.CONTENT_ENCODING, "")); - assertMetadataSame(original0, decoded0); + assertMetaDataResponseSame(original0, decoded0); // Same again? BufferUtil.clearToFill(buffer); @@ -75,7 +76,7 @@ public class HpackTest BufferUtil.flipToFlush(buffer, 0); Response decoded0b = (Response)decoder.decode(buffer); - assertMetadataSame(original0, decoded0b); + assertMetaDataResponseSame(original0, decoded0b); HttpFields fields1 = new HttpFields(); fields1.add(HttpHeader.CONTENT_TYPE, "text/plain"); @@ -93,7 +94,7 @@ public class HpackTest BufferUtil.flipToFlush(buffer, 0); Response decoded1 = (Response)decoder.decode(buffer); - assertMetadataSame(original1, decoded1); + assertMetaDataResponseSame(original1, decoded1); assertEquals("custom-key", decoded1.getFields().getField("Custom-Key").getName()); } @@ -106,19 +107,19 @@ public class HpackTest HttpFields fields0 = new HttpFields(); fields0.add("1234567890", "1234567890123456789012345678901234567890"); - fields0.add("Cookie", "abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"); + fields0.add("Cookie", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"); MetaData original0 = new MetaData(HttpVersion.HTTP_2, fields0); BufferUtil.clearToFill(buffer); encoder.encode(buffer, original0); BufferUtil.flipToFlush(buffer, 0); - MetaData decoded0 = (MetaData)decoder.decode(buffer); + MetaData decoded0 = decoder.decode(buffer); - assertMetadataSame(original0, decoded0); + assertMetaDataSame(original0, decoded0); HttpFields fields1 = new HttpFields(); fields1.add("1234567890", "1234567890123456789012345678901234567890"); - fields1.add("Cookie", "abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"); + fields1.add("Cookie", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"); fields1.add("x", "y"); MetaData original1 = new MetaData(HttpVersion.HTTP_2, fields1); @@ -136,6 +137,27 @@ public class HpackTest } } + @Test + public void encodeDecodeNonAscii() throws Exception + { + HpackEncoder encoder = new HpackEncoder(); + HpackDecoder decoder = new HpackDecoder(4096, 8192); + ByteBuffer buffer = BufferUtil.allocate(16 * 1024); + + HttpFields fields0 = new HttpFields(); + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck + fields0.add("Cookie", "[\uD842\uDF9F]"); + fields0.add("custom-key", "[\uD842\uDF9F]"); + Response original0 = new MetaData.Response(HttpVersion.HTTP_2, 200, fields0); + + BufferUtil.clearToFill(buffer); + encoder.encode(buffer, original0); + BufferUtil.flipToFlush(buffer, 0); + Response decoded0 = (Response)decoder.decode(buffer); + + assertMetaDataSame(original0, decoded0); + } + @Test public void evictReferencedFieldTest() throws Exception { @@ -143,57 +165,132 @@ public class HpackTest HpackDecoder decoder = new HpackDecoder(200, 1024); ByteBuffer buffer = BufferUtil.allocateDirect(16 * 1024); + String longEnoughToBeEvicted = "012345678901234567890123456789012345678901234567890"; + HttpFields fields0 = new HttpFields(); - fields0.add("123456789012345678901234567890123456788901234567890", "value"); - fields0.add("foo", "abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"); + fields0.add(longEnoughToBeEvicted, "value"); + fields0.add("foo", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); MetaData original0 = new MetaData(HttpVersion.HTTP_2, fields0); BufferUtil.clearToFill(buffer); encoder.encode(buffer, original0); BufferUtil.flipToFlush(buffer, 0); - MetaData decoded0 = (MetaData)decoder.decode(buffer); + MetaData decoded0 = decoder.decode(buffer); assertEquals(2, encoder.getHpackContext().size()); assertEquals(2, decoder.getHpackContext().size()); - assertEquals("123456789012345678901234567890123456788901234567890", encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length + 1).getHttpField().getName()); - assertEquals("foo", encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length + 0).getHttpField().getName()); + assertEquals(longEnoughToBeEvicted, encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length + 1).getHttpField().getName()); + assertEquals("foo", encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length).getHttpField().getName()); - assertMetadataSame(original0, decoded0); + assertMetaDataSame(original0, decoded0); HttpFields fields1 = new HttpFields(); - fields1.add("123456789012345678901234567890123456788901234567890", "other_value"); + fields1.add(longEnoughToBeEvicted, "other_value"); fields1.add("x", "y"); MetaData original1 = new MetaData(HttpVersion.HTTP_2, fields1); BufferUtil.clearToFill(buffer); encoder.encode(buffer, original1); BufferUtil.flipToFlush(buffer, 0); - MetaData decoded1 = (MetaData)decoder.decode(buffer); - assertMetadataSame(original1, decoded1); + MetaData decoded1 = decoder.decode(buffer); + assertMetaDataSame(original1, decoded1); assertEquals(2, encoder.getHpackContext().size()); assertEquals(2, decoder.getHpackContext().size()); - assertEquals("x", encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length + 0).getHttpField().getName()); + assertEquals("x", encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length).getHttpField().getName()); assertEquals("foo", encoder.getHpackContext().get(HpackContext.STATIC_TABLE.length + 1).getHttpField().getName()); } - private void assertMetadataSame(MetaData.Response expected, MetaData.Response actual) + @Test + public void testHopHeadersAreRemoved() throws Exception + { + HpackEncoder encoder = new HpackEncoder(); + HpackDecoder decoder = new HpackDecoder(4096, 16384); + + HttpFields input = new HttpFields(); + input.put(HttpHeader.ACCEPT, "*"); + input.put(HttpHeader.CONNECTION, "TE, Upgrade, Custom"); + input.put("Custom", "Pizza"); + input.put(HttpHeader.KEEP_ALIVE, "true"); + input.put(HttpHeader.PROXY_CONNECTION, "foo"); + input.put(HttpHeader.TE, "1234567890abcdef"); + input.put(HttpHeader.TRANSFER_ENCODING, "chunked"); + input.put(HttpHeader.UPGRADE, "gold"); + + ByteBuffer buffer = BufferUtil.allocate(2048); + BufferUtil.clearToFill(buffer); + encoder.encode(buffer, new MetaData(HttpVersion.HTTP_2, input)); + BufferUtil.flipToFlush(buffer, 0); + MetaData metaData = decoder.decode(buffer); + HttpFields output = metaData.getFields(); + + assertEquals(1, output.size()); + assertEquals("*", output.get(HttpHeader.ACCEPT)); + } + + @Test + public void testTETrailers() throws Exception + { + HpackEncoder encoder = new HpackEncoder(); + HpackDecoder decoder = new HpackDecoder(4096, 16384); + + HttpFields input = new HttpFields(); + input.put(HttpHeader.CONNECTION, "TE"); + String teValue = "trailers"; + input.put(HttpHeader.TE, teValue); + String trailerValue = "Custom"; + input.put(HttpHeader.TRAILER, trailerValue); + + ByteBuffer buffer = BufferUtil.allocate(2048); + BufferUtil.clearToFill(buffer); + encoder.encode(buffer, new MetaData(HttpVersion.HTTP_2, input)); + BufferUtil.flipToFlush(buffer, 0); + MetaData metaData = decoder.decode(buffer); + HttpFields output = metaData.getFields(); + + assertEquals(2, output.size()); + assertEquals(teValue, output.get(HttpHeader.TE)); + assertEquals(trailerValue, output.get(HttpHeader.TRAILER)); + } + + @Test + public void testColonHeaders() throws Exception + { + HpackEncoder encoder = new HpackEncoder(); + HpackDecoder decoder = new HpackDecoder(4096, 16384); + + HttpFields input = new HttpFields(); + input.put(":status", "200"); + input.put(":custom", "special"); + + ByteBuffer buffer = BufferUtil.allocate(2048); + BufferUtil.clearToFill(buffer); + assertThrows(HpackException.StreamException.class, () -> encoder.encode(buffer, new MetaData(HttpVersion.HTTP_2, input))); + + encoder.setValidateEncoding(false); + encoder.encode(buffer, new MetaData(HttpVersion.HTTP_2, input)); + + BufferUtil.flipToFlush(buffer, 0); + assertThrows(HpackException.StreamException.class, () -> decoder.decode(buffer)); + } + + private void assertMetaDataResponseSame(MetaData.Response expected, MetaData.Response actual) { assertThat("Response.status", actual.getStatus(), is(expected.getStatus())); assertThat("Response.reason", actual.getReason(), is(expected.getReason())); - assertMetadataSame((MetaData)expected, (MetaData)actual); + assertMetaDataSame(expected, actual); } - private void assertMetadataSame(MetaData expected, MetaData actual) + private void assertMetaDataSame(MetaData expected, MetaData actual) { assertThat("Metadata.contentLength", actual.getContentLength(), is(expected.getContentLength())); assertThat("Metadata.version" + ".version", actual.getHttpVersion(), is(expected.getHttpVersion())); - assertHttpFieldsSame("Metadata.fields", expected.getFields(), actual.getFields()); + assertHttpFieldsSame(expected.getFields(), actual.getFields()); } - private void assertHttpFieldsSame(String msg, HttpFields expected, HttpFields actual) + private void assertHttpFieldsSame(HttpFields expected, HttpFields actual) { - assertThat(msg + ".size", actual.size(), is(expected.size())); + assertThat("metaData.fields.size", actual.size(), is(expected.size())); for (HttpField actualField : actual) { @@ -203,7 +300,7 @@ public class HpackTest // during testing. continue; } - assertThat(msg + ".contains(" + actualField + ")", expected.contains(actualField), is(true)); + assertThat("metaData.fields.contains(" + actualField + ")", expected.contains(actualField), is(true)); } } } diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java index 802427f1866..123844c82d6 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -25,11 +25,13 @@ import java.util.stream.Stream; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.TypeUtil; +import org.hamcrest.Matchers; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -77,8 +79,7 @@ public class HuffmanTest { String s = "bad '" + bad + "'"; - assertThrows(IllegalArgumentException.class, - () -> Huffman.octetsNeeded(s)); + assertThat(Huffman.octetsNeeded(s), Matchers.is(-1)); assertThrows(BufferOverflowException.class, () -> Huffman.encode(BufferUtil.allocate(32), s)); diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java index 1fe8fd60f2f..490a6c135d2 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.hpack; @@ -131,7 +131,7 @@ public class NBitIntegerTest } @Test - public void testEncodeExampleD_1_1() + public void testEncodeExampleD11() { ByteBuffer buf = BufferUtil.allocate(16); int p = BufferUtil.flipToFill(buf); @@ -146,7 +146,7 @@ public class NBitIntegerTest } @Test - public void testDecodeExampleD_1_1() + public void testDecodeExampleD11() { ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("77EaFF")); buf.position(2); @@ -155,7 +155,7 @@ public class NBitIntegerTest } @Test - public void testEncodeExampleD_1_2() + public void testEncodeExampleD12() { ByteBuffer buf = BufferUtil.allocate(16); int p = BufferUtil.flipToFill(buf); @@ -170,7 +170,7 @@ public class NBitIntegerTest } @Test - public void testDecodeExampleD_1_2() + public void testDecodeExampleD12() { ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("881f9a0aff")); buf.position(2); @@ -179,7 +179,7 @@ public class NBitIntegerTest } @Test - public void testEncodeExampleD_1_3() + public void testEncodeExampleD13() { ByteBuffer buf = BufferUtil.allocate(16); int p = BufferUtil.flipToFill(buf); @@ -194,7 +194,7 @@ public class NBitIntegerTest } @Test - public void testDecodeExampleD_1_3() + public void testDecodeExampleD13() { ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString("882aFf")); buf.position(1); diff --git a/jetty-http2/http2-hpack/src/test/resources/jetty-logging.properties b/jetty-http2/http2-hpack/src/test/resources/jetty-logging.properties index f4e33644f4c..9c83a8ee8bb 100644 --- a/jetty-http2/http2-hpack/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-hpack/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.http2.LEVEL=DEBUG #org.eclipse.jetty.http2.hpack.LEVEL=DEBUG diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index da589baa10d..cbc6246eef2 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -14,19 +14,6 @@ ${project.groupId}.client.http - - - - maven-surefire-plugin - - - @{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.http2.http.client.transport=jetty.servlet.api --add-modules jetty.servlet.api - - - - - - org.eclipse.jetty @@ -43,12 +30,22 @@ jetty-alpn-java-client ${project.version} + + org.slf4j + slf4j-api + + org.eclipse.jetty jetty-alpn-java-server ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-http2/http2-http-client-transport/src/main/java/module-info.java b/jetty-http2/http2-http-client-transport/src/main/java/module-info.java index 588427c1a8d..c5e35ef3ef8 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/module-info.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.http2.http.client.transport @@ -21,10 +21,7 @@ module org.eclipse.jetty.http2.http.client.transport exports org.eclipse.jetty.http2.client.http; requires org.eclipse.jetty.alpn.client; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.http2.client; - requires org.eclipse.jetty.http2.common; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.client; + requires transitive org.eclipse.jetty.http2.client; + requires org.slf4j; } diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientConnectionFactoryOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientConnectionFactoryOverHTTP2.java index 8ca10232392..1f17ae4bfcd 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientConnectionFactoryOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientConnectionFactoryOverHTTP2.java @@ -1,34 +1,41 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.List; import java.util.Map; +import org.eclipse.jetty.client.HttpClientTransport; +import org.eclipse.jetty.client.HttpDestination; +import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.http2.client.HTTP2Client; import org.eclipse.jetty.http2.client.HTTP2ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnectionFactory; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; +import org.eclipse.jetty.io.ssl.SslConnection; +import org.eclipse.jetty.util.Promise; +import org.eclipse.jetty.util.component.ContainerLifeCycle; -public class ClientConnectionFactoryOverHTTP2 implements ClientConnectionFactory +public class ClientConnectionFactoryOverHTTP2 extends ContainerLifeCycle implements ClientConnectionFactory { private final ClientConnectionFactory factory = new HTTP2ClientConnectionFactory(); private final HTTP2Client client; @@ -36,10 +43,11 @@ public class ClientConnectionFactoryOverHTTP2 implements ClientConnectionFactory public ClientConnectionFactoryOverHTTP2(HTTP2Client client) { this.client = client; + addBean(client); } @Override - public Connection newConnection(EndPoint endPoint, Map context) throws IOException + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { HTTPSessionListenerPromise listenerPromise = new HTTPSessionListenerPromise(context); context.put(HTTP2ClientConnectionFactory.CLIENT_CONTEXT_KEY, client); @@ -62,5 +70,54 @@ public class ClientConnectionFactoryOverHTTP2 implements ClientConnectionFactory { super(List.of("h2c"), new ClientConnectionFactoryOverHTTP2(client)); } + + @Override + public void upgrade(EndPoint endPoint, Map context) + { + HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + @SuppressWarnings("unchecked") + Promise promise = (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); + context.put(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY, new Promise() + { + @Override + public void succeeded(HttpConnectionOverHTTP2 connection) + { + // This code is run when the client receives the server preface reply. + // Upgrade the connection to setup HTTP/2 frame listeners that will + // handle the HTTP/2 response to the upgrade request. + promise.succeeded(connection); + connection.upgrade(context); + // The connection can be used only after the upgrade that + // creates stream #1 corresponding to the HTTP/1.1 upgrade + // request, otherwise other requests can steal id #1. + destination.accept(connection); + } + + @Override + public void failed(Throwable x) + { + promise.failed(x); + } + }); + upgrade(destination.getClientConnectionFactory(), endPoint, context); + } + + private void upgrade(ClientConnectionFactory factory, EndPoint endPoint, Map context) + { + try + { + // Avoid double TLS wrapping. We want to keep the existing + // SslConnection that has already performed the TLS handshake, + // and just upgrade the nested connection. + if (factory instanceof SslClientConnectionFactory && endPoint instanceof SslConnection.DecryptedEndPoint) + factory = ((SslClientConnectionFactory)factory).getClientConnectionFactory(); + var newConnection = factory.newConnection(endPoint, context); + endPoint.upgrade(newConnection); + } + catch (IOException x) + { + throw new UncheckedIOException(x); + } + } } } diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientHTTP2StreamEndPoint.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientHTTP2StreamEndPoint.java new file mode 100644 index 00000000000..f189f1c3ee8 --- /dev/null +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/ClientHTTP2StreamEndPoint.java @@ -0,0 +1,61 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.client.http; + +import org.eclipse.jetty.http2.HTTP2Channel; +import org.eclipse.jetty.http2.HTTP2StreamEndPoint; +import org.eclipse.jetty.http2.IStream; +import org.eclipse.jetty.http2.frames.DataFrame; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.util.Callback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ClientHTTP2StreamEndPoint extends HTTP2StreamEndPoint implements HTTP2Channel.Client +{ + private static final Logger LOG = LoggerFactory.getLogger(ClientHTTP2StreamEndPoint.class); + + public ClientHTTP2StreamEndPoint(IStream stream) + { + super(stream); + } + + @Override + public void onData(DataFrame frame, Callback callback) + { + offerData(frame, callback); + } + + @Override + public boolean onTimeout(Throwable failure) + { + if (LOG.isDebugEnabled()) + LOG.debug("idle timeout on {}: {}", this, failure); + Connection connection = getConnection(); + if (connection != null) + return connection.onIdleExpired(); + return true; + } + + @Override + public void onFailure(Throwable failure, Callback callback) + { + callback.failed(failure); + } +} diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HTTPSessionListenerPromise.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HTTPSessionListenerPromise.java index 6db3aad9b70..17ebfb51115 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HTTPSessionListenerPromise.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HTTPSessionListenerPromise.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; @@ -62,7 +62,7 @@ class HTTPSessionListenerPromise extends Session.Listener.Adapter implements Pro } @SuppressWarnings("unchecked") - private Promise connectionPromise() + private Promise httpConnectionPromise() { return (Promise)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY); } @@ -77,6 +77,7 @@ class HTTPSessionListenerPromise extends Session.Listener.Adapter implements Pro if (destination instanceof HttpDestination.Multiplexed) ((HttpDestination.Multiplexed)destination).setMaxRequestsPerConnection(settings.get(SettingsFrame.MAX_CONCURRENT_STREAMS)); } + // The first SETTINGS frame is the server preface reply. if (!connection.isMarked()) onServerPreface(session); } @@ -85,7 +86,7 @@ class HTTPSessionListenerPromise extends Session.Listener.Adapter implements Pro { HttpConnectionOverHTTP2 connection = newHttpConnection(destination(), session); if (this.connection.compareAndSet(null, connection, false, true)) - connectionPromise().succeeded(connection); + httpConnectionPromise().succeeded(connection); } protected HttpConnectionOverHTTP2 newHttpConnection(HttpDestination destination, Session session) @@ -105,6 +106,7 @@ class HTTPSessionListenerPromise extends Session.Listener.Adapter implements Pro void onClose(HttpConnectionOverHTTP2 connection, GoAwayFrame frame) { + connection.close(); } @Override @@ -133,7 +135,7 @@ class HTTPSessionListenerPromise extends Session.Listener.Adapter implements Pro { boolean result = connection.compareAndSet(null, null, false, true); if (result) - connectionPromise().failed(failure); + httpConnectionPromise().failed(failure); return result; } } diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java index 3373e5a1401..2bec70b3e42 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java @@ -1,23 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; +import java.io.IOException; + import org.eclipse.jetty.client.HttpChannel; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpExchange; @@ -25,14 +27,19 @@ import org.eclipse.jetty.client.HttpReceiver; import org.eclipse.jetty.client.HttpSender; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Channel; import org.eclipse.jetty.http2.IStream; 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.PushPromiseFrame; import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.util.Callback; public class HttpChannelOverHTTP2 extends HttpChannel { + private final Stream.Listener listener = new Listener(); private final HttpConnectionOverHTTP2 connection; private final Session session; private final HttpSenderOverHTTP2 sender; @@ -60,7 +67,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel public Stream.Listener getStreamListener() { - return receiver; + return listener; } @Override @@ -83,6 +90,8 @@ public class HttpChannelOverHTTP2 extends HttpChannel public void setStream(Stream stream) { this.stream = stream; + if (stream != null) + ((IStream)stream).setAttachment(receiver); } public boolean isFailed() @@ -146,7 +155,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel public void failed(Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("ReleaseCallback failed", x); release(); } @@ -156,4 +165,60 @@ public class HttpChannelOverHTTP2 extends HttpChannel return InvocationType.NON_BLOCKING; } } + + private class Listener implements Stream.Listener + { + @Override + public void onNewStream(Stream stream) + { + setStream(stream); + } + + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + receiver.onHeaders(stream, frame); + } + + @Override + public Stream.Listener onPush(Stream stream, PushPromiseFrame frame) + { + return receiver.onPush(stream, frame); + } + + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + HTTP2Channel.Client channel = (HTTP2Channel.Client)((IStream)stream).getAttachment(); + channel.onData(frame, callback); + } + + @Override + public void onReset(Stream stream, ResetFrame frame) + { + // TODO: needs to call HTTP2Channel? + receiver.onReset(stream, frame); + } + + @Override + public boolean onIdleTimeout(Stream stream, Throwable x) + { + HTTP2Channel.Client channel = (HTTP2Channel.Client)((IStream)stream).getAttachment(); + return channel.onTimeout(x); + } + + @Override + public void onFailure(Stream stream, int error, String reason, Callback callback) + { + HTTP2Channel.Client channel = (HTTP2Channel.Client)((IStream)stream).getAttachment(); + channel.onFailure(new IOException(String.format("Failure %s/%s", ErrorCode.toString(error, null), reason)), callback); + } + + @Override + public void onClosed(Stream stream) + { + // TODO: needs to call HTTP2Channel? + receiver.onClosed(stream); + } + } } diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java index 7efe42ccdc6..e42529ab34d 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java @@ -1,33 +1,36 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; import java.io.IOException; import java.net.InetSocketAddress; +import java.util.List; import java.util.Map; import org.eclipse.jetty.alpn.client.ALPNClientConnectionFactory; import org.eclipse.jetty.client.AbstractHttpClientTransport; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpDestination; +import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.MultiplexConnectionPool; import org.eclipse.jetty.client.MultiplexHttpDestination; +import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.ProxyConfiguration; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http2.api.Session; @@ -92,6 +95,8 @@ public class HttpClientTransportOverHTTP2 extends AbstractHttpClientTransport client.setConnectTimeout(httpClient.getConnectTimeout()); client.setIdleTimeout(httpClient.getIdleTimeout()); client.setInputBufferSize(httpClient.getResponseBufferSize()); + client.setUseInputDirectByteBuffers(httpClient.isUseInputDirectByteBuffers()); + client.setUseOutputDirectByteBuffers(httpClient.isUseOutputDirectByteBuffers()); } addBean(client); super.doStart(); @@ -105,9 +110,16 @@ public class HttpClientTransportOverHTTP2 extends AbstractHttpClientTransport } @Override - public HttpDestination newHttpDestination(HttpDestination.Key key) + public Origin newOrigin(HttpRequest request) { - return new MultiplexHttpDestination(getHttpClient(), key); + String protocol = HttpScheme.HTTPS.is(request.getScheme()) ? "h2" : "h2c"; + return getHttpClient().createOrigin(request, new Origin.Protocol(List.of(protocol), false)); + } + + @Override + public HttpDestination newHttpDestination(Origin origin) + { + return new MultiplexHttpDestination(getHttpClient(), origin); } @Override diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java index 34da1e8feae..40e22015323 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java @@ -1,24 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; import java.nio.channels.AsynchronousCloseException; +import java.util.List; +import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -32,19 +34,27 @@ import org.eclipse.jetty.client.HttpConnection; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.SendFailure; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.CloseState; import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Session; import org.eclipse.jetty.http2.IStream; import org.eclipse.jetty.http2.api.Session; +import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Sweeper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.Sweepable { - private static final Logger LOG = Log.getLogger(HttpConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpConnection.class); private final Set activeChannels = ConcurrentHashMap.newKeySet(); private final Queue idleChannels = new ConcurrentLinkedQueue<>(); @@ -88,6 +98,45 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S return send(channel, exchange); } + public void upgrade(Map context) + { + HttpResponse response = (HttpResponse)context.get(HttpResponse.class.getName()); + HttpRequest request = (HttpRequest)response.getRequest(); + // In case of HTTP/1.1 upgrade to HTTP/2, the request is HTTP/1.1 + // (with upgrade) for a resource, and the response is HTTP/2. + // Create the implicit stream#1 so that it can receive the HTTP/2 response. + MetaData.Request metaData = new MetaData.Request(request.getMethod(), new HttpURI(request.getURI()), HttpVersion.HTTP_2, request.getHeaders()); + // We do not support upgrade requests with content, so endStream=true. + HeadersFrame frame = new HeadersFrame(metaData, null, true); + IStream stream = ((HTTP2Session)session).newStream(frame, null); + stream.updateClose(frame.isEndStream(), CloseState.Event.AFTER_SEND); + + HttpExchange exchange = request.getConversation().getExchanges().peekLast(); + HttpChannelOverHTTP2 http2Channel = acquireHttpChannel(); + activeChannels.add(http2Channel); + HttpExchange newExchange = new HttpExchange(exchange.getHttpDestination(), exchange.getRequest(), List.of()); + http2Channel.associate(newExchange); + stream.setListener(http2Channel.getStreamListener()); + http2Channel.setStream(stream); + newExchange.requestComplete(null); + newExchange.terminateRequest(); + + if (LOG.isDebugEnabled()) + LOG.debug("Upgrade completed for {}", this); + } + + @Override + protected void normalizeRequest(Request request) + { + super.normalizeRequest(request); + if (request instanceof HttpUpgrader.Factory) + { + HttpUpgrader upgrader = ((HttpUpgrader.Factory)request).newHttpUpgrader(HttpVersion.HTTP_2); + ((HttpRequest)request).getConversation().setAttribute(HttpUpgrader.class.getName(), upgrader); + upgrader.prepare((HttpRequest)request); + } + } + protected HttpChannelOverHTTP2 acquireHttpChannel() { HttpChannelOverHTTP2 channel = idleChannels.poll(); diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java index 0d91d5ea4e3..ea2e1f93a22 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; @@ -21,37 +21,39 @@ package org.eclipse.jetty.http2.client.http; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayDeque; -import java.util.Collections; import java.util.List; import java.util.Queue; import java.util.function.BiFunction; import org.eclipse.jetty.client.HttpChannel; +import org.eclipse.jetty.client.HttpConversation; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpReceiver; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Channel; import org.eclipse.jetty.http2.IStream; 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.PushPromiseFrame; import org.eclipse.jetty.http2.frames.ResetFrame; +import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.Retainable; -public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listener +public class HttpReceiverOverHTTP2 extends HttpReceiver implements HTTP2Channel.Client { - private final ContentNotifier contentNotifier = new ContentNotifier(); + private final ContentNotifier contentNotifier = new ContentNotifier(this); public HttpReceiverOverHTTP2(HttpChannel channel) { @@ -64,6 +66,12 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen return (HttpChannelOverHTTP2)super.getHttpChannel(); } + @Override + protected void receive() + { + contentNotifier.process(true); + } + @Override protected void reset() { @@ -71,8 +79,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen contentNotifier.reset(); } - @Override - public void onHeaders(Stream stream, HeadersFrame frame) + void onHeaders(Stream stream, HeadersFrame frame) { HttpExchange exchange = getHttpExchange(); if (exchange == null) @@ -94,6 +101,23 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen return; } + HttpRequest httpRequest = exchange.getRequest(); + if (HttpMethod.CONNECT.is(httpRequest.getMethod()) && httpResponse.getStatus() == HttpStatus.OK_200) + { + ClientHTTP2StreamEndPoint endPoint = new ClientHTTP2StreamEndPoint((IStream)stream); + long idleTimeout = httpRequest.getIdleTimeout(); + if (idleTimeout > 0) + endPoint.setIdleTimeout(idleTimeout); + if (LOG.isDebugEnabled()) + LOG.debug("Successful HTTP2 tunnel on {} via {}", stream, endPoint); + ((IStream)stream).setAttachment(endPoint); + HttpConversation conversation = httpRequest.getConversation(); + conversation.setAttribute(EndPoint.class.getName(), endPoint); + HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName()); + if (upgrader != null) + upgrade(upgrader, httpResponse, endPoint); + } + if (responseHeaders(exchange)) { int status = response.getStatus(); @@ -101,25 +125,48 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen if (frame.isEndStream() || informational) responseSuccess(exchange); } + else + { + if (frame.isEndStream()) + { + // There is no demand to trigger response success, so add + // a poison pill to trigger it when there will be demand. + notifyContent(exchange, new DataFrame(stream.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP); + } + } } } else // Response trailers. { HttpFields trailers = metaData.getFields(); trailers.forEach(httpResponse::trailer); + // Previous DataFrames had endStream=false, so + // add a poison pill to trigger response success + // after all normal DataFrames have been consumed. notifyContent(exchange, new DataFrame(stream.getId(), BufferUtil.EMPTY_BUFFER, true), Callback.NOOP); } } - @Override - public Stream.Listener onPush(Stream stream, PushPromiseFrame frame) + private void upgrade(HttpUpgrader upgrader, HttpResponse response, EndPoint endPoint) + { + try + { + upgrader.upgrade(response, endPoint, Callback.from(Callback.NOOP::succeeded, this::responseFailure)); + } + catch (Throwable x) + { + responseFailure(x); + } + } + + Stream.Listener onPush(Stream stream, PushPromiseFrame frame) { HttpExchange exchange = getHttpExchange(); if (exchange == null) return null; HttpRequest request = exchange.getRequest(); - MetaData.Request metaData = (MetaData.Request)frame.getMetaData(); + MetaData.Request metaData = frame.getMetaData(); HttpRequest pushRequest = (HttpRequest)getHttpDestination().getHttpClient().newRequest(metaData.getURIString()); // TODO: copy PUSH_PROMISE headers into pushRequest. @@ -130,8 +177,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen if (listener != null) { HttpChannelOverHTTP2 pushChannel = getHttpChannel().getHttpConnection().acquireHttpChannel(); - List listeners = Collections.singletonList(listener); - HttpExchange pushExchange = new HttpExchange(getHttpDestination(), pushRequest, listeners); + HttpExchange pushExchange = new HttpExchange(getHttpDestination(), pushRequest, List.of(listener)); pushChannel.associate(pushExchange); pushChannel.setStream(stream); // TODO: idle timeout ? @@ -146,7 +192,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen } @Override - public void onData(Stream stream, DataFrame frame, Callback callback) + public void onData(DataFrame frame, Callback callback) { HttpExchange exchange = getHttpExchange(); if (exchange == null) @@ -159,8 +205,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen } } - @Override - public void onReset(Stream stream, ResetFrame frame) + void onReset(Stream stream, ResetFrame frame) { HttpExchange exchange = getHttpExchange(); if (exchange == null) @@ -170,39 +215,55 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen } @Override - public boolean onIdleTimeout(Stream stream, Throwable x) + public boolean onTimeout(Throwable failure) { HttpExchange exchange = getHttpExchange(); if (exchange == null) return false; - return !exchange.abort(x); + return !exchange.abort(failure); } @Override - public void onFailure(Stream stream, int error, String reason, Callback callback) + public void onFailure(Throwable failure, Callback callback) { - responseFailure(new IOException(String.format("%s/%s", ErrorCode.toString(error, null), reason))); + responseFailure(failure); callback.succeeded(); } - @Override - public void onClosed(Stream stream) + void onClosed(Stream stream) { getHttpChannel().onStreamClosed((IStream)stream); } private void notifyContent(HttpExchange exchange, DataFrame frame, Callback callback) { - contentNotifier.offer(new DataInfo(exchange, frame, callback)); - contentNotifier.iterate(); + contentNotifier.offer(exchange, frame, callback); } - private class ContentNotifier extends IteratingCallback implements Retainable + private class ContentNotifier { private final Queue queue = new ArrayDeque<>(); + private final HttpReceiverOverHTTP2 receiver; private DataInfo dataInfo; + private boolean active; + private boolean resume; + private boolean stalled; - private void offer(DataInfo dataInfo) + private ContentNotifier(HttpReceiverOverHTTP2 receiver) + { + this.receiver = receiver; + } + + private void offer(HttpExchange exchange, DataFrame frame, Callback callback) + { + DataInfo dataInfo = new DataInfo(exchange, frame, callback); + if (LOG.isDebugEnabled()) + LOG.debug("Queueing content {}", dataInfo); + enqueue(dataInfo); + process(false); + } + + private void enqueue(DataInfo dataInfo) { synchronized (this) { @@ -210,73 +271,164 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen } } - @Override - protected Action process() + private void process(boolean resume) { - if (dataInfo != null) - { - dataInfo.callback.succeeded(); - if (dataInfo.frame.isEndStream()) - return Action.SUCCEEDED; - } + // Allow only one thread at a time. + boolean busy = active(resume); + if (LOG.isDebugEnabled()) + LOG.debug("Resuming({}) processing({}) of content", resume, !busy); + if (busy) + return; + // Process only if there is demand. synchronized (this) { - dataInfo = queue.poll(); + if (!resume && demand() <= 0) + { + if (LOG.isDebugEnabled()) + LOG.debug("Stalling processing, content available but no demand"); + active = false; + stalled = true; + return; + } } - if (dataInfo == null) - return Action.IDLE; + while (true) + { + if (dataInfo != null) + { + if (dataInfo.frame.isEndStream()) + { + receiver.responseSuccess(dataInfo.exchange); + // Return even if active, as reset() will be called later. + return; + } + } - ByteBuffer buffer = dataInfo.frame.getData(); - if (buffer.hasRemaining()) - responseContent(dataInfo.exchange, buffer, this); - else - succeeded(); - return Action.SCHEDULED; + synchronized (this) + { + dataInfo = queue.poll(); + if (LOG.isDebugEnabled()) + LOG.debug("Processing content {}", dataInfo); + if (dataInfo == null) + { + active = false; + return; + } + } + + + ByteBuffer buffer = dataInfo.frame.getData(); + Callback callback = dataInfo.callback; + if (buffer.hasRemaining()) + { + boolean proceed = receiver.responseContent(dataInfo.exchange, buffer, Callback.from(callback::succeeded, x -> fail(callback, x))); + if (!proceed) + { + // The call to responseContent() said we should + // stall, but another thread may have just resumed. + boolean stall = stall(); + if (LOG.isDebugEnabled()) + LOG.debug("Stalling({}) processing", stall); + if (stall) + return; + } + } + else + { + callback.succeeded(); + } + } } - @Override - public void retain() + private boolean active(boolean resume) { - Callback callback = dataInfo.callback; - if (callback instanceof Retainable) - ((Retainable)callback).retain(); + synchronized (this) + { + if (active) + { + // There is a thread in process(), + // but it may be about to exit, so + // remember "resume" to signal the + // processing thread to continue. + if (resume) + this.resume = true; + return true; + } + + // If there is no demand (i.e. stalled + // and not resuming) then don't process. + if (stalled && !resume) + return true; + + // Start processing. + active = true; + stalled = false; + return false; + } } - @Override - protected void onCompleteSuccess() + /** + * Called when there is no demand, this method checks whether + * the processing should really stop or it should continue. + * + * @return true to stop processing, false to continue processing + */ + private boolean stall() { - responseSuccess(dataInfo.exchange); + synchronized (this) + { + if (resume) + { + // There was no demand, but another thread + // just demanded, continue processing. + resume = false; + return false; + } + + // There is no demand, stop processing. + active = false; + stalled = true; + return true; + } } - @Override - protected void onCompleteFailure(Throwable failure) + private void reset() { - dataInfo.callback.failed(failure); - responseFailure(failure); - } - - @Override - public boolean reset() - { - queue.clear(); dataInfo = null; - return super.reset(); + synchronized (this) + { + queue.clear(); + active = false; + resume = false; + stalled = false; + } } - } - private static class DataInfo - { - private final HttpExchange exchange; - private final DataFrame frame; - private final Callback callback; - - private DataInfo(HttpExchange exchange, DataFrame frame, Callback callback) + private void fail(Callback callback, Throwable failure) { - this.exchange = exchange; - this.frame = frame; - this.callback = callback; + callback.failed(failure); + receiver.responseFailure(failure); + } + + private class DataInfo + { + private final HttpExchange exchange; + private final DataFrame frame; + private final Callback callback; + + private DataInfo(HttpExchange exchange, DataFrame frame, Callback callback) + { + this.exchange = exchange; + this.frame = frame; + this.callback = callback; + } + + @Override + public String toString() + { + return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), frame); + } } } } diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java index e1078ad0976..b3aeacaa3de 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java @@ -1,43 +1,49 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; import java.net.URI; +import java.util.function.Consumer; import java.util.function.Supplier; import org.eclipse.jetty.client.HttpContent; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpSender; +import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; -import org.eclipse.jetty.http2.IStream; 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.util.Callback; import org.eclipse.jetty.util.Promise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpSenderOverHTTP2 extends HttpSender { + private static final Logger LOG = LoggerFactory.getLogger(HttpSenderOverHTTP2.class); + public HttpSenderOverHTTP2(HttpChannelOverHTTP2 channel) { super(channel); @@ -53,23 +59,44 @@ public class HttpSenderOverHTTP2 extends HttpSender protected void sendHeaders(HttpExchange exchange, final HttpContent content, final Callback callback) { HttpRequest request = exchange.getRequest(); - String path = relativize(request.getPath()); - HttpURI uri = HttpURI.createHttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null); - MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders()); + boolean isTunnel = HttpMethod.CONNECT.is(request.getMethod()); + MetaData.Request metaData; + if (isTunnel) + { + String upgradeProtocol = request.getUpgradeProtocol(); + if (upgradeProtocol == null) + { + metaData = new MetaData.ConnectRequest((String)null, new HostPortHttpField(request.getPath()), null, request.getHeaders(), null); + } + else + { + HostPortHttpField authority = new HostPortHttpField(request.getHost(), request.getPort()); + metaData = new MetaData.ConnectRequest(request.getScheme(), authority, request.getPath(), request.getHeaders(), upgradeProtocol); + } + } + else + { + String path = relativize(request.getPath()); + HttpURI uri = HttpURI.createHttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null); + metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders()); + } Supplier trailerSupplier = request.getTrailers(); metaData.setTrailerSupplier(trailerSupplier); HeadersFrame headersFrame; Promise promise; - if (content.hasContent()) + if (isTunnel) { headersFrame = new HeadersFrame(metaData, null, false); - promise = new HeadersPromise(request, callback) + promise = new HeadersPromise(request, callback, stream -> callback.succeeded()); + } + else + { + if (content.hasContent()) { - @Override - public void succeeded(Stream stream) + headersFrame = new HeadersFrame(metaData, null, false); + promise = new HeadersPromise(request, callback, stream -> { - super.succeeded(stream); if (expects100Continue(request)) { // Don't send the content yet. @@ -84,26 +111,21 @@ public class HttpSenderOverHTTP2 extends HttpSender else callback.succeeded(); } - } - }; - } - else - { - HttpFields trailers = trailerSupplier == null ? null : trailerSupplier.get(); - boolean endStream = trailers == null || trailers.size() == 0; - headersFrame = new HeadersFrame(metaData, null, endStream); - promise = new HeadersPromise(request, callback) + }); + } + else { - @Override - public void succeeded(Stream stream) + HttpFields trailers = trailerSupplier == null ? null : trailerSupplier.get(); + boolean endStream = trailers == null || trailers.size() <= 0; + headersFrame = new HeadersFrame(metaData, null, endStream); + promise = new HeadersPromise(request, callback, stream -> { - super.succeeded(stream); if (endStream) callback.succeeded(); else sendTrailers(stream, trailers, callback); - } - }; + }); + } } // TODO optimize the send of HEADERS and DATA frames. HttpChannelOverHTTP2 channel = getHttpChannel(); @@ -168,26 +190,26 @@ public class HttpSenderOverHTTP2 extends HttpSender stream.headers(trailersFrame, callback); } - private class HeadersPromise implements Promise + private static class HeadersPromise implements Promise { private final HttpRequest request; private final Callback callback; + private final Consumer succeed; - private HeadersPromise(HttpRequest request, Callback callback) + private HeadersPromise(HttpRequest request, Callback callback, Consumer succeed) { this.request = request; this.callback = callback; + this.succeed = succeed; } @Override public void succeeded(Stream stream) { - HttpChannelOverHTTP2 channel = getHttpChannel(); - channel.setStream(stream); - ((IStream)stream).setAttachment(channel); long idleTimeout = request.getIdleTimeout(); if (idleTimeout >= 0) stream.setIdleTimeout(idleTimeout); + succeed.accept(stream); } @Override diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java index 75790060d48..197e4e5ec20 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java index a0225ae4cd4..4cdf86407b6 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; @@ -112,7 +112,7 @@ public class DirectHTTP2OverTLSTest private void configureSslContextFactory(SslContextFactory sslContextFactory) { - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setUseCipherSuitesOrder(true); sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/EmptyServerHandler.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/EmptyServerHandler.java index 595f77ca933..05aa2344eb5 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/EmptyServerHandler.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/EmptyServerHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; @@ -26,10 +26,10 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; -public class EmptyServerHandler extends AbstractHandler.ErrorDispatchHandler +public class EmptyServerHandler extends AbstractHandler { @Override - protected final void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public final void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { jettyRequest.setHandled(true); service(target, jettyRequest, request, response); diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java index 32ccb0701cc..aeac4cc8a37 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; @@ -43,6 +43,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpProxy; +import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpMethod; @@ -61,6 +62,8 @@ import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.hpack.HpackException; +import org.eclipse.jetty.http2.parser.RateControl; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory; import org.eclipse.jetty.io.ByteBufferPool; @@ -74,6 +77,7 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -96,6 +100,8 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest httpClient.setExecutor(executor); httpClient.setConnectTimeout(13); httpClient.setIdleTimeout(17); + httpClient.setUseInputDirectByteBuffers(false); + httpClient.setUseOutputDirectByteBuffers(false); httpClient.start(); @@ -105,6 +111,8 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest assertSame(httpClient.getByteBufferPool(), http2Client.getByteBufferPool()); assertEquals(httpClient.getConnectTimeout(), http2Client.getConnectTimeout()); assertEquals(httpClient.getIdleTimeout(), http2Client.getIdleTimeout()); + assertEquals(httpClient.isUseInputDirectByteBuffers(), http2Client.isUseInputDirectByteBuffers()); + assertEquals(httpClient.isUseOutputDirectByteBuffers(), http2Client.isUseOutputDirectByteBuffers()); httpClient.stop(); @@ -194,7 +202,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest .onRequestBegin(request -> { if (request.getVersion() != HttpVersion.HTTP_2) - request.abort(new Exception("Not a HTTP/2 request")); + request.abort(new Exception("Not an HTTP/2 request")); }) .send(); @@ -341,7 +349,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest }); int proxyPort = connector.getLocalPort(); - client.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyPort)); + client.getProxyConfiguration().getProxies().add(new HttpProxy(new Origin.Address("localhost", proxyPort), false, new Origin.Protocol(List.of("h2c"), false))); int serverPort = proxyPort + 1; // Any port will do, just not the same as the proxy. ContentResponse response = client.newRequest("localhost", serverPort) @@ -461,21 +469,35 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest @Override public void onPreface() { - // Server's preface. - generator.control(lease, new SettingsFrame(new HashMap<>(), false)); - // Reply to client's SETTINGS. - generator.control(lease, new SettingsFrame(new HashMap<>(), true)); - writeFrames(); + try + { + // Server's preface. + generator.control(lease, new SettingsFrame(new HashMap<>(), false)); + // Reply to client's SETTINGS. + generator.control(lease, new SettingsFrame(new HashMap<>(), true)); + writeFrames(); + } + catch (HpackException x) + { + x.printStackTrace(); + } } @Override public void onHeaders(HeadersFrame request) { - // Response. - MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); - HeadersFrame response = new HeadersFrame(request.getStreamId(), metaData, null, true); - generator.control(lease, response); - writeFrames(); + try + { + // Response. + MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields()); + HeadersFrame response = new HeadersFrame(request.getStreamId(), metaData, null, true); + generator.control(lease, response); + writeFrames(); + } + catch (HpackException x) + { + x.printStackTrace(); + } } private void writeFrames() @@ -494,7 +516,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest x.printStackTrace(); } } - }, 4096, 8192); + }, 4096, 8192, RateControl.NO_RATE_CONTROL); parser.init(UnaryOperator.identity()); byte[] bytes = new byte[1024]; @@ -567,6 +589,8 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest @Override public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) { + // Disable checks for invalid headers. + ((HTTP2Session)stream.getSession()).getGenerator().setValidateHpackEncoding(false); // Produce an invalid HPACK block by adding a request pseudo-header to the response. HttpFields fields = new HttpFields(); fields.put(":method", "get"); @@ -595,6 +619,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest @Disabled @Test + @Tag("external") public void testExternalServer() throws Exception { ClientConnector clientConnector = new ClientConnector(); diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java index 9dd125b626a..7cbfe76b05d 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; @@ -159,7 +159,6 @@ public class MaxConcurrentStreamsTest extends AbstractTest } }); - String scheme = "http"; String host = "localhost"; int port = connector.getLocalPort(); @@ -212,15 +211,15 @@ public class MaxConcurrentStreamsTest extends AbstractTest // This request will be queued and establish the connection, // which will trigger the send of the second request. - ContentResponse response1 = client.newRequest(host, port) - .path("/1") - .timeout(5, TimeUnit.SECONDS) - .send(); + var request = client.newRequest(host, port) + .path("/1") + .timeout(5, TimeUnit.SECONDS); + ContentResponse response = request.send(); - assertEquals(HttpStatus.OK_200, response1.getStatus()); + assertEquals(HttpStatus.OK_200, response.getStatus()); assertTrue(latch.await(5, TimeUnit.SECONDS), failures.toString()); assertEquals(2, connections.get()); - HttpDestination destination = (HttpDestination)client.getDestination(scheme, host, port); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool(); assertEquals(2, connectionPool.getConnectionCount()); } @@ -253,16 +252,15 @@ public class MaxConcurrentStreamsTest extends AbstractTest // Send the request in excess. CountDownLatch latch = new CountDownLatch(1); String path = "/excess"; - client.newRequest("localhost", connector.getLocalPort()) - .path(path) - .send(result -> - { - if (result.getResponse().getStatus() == HttpStatus.OK_200) - latch.countDown(); - }); + var request = client.newRequest("localhost", connector.getLocalPort()).path(path); + request.send(result -> + { + if (result.getResponse().getStatus() == HttpStatus.OK_200) + latch.countDown(); + }); // The last exchange should remain in the queue. - HttpDestination destination = (HttpDestination)client.getDestination("http", "localhost", connector.getLocalPort()); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); assertEquals(1, destination.getHttpExchanges().size()); assertEquals(path, destination.getHttpExchanges().peek().getRequest().getPath()); diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/PushedResourcesTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/PushedResourcesTest.java index 9f7622aec6c..9d958fb59c4 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/PushedResourcesTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/PushedResourcesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/RequestTrailersTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/RequestTrailersTest.java index 46778f30d9a..a94a2f88f61 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/RequestTrailersTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/RequestTrailersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/ResponseTrailerTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/ResponseTrailerTest.java index 0b8d6a92c59..8525f2a73fc 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/ResponseTrailerTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/ResponseTrailerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.client.http; diff --git a/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties b/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties index 34929219c9d..1cec8b3203e 100644 --- a/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.client.LEVEL=DEBUG org.eclipse.jetty.http2.hpack.LEVEL=INFO diff --git a/jetty-http2/http2-http-client-transport/src/test/resources/keystore.jks b/jetty-http2/http2-http-client-transport/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-http2/http2-http-client-transport/src/test/resources/keystore.jks and /dev/null differ diff --git a/jetty-http2/http2-http-client-transport/src/test/resources/keystore.p12 b/jetty-http2/http2-http-client-transport/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..925bae6c650 Binary files /dev/null and b/jetty-http2/http2-http-client-transport/src/test/resources/keystore.p12 differ diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 702a6204ab0..af5742f74e1 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -55,6 +55,10 @@ jetty-server ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty jetty-servlet @@ -73,6 +77,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml b/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml index 16984b9bbdf..3110c911d9d 100644 --- a/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml +++ b/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml @@ -1,9 +1,6 @@ - - - @@ -12,6 +9,12 @@ + + + + + + diff --git a/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml b/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml index 08e5d62911f..e820dd186ff 100644 --- a/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml +++ b/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml @@ -1,9 +1,6 @@ - - - @@ -11,6 +8,12 @@ + + + + + + diff --git a/jetty-http2/http2-server/src/main/config/modules/http2.mod b/jetty-http2/http2-server/src/main/config/modules/http2.mod index 2ca6596e578..c33beaf2c25 100644 --- a/jetty-http2/http2-server/src/main/config/modules/http2.mod +++ b/jetty-http2/http2-server/src/main/config/modules/http2.mod @@ -29,3 +29,9 @@ etc/jetty-http2.xml ## Initial session receive window (client to server) # jetty.http2.initialSessionRecvWindow=1048576 + +## The max number of keys in all SETTINGS frames +# jetty.http2.maxSettingsKeys=64 + +## Max number of bad frames and pings per second +# jetty.http2.rateControl.maxEventsPerSecond=20 diff --git a/jetty-http2/http2-server/src/main/config/modules/http2c.mod b/jetty-http2/http2-server/src/main/config/modules/http2c.mod index b109a8c4ce8..cac69f065ad 100644 --- a/jetty-http2/http2-server/src/main/config/modules/http2c.mod +++ b/jetty-http2/http2-server/src/main/config/modules/http2c.mod @@ -24,3 +24,9 @@ etc/jetty-http2c.xml ## Initial stream receive window (client to server) # jetty.http2c.initialStreamRecvWindow=65535 + +## The max number of keys in all SETTINGS frames +# jetty.http2.maxSettingsKeys=64 + +## Max number of bad frames and pings per second +# jetty.http2.rateControl.maxEventsPerSecond=20 diff --git a/jetty-http2/http2-server/src/main/java/module-info.java b/jetty-http2/http2-server/src/main/java/module-info.java index 329d1d4efda..4bce9a0b782 100644 --- a/jetty-http2/http2-server/src/main/java/module-info.java +++ b/jetty-http2/http2-server/src/main/java/module-info.java @@ -1,28 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.http2.server { exports org.eclipse.jetty.http2.server; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.http2.common; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.http2.common; + requires transitive org.eclipse.jetty.server; + requires org.slf4j; } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java index a7492e814f8..50e69c0ca04 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -24,17 +24,22 @@ import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.http2.BufferingFlowControlStrategy; import org.eclipse.jetty.http2.FlowControlStrategy; import org.eclipse.jetty.http2.HTTP2Connection; +import org.eclipse.jetty.http2.ISession; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.api.server.ServerSessionListener; import org.eclipse.jetty.http2.frames.Frame; import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.http2.parser.RateControl; import org.eclipse.jetty.http2.parser.ServerParser; +import org.eclipse.jetty.http2.parser.WindowRateControl; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.AbstractConnectionFactory; @@ -44,6 +49,7 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.Dumpable; +import org.eclipse.jetty.util.component.Graceful; import org.eclipse.jetty.util.component.LifeCycle; @ManagedObject @@ -58,8 +64,12 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne private int maxHeaderBlockFragment = 0; private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; + private boolean connectProtocolEnabled = true; + private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(20); private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); private long streamIdleTimeout; + private boolean useInputDirectByteBuffers; + private boolean useOutputDirectByteBuffers; public AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration) { @@ -78,6 +88,8 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne this.httpConfiguration = Objects.requireNonNull(httpConfiguration); addBean(httpConfiguration); setInputBufferSize(Frame.DEFAULT_MAX_LENGTH + Frame.HEADER_LENGTH); + setUseInputDirectByteBuffers(httpConfiguration.isUseInputDirectByteBuffers()); + setUseOutputDirectByteBuffers(httpConfiguration.isUseOutputDirectByteBuffers()); } @ManagedAttribute("The HPACK dynamic table maximum size") @@ -178,6 +190,57 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne this.maxSettingsKeys = maxSettingsKeys; } + @ManagedAttribute("Whether CONNECT requests supports a protocol") + public boolean isConnectProtocolEnabled() + { + return connectProtocolEnabled; + } + + public void setConnectProtocolEnabled(boolean connectProtocolEnabled) + { + this.connectProtocolEnabled = connectProtocolEnabled; + } + + /** + * @return the factory that creates RateControl objects + */ + public RateControl.Factory getRateControlFactory() + { + return rateControlFactory; + } + + /** + *

      Sets the factory that creates a per-connection RateControl object.

      + * + * @param rateControlFactory the factory that creates RateControl objects + */ + public void setRateControlFactory(RateControl.Factory rateControlFactory) + { + this.rateControlFactory = Objects.requireNonNull(rateControlFactory); + } + + @ManagedAttribute("Whether to use direct ByteBuffers for reading") + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + @ManagedAttribute("Whether to use direct ByteBuffers for writing") + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + public HttpConfiguration getHttpConfiguration() { return httpConfiguration; @@ -192,6 +255,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne if (maxConcurrentStreams >= 0) settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams); settings.put(SettingsFrame.MAX_HEADER_LIST_SIZE, getHttpConfiguration().getRequestHeaderSize()); + settings.put(SettingsFrame.ENABLE_CONNECT_PROTOCOL, isConnectProtocolEnabled() ? 1 : 0); return settings; } @@ -200,7 +264,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne { ServerSessionListener listener = newSessionListener(connector, endPoint); - Generator generator = new Generator(connector.getByteBufferPool(), getMaxDynamicTableSize(), getMaxHeaderBlockFragment()); + Generator generator = new Generator(connector.getByteBufferPool(), isUseOutputDirectByteBuffers(), getMaxDynamicTableSize(), getMaxHeaderBlockFragment()); FlowControlStrategy flowControl = getFlowControlStrategyFactory().newFlowControlStrategy(); HTTP2ServerSession session = new HTTP2ServerSession(connector.getScheduler(), endPoint, generator, listener, flowControl); session.setMaxLocalStreams(getMaxConcurrentStreams()); @@ -210,46 +274,51 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne // the typical case is that the connection will be busier and the // stream idle timeout will expire earlier than the connection's. long streamIdleTimeout = getStreamIdleTimeout(); - if (streamIdleTimeout <= 0) - streamIdleTimeout = endPoint.getIdleTimeout(); - session.setStreamIdleTimeout(streamIdleTimeout); + if (streamIdleTimeout > 0) + session.setStreamIdleTimeout(streamIdleTimeout); session.setInitialSessionRecvWindow(getInitialSessionRecvWindow()); session.setWriteThreshold(getHttpConfiguration().getOutputBufferSize()); + session.setConnectProtocolEnabled(isConnectProtocolEnabled()); - ServerParser parser = newServerParser(connector, session); + ServerParser parser = newServerParser(connector, session, getRateControlFactory().newRateControl(endPoint)); parser.setMaxFrameLength(getMaxFrameLength()); parser.setMaxSettingsKeys(getMaxSettingsKeys()); HTTP2Connection connection = new HTTP2ServerConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener); - connection.addListener(sessionContainer); + connection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers()); + connection.setUseOutputDirectByteBuffers(isUseOutputDirectByteBuffers()); + connection.addEventListener(sessionContainer); return configure(connection, connector, endPoint); } protected abstract ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint); - protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener) + protected ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl) { - return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize()); + return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize(), rateControl); } @ManagedObject("The container of HTTP/2 sessions") - public static class HTTP2SessionContainer implements Connection.Listener, Dumpable + public static class HTTP2SessionContainer implements Connection.Listener, Graceful, Dumpable { - private final Set sessions = ConcurrentHashMap.newKeySet(); + private final Set sessions = ConcurrentHashMap.newKeySet(); + private final AtomicReference> shutdown = new AtomicReference<>(); @Override public void onOpened(Connection connection) { - Session session = ((HTTP2Connection)connection).getSession(); + ISession session = ((HTTP2Connection)connection).getSession(); sessions.add(session); LifeCycle.start(session); + if (isShutdown()) + shutdown(session); } @Override public void onClosed(Connection connection) { - Session session = ((HTTP2Connection)connection).getSession(); + ISession session = ((HTTP2Connection)connection).getSession(); if (sessions.remove(session)) LifeCycle.stop(session); } @@ -265,6 +334,39 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne return sessions.size(); } + @Override + public CompletableFuture shutdown() + { + CompletableFuture result = new CompletableFuture<>(); + if (shutdown.compareAndSet(null, result)) + { + CompletableFuture.allOf(sessions.stream().map(this::shutdown).toArray(CompletableFuture[]::new)) + .whenComplete((v, x) -> + { + if (x == null) + result.complete(v); + else + result.completeExceptionally(x); + }); + return result; + } + else + { + return shutdown.get(); + } + } + + @Override + public boolean isShutdown() + { + return shutdown.get() != null; + } + + private CompletableFuture shutdown(ISession session) + { + return session.shutdown(); + } + @Override public String dump() { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java index cc0b9925311..677d65f3d93 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -28,8 +28,8 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * HTTP2 Clear Text Connection factory. @@ -39,14 +39,14 @@ import org.eclipse.jetty.util.log.Logger; *

      *

      If used in combination with a {@link HttpConnectionFactory} as the * default protocol, this factory can support the non-standard direct - * update mechanism, where a HTTP1 request of the form "PRI * HTTP/2.0" - * is used to trigger a switch to a HTTP2 connection. This approach + * update mechanism, where an HTTP1 request of the form "PRI * HTTP/2.0" + * is used to trigger a switch to an HTTP2 connection. This approach * allows a single port to accept either HTTP/1 or HTTP/2 direct * connections. */ public class HTTP2CServerConnectionFactory extends HTTP2ServerConnectionFactory implements ConnectionFactory.Upgrading { - private static final Logger LOG = Log.getLogger(HTTP2CServerConnectionFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2CServerConnectionFactory.class); public HTTP2CServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration) { @@ -74,13 +74,13 @@ public class HTTP2CServerConnectionFactory extends HTTP2ServerConnectionFactory public Connection upgradeConnection(Connector connector, EndPoint endPoint, Request request, HttpFields response101) throws BadMessageException { if (LOG.isDebugEnabled()) - LOG.debug("{} upgraded {}{}", this, request.toString(), request.getFields()); + LOG.debug("{} upgrading {}{}{}", this, request, System.lineSeparator(), request.getFields()); if (request.getContentLength() > 0) return null; HTTP2ServerConnection connection = (HTTP2ServerConnection)newConnection(connector, endPoint); - if (connection.upgrade(request)) + if (connection.upgrade(request, response101)) return connection; return null; } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java index 331696417d2..515f733dd16 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java @@ -1,26 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; import java.io.Closeable; import java.io.IOException; -import java.nio.ByteBuffer; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Base64; @@ -33,11 +32,14 @@ import java.util.concurrent.atomic.AtomicLong; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.MetaData.Request; import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Channel; import org.eclipse.jetty.http2.HTTP2Connection; import org.eclipse.jetty.http2.ISession; import org.eclipse.jetty.http2.IStream; @@ -52,7 +54,6 @@ import org.eclipse.jetty.http2.frames.SettingsFrame; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.http2.parser.SettingsBodyParser; import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; @@ -61,10 +62,10 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.CountingCallback; import org.eclipse.jetty.util.TypeUtil; -public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo +public class HTTP2ServerConnection extends HTTP2Connection { /** - * @param protocol A HTTP2 protocol variant + * @param protocol An HTTP2 protocol variant * @return True if the protocol version is supported */ public static boolean isSupportedProtocol(String protocol) @@ -86,7 +87,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection return false; } } - + private final Queue channels = new ArrayDeque<>(); private final List upgradeFrames = new ArrayList<>(); private final AtomicLong totalRequests = new AtomicLong(); @@ -130,21 +131,14 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection this.recycleHttpChannels = recycleHttpChannels; } - @Override - public void onUpgradeTo(ByteBuffer buffer) - { - if (LOG.isDebugEnabled()) - LOG.debug("HTTP2 onUpgradeTo {} {}", this, BufferUtil.toDetailString(buffer)); - setInputBuffer(buffer); - } - @Override public void onOpen() { - notifyAccept(getSession()); + ISession session = getSession(); + notifyAccept(session); for (Frame frame : upgradeFrames) { - getSession().onFrame(frame); + session.onFrame(frame); } super.onOpen(); produce(); @@ -176,10 +170,10 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { if (LOG.isDebugEnabled()) LOG.debug("Processing {} on {}", frame, stream); - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); + HTTP2Channel.Server channel = (HTTP2Channel.Server)stream.getAttachment(); if (channel != null) { - Runnable task = channel.onRequestContent(frame, callback); + Runnable task = channel.onData(frame, callback); if (task != null) offerTask(task, false); } @@ -193,10 +187,10 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { if (LOG.isDebugEnabled()) LOG.debug("Processing trailers {} on {}", frame, stream); - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); + HTTP2Channel.Server channel = (HTTP2Channel.Server)stream.getAttachment(); if (channel != null) { - Runnable task = channel.onRequestTrailers(frame); + Runnable task = channel.onTrailer(frame); if (task != null) offerTask(task, false); } @@ -204,8 +198,8 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection public boolean onStreamTimeout(IStream stream, Throwable failure) { - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); - boolean result = channel != null && channel.onStreamTimeout(failure, task -> offerTask(task, true)); + HTTP2Channel.Server channel = (HTTP2Channel.Server)stream.getAttachment(); + boolean result = channel != null && channel.onTimeout(failure, task -> offerTask(task, true)); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", stream, failure); return result; @@ -215,7 +209,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { if (LOG.isDebugEnabled()) LOG.debug("Processing failure on {}: {}", stream, failure); - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); + HTTP2Channel.Server channel = (HTTP2Channel.Server)stream.getAttachment(); if (channel != null) { Runnable task = channel.onFailure(failure, callback); @@ -233,11 +227,11 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection ISession session = getSession(); // Compute whether all requests are idle. boolean result = session.getStreams().stream() - .map(stream -> (IStream)stream) - .map(stream -> (HttpChannelOverHTTP2)stream.getAttachment()) - .filter(Objects::nonNull) - .map(HttpChannelOverHTTP2::isRequestIdle) - .reduce(true, Boolean::logicalAnd); + .map(stream -> (IStream)stream) + .map(stream -> (HTTP2Channel.Server)stream.getAttachment()) + .filter(Objects::nonNull) + .map(HTTP2Channel.Server::isIdle) + .reduce(true, Boolean::logicalAnd); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", session, failure); return result; @@ -287,6 +281,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection HttpTransportOverHTTP2 transport = new HttpTransportOverHTTP2(connector, this); transport.setStream(stream); channel = newServerHttpChannelOverHTTP2(connector, httpConfig, transport); + channel.setUseOutputDirectByteBuffers(isUseOutputDirectByteBuffers()); if (LOG.isDebugEnabled()) LOG.debug("Creating channel {} for {}", channel, this); } @@ -325,7 +320,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection } } - public boolean upgrade(Request request) + public boolean upgrade(Request request, HttpFields responseFields) { if (HttpMethod.PRI.is(request.getMethod())) { @@ -340,7 +335,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection final byte[] settings = Base64.getUrlDecoder().decode(value == null ? "" : value); if (LOG.isDebugEnabled()) - LOG.debug("{} settings {}", this, TypeUtil.toHexString(settings)); + LOG.debug("{} {}: {}", this, HttpHeader.HTTP2_SETTINGS, TypeUtil.toHexString(settings)); SettingsFrame settingsFrame = SettingsBodyParser.parseBody(BufferUtil.toBuffer(settings)); if (settingsFrame == null) @@ -349,11 +344,18 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection throw new BadMessageException(); } + responseFields.put(HttpHeader.UPGRADE, "h2c"); + responseFields.put(HttpHeader.CONNECTION, "Upgrade"); + getParser().standardUpgrade(); + // We fake that we received a client preface, so that we can send the + // server preface as the first HTTP/2 frame as required by the spec. + // When the client sends the real preface, the parser won't notify it. upgradeFrames.add(new PrefaceFrame()); + // This is the settings from the HTTP2-Settings header. upgradeFrames.add(settingsFrame); - // Remember the request to send a response from onOpen(). + // Remember the request to send a response. upgradeFrames.add(new HeadersFrame(1, new Request(request), null, true)); } return true; @@ -373,15 +375,26 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection return super.onRequest(frame); } + @Override + protected boolean checkAndPrepareUpgrade() + { + return isTunnel() && getHttpTransport().prepareUpgrade(); + } + @Override public void onCompleted() { - totalResponses.incrementAndGet(); super.onCompleted(); - if (!getStream().isReset()) + totalResponses.incrementAndGet(); + if (!getStream().isReset() && !isTunnel()) recycle(); } + private boolean isTunnel() + { + return HttpMethod.CONNECT.is(getRequest().getMethod()) && getResponse().getStatus() == HttpStatus.OK_200; + } + @Override public void recycle() { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java index 7e45753e5c0..cd116fecc43 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -40,12 +40,12 @@ import org.eclipse.jetty.server.NegotiatingServerConnection.CipherDiscriminator; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionFactory implements CipherDiscriminator { - private static final Logger LOG = Log.getLogger(HTTP2ServerConnectionFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2ServerConnectionFactory.class); public HTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration) { @@ -102,6 +102,15 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF return this; } + @Override + public void onBeforeData(Stream stream) + { + // Do not notify DATA frame listeners until demanded. + // This allows CONNECT requests with pseudo header :protocol + // (e.g. WebSocket over HTTP/2) to buffer DATA frames + // until they upgrade and are ready to process them. + } + @Override public boolean onIdleTimeout(Session session) { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java index 9e657a9b464..1660a244a85 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -39,13 +39,13 @@ import org.eclipse.jetty.http2.generator.Generator; import org.eclipse.jetty.http2.parser.ServerParser; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Listener { - private static final Logger LOG = Log.getLogger(HTTP2ServerSession.class); + private static final Logger LOG = LoggerFactory.getLogger(HTTP2ServerSession.class); private final ServerSessionListener listener; @@ -104,13 +104,30 @@ public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Lis } else { - stream = createRemoteStream(streamId); - if (stream != null) + if (isClosed()) { - onStreamOpened(stream); - stream.process(frame, Callback.NOOP); - Stream.Listener listener = notifyNewStream(stream, frame); - stream.setListener(listener); + reset(new ResetFrame(streamId, ErrorCode.REFUSED_STREAM_ERROR.code), Callback.NOOP); + } + else + { + stream = createRemoteStream(streamId, (MetaData.Request)metaData); + if (stream != null) + { + onStreamOpened(stream); + + if (metaData instanceof MetaData.ConnectRequest) + { + if (!isConnectProtocolEnabled() && ((MetaData.ConnectRequest)metaData).getProtocol() != null) + { + stream.reset(new ResetFrame(streamId, ErrorCode.PROTOCOL_ERROR.code), Callback.NOOP); + return; + } + } + + stream.process(frame, Callback.NOOP); + Stream.Listener listener = notifyNewStream(stream, frame); + stream.setListener(listener); + } } } } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index 617025a5465..f83e43f985f 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -32,6 +32,7 @@ import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.PreEncodedHttpField; +import org.eclipse.jetty.http2.HTTP2Channel; import org.eclipse.jetty.http2.IStream; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.frames.DataFrame; @@ -44,17 +45,18 @@ import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpInput; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, WriteFlusher.Listener +public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, WriteFlusher.Listener, HTTP2Channel.Server { - private static final Logger LOG = Log.getLogger(HttpChannelOverHTTP2.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpChannelOverHTTP2.class); private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); private static final HttpField POWERED_BY = new PreEncodedHttpField(HttpHeader.X_POWERED_BY, HttpConfiguration.SERVER_VERSION); private boolean _expect100Continue; private boolean _delayedUntilContent; + private boolean _useOutputDirectByteBuffers; public HttpChannelOverHTTP2(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransportOverHTTP2 transport) { @@ -66,6 +68,17 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ return getHttpTransport().getStream(); } + @Override + public boolean isUseOutputDirectByteBuffers() + { + return _useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + _useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + @Override public boolean isExpecting100Continue() { @@ -126,17 +139,22 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ onRequestComplete(); } + boolean connect = request instanceof MetaData.ConnectRequest; _delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() && - !endStream && !_expect100Continue; + !endStream && !_expect100Continue && !connect; + + // Delay the demand of DATA frames for CONNECT with :protocol. + if (!connect || request.getProtocol() == null) + getStream().demand(1); if (LOG.isDebugEnabled()) { Stream stream = getStream(); LOG.debug("HTTP2 Request #{}/{}, delayed={}:{}{} {} {}{}{}", - stream.getId(), Integer.toHexString(stream.getSession().hashCode()), - _delayedUntilContent, System.lineSeparator(), - request.getMethod(), request.getURI(), request.getHttpVersion(), - System.lineSeparator(), fields); + stream.getId(), Integer.toHexString(stream.getSession().hashCode()), + _delayedUntilContent, System.lineSeparator(), + request.getMethod(), request.getURI(), request.getHttpVersion(), + System.lineSeparator(), fields); } return _delayedUntilContent ? null : this; @@ -166,9 +184,9 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ { Stream stream = getStream(); LOG.debug("HTTP2 PUSH Request #{}/{}:{}{} {} {}{}{}", - stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), - request.getMethod(), request.getURI(), request.getHttpVersion(), - System.lineSeparator(), request.getFields()); + stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), + request.getMethod(), request.getURI(), request.getHttpVersion(), + System.lineSeparator(), request.getFields()); } return this; @@ -208,11 +226,17 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ { Stream stream = getStream(); LOG.debug("HTTP2 Commit Response #{}/{}:{}{} {} {}{}{}", - stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), info.getHttpVersion(), info.getStatus(), info.getReason(), - System.lineSeparator(), info.getFields()); + stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), info.getHttpVersion(), info.getStatus(), info.getReason(), + System.lineSeparator(), info.getFields()); } } + @Override + public Runnable onData(DataFrame frame, Callback callback) + { + return onRequestContent(frame, callback); + } + public Runnable onRequestContent(DataFrame frame, final Callback callback) { Stream stream = getStream(); @@ -260,11 +284,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ if (LOG.isDebugEnabled()) { LOG.debug("HTTP2 Request #{}/{}: {} bytes of {} content, handle: {}", - stream.getId(), - Integer.toHexString(stream.getSession().hashCode()), - length, - endStream ? "last" : "some", - handle); + stream.getId(), + Integer.toHexString(stream.getSession().hashCode()), + length, + endStream ? "last" : "some", + handle); } boolean wasDelayed = _delayedUntilContent; @@ -272,7 +296,8 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ return handle || wasDelayed ? this : null; } - public Runnable onRequestTrailers(HeadersFrame frame) + @Override + public Runnable onTrailer(HeadersFrame frame) { HttpFields trailers = frame.getMetaData().getFields(); if (trailers.size() > 0) @@ -282,8 +307,8 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ { Stream stream = getStream(); LOG.debug("HTTP2 Request #{}/{}, trailers:{}{}", - stream.getId(), Integer.toHexString(stream.getSession().hashCode()), - System.lineSeparator(), trailers); + stream.getId(), Integer.toHexString(stream.getSession().hashCode()), + System.lineSeparator(), trailers); } boolean handle = onRequestComplete(); @@ -293,17 +318,19 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ return handle || wasDelayed ? this : null; } - public boolean isRequestIdle() + @Override + public boolean isIdle() { return getState().isIdle(); } - public boolean onStreamTimeout(Throwable failure, Consumer consumer) + @Override + public boolean onTimeout(Throwable failure, Consumer consumer) { final boolean delayed = _delayedUntilContent; _delayedUntilContent = false; - boolean result = isRequestIdle(); + boolean result = isIdle(); if (result) consumeInput(); @@ -317,6 +344,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ return result; } + @Override public Runnable onFailure(Throwable failure, Callback callback) { getHttpTransport().onStreamFailure(failure); @@ -368,6 +396,18 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ } } + @Override + public boolean isTunnellingSupported() + { + return true; + } + + @Override + public EndPoint getTunnellingEndPoint() + { + return new ServerHTTP2StreamEndPoint(getStream()); + } + @Override public void close() { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index a8a9476423f..e8ff9759227 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; @@ -33,24 +34,27 @@ import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.PushPromiseFrame; import org.eclipse.jetty.http2.frames.ResetFrame; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpTransport; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HttpTransportOverHTTP2 implements HttpTransport { - private static final Logger LOG = Log.getLogger(HttpTransportOverHTTP2.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpTransportOverHTTP2.class); private final AtomicBoolean commit = new AtomicBoolean(); private final TransportCallback transportCallback = new TransportCallback(); private final Connector connector; private final HTTP2ServerConnection connection; private IStream stream; - private MetaData metaData; + private MetaData.Response metaData; public HttpTransportOverHTTP2(Connector connector, HTTP2ServerConnection connection) { @@ -58,14 +62,6 @@ public class HttpTransportOverHTTP2 implements HttpTransport this.connection = connection; } - @Override - public boolean isOptimizedForDirectBuffers() - { - // Because sent buffers are passed directly to the endpoint without - // copying we can defer to the endpoint - return connection.getEndPoint().isOptimizedForDirectBuffers(); - } - public IStream getStream() { return stream; @@ -85,13 +81,14 @@ public class HttpTransportOverHTTP2 implements HttpTransport } @Override - public void send(MetaData.Response info, boolean isHeadRequest, ByteBuffer content, boolean lastContent, Callback callback) + public void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback) { + boolean isHeadRequest = HttpMethod.HEAD.is(request.getMethod()); boolean hasContent = BufferUtil.hasContent(content) && !isHeadRequest; - if (info != null) + if (response != null) { - metaData = info; - int status = info.getStatus(); + metaData = response; + int status = response.getStatus(); boolean interimResponse = status == HttpStatus.CONTINUE_100 || status == HttpStatus.PROCESSING_102; if (interimResponse) { @@ -103,7 +100,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport else { if (transportCallback.start(callback, false)) - sendHeadersFrame(info, false, transportCallback); + sendHeadersFrame(response, false, transportCallback); } } else @@ -139,28 +136,36 @@ public class HttpTransportOverHTTP2 implements HttpTransport } }; if (transportCallback.start(commitCallback, true)) - sendHeadersFrame(info, false, transportCallback); + sendHeadersFrame(response, false, transportCallback); } else { if (lastContent) { - HttpFields trailers = retrieveTrailers(); - if (trailers != null) + if (isTunnel(request, response)) { - if (transportCallback.start(new SendTrailers(callback, trailers), true)) - sendHeadersFrame(info, false, transportCallback); + if (transportCallback.start(callback, true)) + sendHeadersFrame(response, false, transportCallback); } else { - if (transportCallback.start(callback, true)) - sendHeadersFrame(info, true, transportCallback); + HttpFields trailers = retrieveTrailers(); + if (trailers != null) + { + if (transportCallback.start(new SendTrailers(callback, trailers), true)) + sendHeadersFrame(response, false, transportCallback); + } + else + { + if (transportCallback.start(callback, true)) + sendHeadersFrame(response, true, transportCallback); + } } } else { if (transportCallback.start(callback, true)) - sendHeadersFrame(info, false, transportCallback); + sendHeadersFrame(response, false, transportCallback); } } } @@ -172,7 +177,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport } else { - if (hasContent || lastContent) + if (hasContent || (lastContent && !isTunnel(request, metaData))) { if (lastContent) { @@ -220,6 +225,11 @@ public class HttpTransportOverHTTP2 implements HttpTransport return trailers.size() == 0 ? null : trailers; } + private boolean isTunnel(MetaData.Request request, MetaData.Response response) + { + return HttpMethod.CONNECT.is(request.getMethod()) && response.getStatus() == HttpStatus.OK_200; + } + @Override public boolean isPushSupported() { @@ -239,7 +249,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport if (LOG.isDebugEnabled()) LOG.debug("HTTP/2 Push {}", request); - stream.push(new PushPromiseFrame(stream.getId(), 0, request), new Promise() + stream.push(new PushPromiseFrame(stream.getId(), 0, request), new Promise<>() { @Override public void succeeded(Stream pushStream) @@ -304,23 +314,53 @@ public class HttpTransportOverHTTP2 implements HttpTransport return transportCallback.onIdleTimeout(failure); } + /** + * @return true if error sent, false if upgraded or aborted. + */ + boolean prepareUpgrade() + { + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); + Request request = channel.getRequest(); + if (request.getHttpInput().hasContent()) + return channel.sendErrorOrAbort("Unexpected content in CONNECT request"); + + Connection connection = (Connection)request.getAttribute(UPGRADE_CONNECTION_ATTRIBUTE); + if (connection == null) + return channel.sendErrorOrAbort("No UPGRADE_CONNECTION_ATTRIBUTE available"); + + EndPoint endPoint = connection.getEndPoint(); + endPoint.upgrade(connection); + stream.setAttachment(endPoint); + + // Only now that we have switched the attachment, we can demand DATA frames to process them. + stream.demand(1); + + if (LOG.isDebugEnabled()) + LOG.debug("Upgrading to {}", connection); + + return false; + } + @Override public void onCompleted() { - // If the stream is not closed, it is still reading the request content. - // Send a reset to the other end so that it stops sending data. - if (!stream.isClosed()) + Object attachment = stream.getAttachment(); + if (attachment instanceof HttpChannelOverHTTP2) { - if (LOG.isDebugEnabled()) - LOG.debug("HTTP2 Response #{}: unconsumed request content, resetting stream", stream.getId()); - stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); - } + // If the stream is not closed, it is still reading the request content. + // Send a reset to the other end so that it stops sending data. + if (!stream.isClosed()) + { + if (LOG.isDebugEnabled()) + LOG.debug("HTTP2 Response #{}: unconsumed request content, resetting stream", stream.getId()); + stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); + } - // Consume the existing queued data frames to - // avoid stalling the session flow control. - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); - if (channel != null) + // Consume the existing queued data frames to + // avoid stalling the session flow control. + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)attachment; channel.consumeInput(); + } } @Override @@ -331,7 +371,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport LOG.debug("HTTP2 Response #{}/{} aborted", stream == null ? -1 : stream.getId(), stream == null ? -1 : Integer.toHexString(stream.getSession().hashCode())); if (stream != null) - stream.reset(new ResetFrame(stream.getId(), ErrorCode.INTERNAL_ERROR.code), Callback.NOOP); + stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); } private class TransportCallback implements Callback @@ -392,35 +432,20 @@ public class HttpTransportOverHTTP2 implements HttpTransport public void failed(Throwable failure) { boolean commit; - Callback callback = null; - synchronized (this) - { - commit = this.commit; - // Only fail pending writes, as we - // may need to write an error page. - if (state == State.WRITING) - { - this.state = State.FAILED; - callback = this.callback; - this.callback = null; - this.failure = failure; - } - } - if (LOG.isDebugEnabled()) - LOG.debug(String.format("HTTP2 Response #%d/%h %s %s", stream.getId(), stream.getSession(), commit ? "commit" : "flush", callback == null ? "ignored" : "failed"), failure); - if (callback != null) - callback.failed(failure); - } - - @Override - public InvocationType getInvocationType() - { Callback callback; synchronized (this) { + commit = this.commit; + this.state = State.FAILED; callback = this.callback; + this.callback = null; + this.failure = failure; } - return callback != null ? callback.getInvocationType() : Callback.super.getInvocationType(); + if (LOG.isDebugEnabled()) + LOG.debug(String.format("HTTP2 Response #%d/%h %s %s", stream.getId(), stream.getSession(), + commit ? "commit" : "flush", callback == null ? "ignored" : "failed"), failure); + if (callback != null) + callback.failed(failure); } private boolean onIdleTimeout(Throwable failure) @@ -446,6 +471,17 @@ public class HttpTransportOverHTTP2 implements HttpTransport callback.failed(failure); return result; } + + @Override + public InvocationType getInvocationType() + { + Callback callback; + synchronized (this) + { + callback = this.callback; + } + return callback != null ? callback.getInvocationType() : Callback.super.getInvocationType(); + } } private enum State diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/RawHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/RawHTTP2ServerConnectionFactory.java index c1d1a92dba9..6746c42516e 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/RawHTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/RawHTTP2ServerConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/ServerHTTP2StreamEndPoint.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/ServerHTTP2StreamEndPoint.java new file mode 100644 index 00000000000..9b922d327c3 --- /dev/null +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/ServerHTTP2StreamEndPoint.java @@ -0,0 +1,86 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http2.server; + +import java.util.function.Consumer; + +import org.eclipse.jetty.http2.HTTP2Channel; +import org.eclipse.jetty.http2.HTTP2StreamEndPoint; +import org.eclipse.jetty.http2.IStream; +import org.eclipse.jetty.http2.frames.DataFrame; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.util.Callback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServerHTTP2StreamEndPoint extends HTTP2StreamEndPoint implements HTTP2Channel.Server +{ + private static final Logger LOG = LoggerFactory.getLogger(ServerHTTP2StreamEndPoint.class); + + public ServerHTTP2StreamEndPoint(IStream stream) + { + super(stream); + } + + @Override + public Runnable onData(DataFrame frame, Callback callback) + { + offerData(frame, callback); + return null; + } + + @Override + public Runnable onTrailer(HeadersFrame frame) + { + // We are tunnelling, so there are no trailers. + return null; + } + + @Override + public boolean onTimeout(Throwable failure, Consumer consumer) + { + if (LOG.isDebugEnabled()) + LOG.debug("idle timeout on {}: {}", this, failure); + offerFailure(failure); + boolean result = true; + Connection connection = getConnection(); + if (connection != null) + result = connection.onIdleExpired(); + consumer.accept(() -> close(failure)); + return result; + } + + @Override + public Runnable onFailure(Throwable failure, Callback callback) + { + if (LOG.isDebugEnabled()) + LOG.debug("failure on {}: {}", this, failure); + offerFailure(failure); + close(failure); + return callback::succeeded; + } + + @Override + public boolean isIdle() + { + // We are tunnelling, so we are never idle. + return false; + } +} diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/AbstractServerTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/AbstractServerTest.java index 15c694254fa..315e5923704 100644 --- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/AbstractServerTest.java +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/AbstractServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java index 963591f41c1..f526bc3cdfa 100644 --- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/CloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/H2SpecServer.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/H2SpecServer.java index 97d0a86fa2d..90bfa31f369 100644 --- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/H2SpecServer.java +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/H2SpecServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -34,11 +34,11 @@ public class H2SpecServer Server server = new Server(); - HttpConfiguration http_config = new HttpConfiguration(); - http_config.setRequestHeaderSize(16 * 1024); + HttpConfiguration httpConfig = new HttpConfiguration(); + httpConfig.setRequestHeaderSize(16 * 1024); - HttpConnectionFactory http = new HttpConnectionFactory(http_config); - HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(http_config); + HttpConnectionFactory http = new HttpConnectionFactory(httpConfig); + HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfig); ServerConnector connector = new ServerConnector(server, http, h2c); connector.setPort(port); server.addConnector(connector); diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServer.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServer.java index 6a9527da0de..118faf7880e 100644 --- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServer.java +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java index 134639d9429..42111cd259f 100644 --- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2CServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -82,7 +82,7 @@ public class HTTP2CServerTest extends AbstractServerTest } @Test - public void testHTTP_1_0_Simple() throws Exception + public void testHTTP10Simple() throws Exception { try (Socket client = new Socket("localhost", connector.getLocalPort())) { @@ -97,7 +97,7 @@ public class HTTP2CServerTest extends AbstractServerTest } @Test - public void testHTTP_1_1_Simple() throws Exception + public void testHTTP11Simple() throws Exception { try (Socket client = new Socket("localhost", connector.getLocalPort())) { @@ -115,7 +115,7 @@ public class HTTP2CServerTest extends AbstractServerTest } @Test - public void testHTTP_1_1_Upgrade() throws Exception + public void testHTTP11Upgrade() throws Exception { try (Socket client = new Socket("localhost", connector.getLocalPort())) { @@ -125,7 +125,7 @@ public class HTTP2CServerTest extends AbstractServerTest "Host: localhost\r\n" + "Connection: something, else, upgrade, HTTP2-Settings\r\n" + "Upgrade: h2c\r\n" + - "HTTP2-Settings: \r\n" + + "HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA\r\n" + "\r\n").getBytes(StandardCharsets.ISO_8859_1)); output.flush(); @@ -188,7 +188,7 @@ public class HTTP2CServerTest extends AbstractServerTest assertThat(content, containsString("Hello from Jetty using HTTP/1.1")); assertThat(content, containsString("uri=/one")); - // Send a HTTP/2 request. + // Send an HTTP/2 request. headersRef.set(null); dataRef.set(null); latchRef.set(new CountDownLatch(2)); @@ -223,7 +223,7 @@ public class HTTP2CServerTest extends AbstractServerTest } @Test - public void testHTTP_2_0_Direct() throws Exception + public void testHTTP20Direct() throws Exception { final CountDownLatch latch = new CountDownLatch(3); @@ -290,7 +290,7 @@ public class HTTP2CServerTest extends AbstractServerTest } @Test - public void testHTTP_2_0_DirectWithoutH2C() throws Exception + public void testHTTP20DirectWithoutH2C() throws Exception { AtomicLong fills = new AtomicLong(); // Remove "h2c", leaving only "http/1.1". @@ -319,7 +319,7 @@ public class HTTP2CServerTest extends AbstractServerTest connector.setDefaultProtocol(connectionFactory.getProtocol()); connector.start(); - // Now send a HTTP/2 direct request, which + // Now send an HTTP/2 direct request, which // will have the PRI * HTTP/2.0 preface. byteBufferPool = new MappedByteBufferPool(); @@ -336,7 +336,7 @@ public class HTTP2CServerTest extends AbstractServerTest output.write(BufferUtil.toArray(buffer)); } - // We sent a HTTP/2 preface, but the server has no "h2c" connection + // We sent an HTTP/2 preface, but the server has no "h2c" connection // factory so it does not know how to handle this request. InputStream input = client.getInputStream(); diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java index 53bba437cd9..650634fc2d9 100644 --- a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/HTTP2ServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http2.server; @@ -60,12 +60,12 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ChannelEndPoint; import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.SocketChannelEndPoint; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertArrayEquals; @@ -383,13 +383,14 @@ public class HTTP2ServerTest extends AbstractServerTest @Test public void testNonISOHeader() throws Exception { - try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) + try (StacklessLogging ignored = new StacklessLogging(HttpChannel.class)) { startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck // Invalid header name, the connection must be closed. response.setHeader("Euro_(\u20AC)", "42"); } diff --git a/jetty-http2/http2-server/src/test/resources/jetty-logging.properties b/jetty-http2/http2-server/src/test/resources/jetty-logging.properties index 9611e7c6ad5..d71badfeed6 100644 --- a/jetty-http2/http2-server/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-server/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.http2.LEVEL=DEBUG org.eclipse.jetty.http2.hpack.LEVEL=INFO diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml index 751d63b19e2..7fa7aab27cc 100644 --- a/jetty-infinispan/infinispan-common/pom.xml +++ b/jetty-infinispan/infinispan-common/pom.xml @@ -53,6 +53,15 @@ jetty-server ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.infinispan infinispan-client-hotrod diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/BoundDelegatingInputStream.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/BoundDelegatingInputStream.java new file mode 100644 index 00000000000..e9fe899d30f --- /dev/null +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/BoundDelegatingInputStream.java @@ -0,0 +1,145 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.session.infinispan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInput; + +/** + * BoundDelegatingInputStream + * + * An InputStream that delegates methods to an ObjectInput. The ObjectInput must start + * with an integer containing the length of the data. + */ +public class BoundDelegatingInputStream extends InputStream +{ + + protected final ObjectInput objectInput; + private final int length; + private int position = 0; + + public BoundDelegatingInputStream(ObjectInput objectInput) throws IOException + { + this.objectInput = objectInput; + this.length = objectInput.readInt(); + } + + @Override + public int read() throws IOException + { + if (position < length) + { + position++; + return objectInput.read(); + } + return -1; + } + + @Override + public int read(byte[] b) throws IOException + { + int available = length - position; + int read = -1; + if (position == length) + { + return read; + } + if (b.length > available) + { + read = objectInput.read(b, 0, available); + } + else + { + read = objectInput.read(b); + } + if (read != -1) + { + position += read; + } + return read; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException + { + int read = -1; + if (position == length) + { + return read; + } + if (position + len > length) + { + read = objectInput.read(b, off, length - position); + } + else + { + read = objectInput.read(b, off, len); + } + if (read != -1) + { + position += read; + } + return read; + } + + @Override + public long skip(long n) throws IOException + { + long skip = 0; + if (position + n < length) + { + skip = objectInput.skip(length - position); + } + else + { + skip = objectInput.skip(n); + } + if (skip > 0) + { + position += skip; + } + return skip; + } + + @Override + public int available() throws IOException + { + if (position < length) + { + int available = objectInput.available(); + if (position + available > length) + { + return length - position; + } + else + { + return available; + } + } + return 0; + } + + @Override + public void close() throws IOException + { + objectInput.close(); + } + +} diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java index a5f73eb9e4c..030d91701d0 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java @@ -1,3 +1,21 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.session.infinispan; import java.io.ByteArrayInputStream; @@ -8,6 +26,7 @@ import java.util.Map; import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.util.ClassLoadingObjectInputStream; +import org.infinispan.commons.marshall.SerializeWith; /** * InfinispanSessionData @@ -19,6 +38,7 @@ import org.eclipse.jetty.util.ClassLoadingObjectInputStream; * pool and thus these threads have no knowledge of the correct classloader to * use. */ +@SerializeWith(SessionDataMarshaller.class) public class InfinispanSessionData extends SessionData { protected byte[] _serializedAttributes; @@ -66,4 +86,4 @@ public class InfinispanSessionData extends SessionData _serializedAttributes = baos.toByteArray(); } } -} \ No newline at end of file +} diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java index 552be1c86f6..a94e08c902d 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; @@ -29,9 +29,9 @@ import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.server.session.UnreadableSessionDataException; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.infinispan.commons.api.BasicCache; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * InfinispanSessionDataStore @@ -39,7 +39,7 @@ import org.infinispan.commons.api.BasicCache; @ManagedObject public class InfinispanSessionDataStore extends AbstractSessionDataStore { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(InfinispanSessionDataStore.class); /** * Clustered cache of sessions @@ -82,9 +82,6 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore _queryManager = queryManager; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#load(String) - */ @Override protected void doStart() throws Exception { diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java index faf275c17cb..55c92e42b91 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; @@ -49,9 +49,6 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF _infinispanIdleTimeoutSec = infinispanIdleTimeoutSec; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java index 32c162c7c6d..c72d6459eca 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/NullQueryManagerFactory.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/NullQueryManagerFactory.java index 764ac2405bf..2f028558f98 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/NullQueryManagerFactory.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/NullQueryManagerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManager.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManager.java index 4250553aec2..f8e2bf4ab63 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManager.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManagerFactory.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManagerFactory.java index 6475614a290..b253b7a484d 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManagerFactory.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManagerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java index 27f98672ddb..ed2d7ec4fa8 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java @@ -1,26 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import org.infinispan.commons.marshall.Externalizer; +import org.infinispan.protostream.FileDescriptorSource; import org.infinispan.protostream.MessageMarshaller; +import org.infinispan.protostream.ProtobufUtil; +import org.infinispan.protostream.SerializationContext; /** * SessionDataMarshaller @@ -30,13 +36,30 @@ import org.infinispan.protostream.MessageMarshaller; * control to ensure that session attributes can be deserialized using either * the container class loader or the webapp classloader, as appropriate. */ -public class SessionDataMarshaller implements MessageMarshaller +public class SessionDataMarshaller + implements MessageMarshaller, Externalizer { /** * The version of the serializer. */ private static final int VERSION = 0; + private static SerializationContext serializationContext; + + private static synchronized void initSerializationContext() throws IOException + { + if (serializationContext != null) + { + return; + } + FileDescriptorSource fds = new FileDescriptorSource(); + fds.addProtoFiles("/session.proto"); + SerializationContext sCtx = ProtobufUtil.newSerializationContext(); + sCtx.registerProtoFiles(fds); + sCtx.registerMarshaller(new SessionDataMarshaller()); + serializationContext = sCtx; + } + @Override public Class getJavaClass() { @@ -49,6 +72,39 @@ public class SessionDataMarshaller implements MessageMarshaller _cache = _manager.getCache(_name); + cacheManager.defineConfiguration(name, c); + Cache cache = cacheManager.getCache(name); //put some sessions into the cache int numSessions = 10; @@ -92,11 +89,11 @@ public class EmbeddedQueryManagerTest expiredSessions.add("sd" + i); //add to cache - _cache.put("sd" + i, sd); + cache.put("sd" + i, sd); } //run the query - QueryManager qm = new EmbeddedQueryManager(_cache); + QueryManager qm = new EmbeddedQueryManager(cache); Set queryResult = qm.queryExpiredSessions(currentTime); // Check that the result is correct diff --git a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java index 5cf40613a41..796a118efa6 100644 --- a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java +++ b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; diff --git a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java index cf4a53fa3e3..37a7c4590fd 100644 --- a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java +++ b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.session.infinispan; diff --git a/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java b/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java index a99da415c5d..69a6f0268e9 100644 --- a/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java +++ b/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session.infinispan; @@ -70,7 +70,7 @@ public class RemoteQueryManagerTest serCtx.registerProtoFiles(fds); serCtx.registerMarshaller(new SessionDataMarshaller()); - RemoteCache _cache = remoteCacheManager.getCache(DEFAULT_CACHE_NAME); + RemoteCache cache = remoteCacheManager.getCache(DEFAULT_CACHE_NAME); ByteArrayOutputStream baos; try (InputStream is = RemoteQueryManagerTest.class.getClassLoader().getResourceAsStream("session.proto")) @@ -106,12 +106,12 @@ public class RemoteQueryManagerTest expiredSessions.add(id); //add to cache - _cache.put(id, sd); - assertNotNull(_cache.get(id)); + cache.put(id, sd); + assertNotNull(cache.get(id)); } //run the query - QueryManager qm = new RemoteQueryManager(_cache); + QueryManager qm = new RemoteQueryManager(cache); Set queryResult = qm.queryExpiredSessions(currentTime); // Check that the result is correct diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index ef53deabed6..cd974cb34d6 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -18,6 +18,15 @@ jetty-util ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-io/src/main/java/module-info.java b/jetty-io/src/main/java/module-info.java index 307230614e4..e9286fa962f 100644 --- a/jetty-io/src/main/java/module-info.java +++ b/jetty-io/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.io @@ -21,5 +21,6 @@ module org.eclipse.jetty.io exports org.eclipse.jetty.io; exports org.eclipse.jetty.io.ssl; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.util; + requires org.slf4j; } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java index 71c0fec0c55..20c18906e19 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java index 74ba6f0ed52..eac63d67f89 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; +import java.util.EventListener; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; @@ -25,9 +26,9 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Invocable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A convenience base implementation of {@link Connection}.

      @@ -38,7 +39,7 @@ import org.eclipse.jetty.util.thread.Invocable; */ public abstract class AbstractConnection implements Connection { - private static final Logger LOG = Log.getLogger(AbstractConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractConnection.class); private final List _listeners = new CopyOnWriteArrayList<>(); private final long _created = System.currentTimeMillis(); @@ -57,13 +58,14 @@ public abstract class AbstractConnection implements Connection } @Override - public void addListener(Listener listener) + public void addEventListener(EventListener listener) { - _listeners.add(listener); + if (listener instanceof Listener) + _listeners.add((Listener)listener); } @Override - public void removeListener(Listener listener) + public void removeEventListener(EventListener listener) { _listeners.remove(listener); } @@ -93,7 +95,7 @@ public abstract class AbstractConnection implements Connection } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed callback", x); } }; @@ -106,7 +108,7 @@ public abstract class AbstractConnection implements Connection } catch (RejectedExecutionException e) { - LOG.debug(e); + LOG.debug("Rejected", e); callback.failed(x); } break; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java index 7e926856c04..7cd08ad4542 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -25,13 +25,13 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint { - private static final Logger LOG = Log.getLogger(AbstractEndPoint.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractEndPoint.class); private final AtomicReference _state = new AtomicReference<>(State.OPEN); private final long _created = System.currentTimeMillis(); @@ -327,12 +327,6 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint _connection = connection; } - @Override - public boolean isOptimizedForDirectBuffers() - { - return false; - } - protected void reset() { _state.set(State.OPEN); @@ -406,7 +400,7 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint return _fillInterest; } - protected WriteFlusher getWriteFlusher() + public WriteFlusher getWriteFlusher() { return _writeFlusher; } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java index 6c00d73d822..d1dc3c09ae6 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java index 14948563718..bddd34d0bfc 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -34,17 +34,17 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Locker; +import org.eclipse.jetty.util.thread.AutoLock; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ByteArrayEndPoint. */ public class ByteArrayEndPoint extends AbstractEndPoint { - static final Logger LOG = Log.getLogger(ByteArrayEndPoint.class); + static final Logger LOG = LoggerFactory.getLogger(ByteArrayEndPoint.class); static final InetAddress NOIP; static final InetSocketAddress NOIPPORT; @@ -57,7 +57,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint } catch (UnknownHostException e) { - LOG.warn(e); + LOG.warn("Unable to get IPv4 no-ip reference for 0.0.0.0", e); } finally { @@ -68,24 +68,13 @@ public class ByteArrayEndPoint extends AbstractEndPoint private static final ByteBuffer EOF = BufferUtil.allocate(0); - private final Runnable _runFillable = new Runnable() - { - @Override - public void run() - { - getFillInterest().fillable(); - } - }; - - private final Locker _locker = new Locker(); - private final Condition _hasOutput = _locker.newCondition(); + private final Runnable _runFillable = () -> getFillInterest().fillable(); + private final AutoLock _lock = new AutoLock(); + private final Condition _hasOutput = _lock.newCondition(); private final Queue _inQ = new ArrayDeque<>(); private ByteBuffer _out; private boolean _growOutput; - /** - * - */ public ByteArrayEndPoint() { this(null, 0, null, null); @@ -138,7 +127,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint public void doShutdownOutput() { super.doShutdownOutput(); - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { _hasOutput.signalAll(); } @@ -148,7 +137,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint public void doClose() { super.doClose(); - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { _hasOutput.signalAll(); } @@ -180,7 +169,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint @Override protected void needsFillInterest() throws IOException { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { if (!isOpen()) throw new ClosedChannelException(); @@ -205,7 +194,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint public void addInput(ByteBuffer in) { boolean fillable = false; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { if (isEOF(_inQ.peek())) throw new RuntimeIOException(new EOFException()); @@ -238,7 +227,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint public void addInputAndExecute(ByteBuffer in) { boolean fillable = false; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { if (isEOF(_inQ.peek())) throw new RuntimeIOException(new EOFException()); @@ -263,7 +252,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint */ public ByteBuffer getOutput() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { return _out; } @@ -293,7 +282,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint { ByteBuffer b; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { b = _out; _out = BufferUtil.allocate(b.capacity()); @@ -314,7 +303,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint { ByteBuffer b; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { while (BufferUtil.isEmpty(_out) && !isOutputShutdown()) { @@ -351,7 +340,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint */ public void setOutput(ByteBuffer out) { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { _out = out; } @@ -359,21 +348,18 @@ public class ByteArrayEndPoint extends AbstractEndPoint } /** - * @return true if there are bytes remaining to be read from the encoded input + * @return {@code true} if there are bytes remaining to be read from the encoded input */ public boolean hasMore() { return getOutput().position() > 0; } - /* - * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer) - */ @Override public int fill(ByteBuffer buffer) throws IOException { int filled = 0; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { while (true) { @@ -411,14 +397,11 @@ public class ByteArrayEndPoint extends AbstractEndPoint return filled; } - /* - * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer) - */ @Override public boolean flush(ByteBuffer... buffers) throws IOException { boolean flushed = true; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { if (!isOpen()) throw new IOException("CLOSED"); @@ -461,13 +444,10 @@ public class ByteArrayEndPoint extends AbstractEndPoint return flushed; } - /** - * - */ @Override public void reset() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { _inQ.clear(); _hasOutput.signalAll(); @@ -476,9 +456,6 @@ public class ByteArrayEndPoint extends AbstractEndPoint super.reset(); } - /* - * @see org.eclipse.io.EndPoint#getConnection() - */ @Override public Object getTransport() { @@ -507,7 +484,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint int q; ByteBuffer b; String o; - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { q = _inQ.size(); b = _inQ.peek(); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferOutputStream.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferOutputStream.java new file mode 100644 index 00000000000..1ac63d2ee9a --- /dev/null +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferOutputStream.java @@ -0,0 +1,62 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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; + +import java.io.OutputStream; +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.BufferUtil; + +/** + * Simple wrapper of a ByteBuffer as an OutputStream. + * The buffer does not grow and this class will throw an + * {@link java.nio.BufferOverflowException} if the buffer capacity is exceeded. + */ +public class ByteBufferOutputStream extends OutputStream +{ + final ByteBuffer _buffer; + + public ByteBufferOutputStream(ByteBuffer buffer) + { + _buffer = buffer; + } + + public void close() + { + } + + public void flush() + { + } + + public void write(byte[] b) + { + write(b, 0, b.length); + } + + public void write(byte[] b, int off, int len) + { + BufferUtil.append(_buffer, b, off, len); + } + + public void write(int b) + { + BufferUtil.append(_buffer, (byte)b); + } +} diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java index 68db0b2880b..06e64fd9406 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -127,11 +127,16 @@ public interface ByteBufferPool { ByteBuffer buffer = buffers.get(i); if (recycles.get(i)) - byteBufferPool.release(buffer); + release(buffer); } buffers.clear(); recycles.clear(); } + + public void release(ByteBuffer buffer) + { + byteBufferPool.release(buffer); + } } public static class Bucket diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java index 0d58fde8245..2c89a173753 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -28,10 +28,10 @@ import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Invocable; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Channel End Point. @@ -39,7 +39,7 @@ import org.eclipse.jetty.util.thread.Scheduler; */ public abstract class ChannelEndPoint extends AbstractEndPoint implements ManagedSelector.Selectable { - private static final Logger LOG = Log.getLogger(ChannelEndPoint.class); + private static final Logger LOG = LoggerFactory.getLogger(ChannelEndPoint.class); private final ByteChannel _channel; private final GatheringByteChannel _gather; @@ -89,7 +89,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage } catch (Throwable x) { - LOG.warn(x); + LOG.warn("Unable to close ChannelEndPoint", x); } } } @@ -175,12 +175,6 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage _gather = (channel instanceof GatheringByteChannel) ? (GatheringByteChannel)channel : null; } - @Override - public boolean isOptimizedForDirectBuffers() - { - return true; - } - @Override public boolean isOpen() { @@ -198,7 +192,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage } catch (IOException e) { - LOG.debug(e); + LOG.debug("Unable to close channel", e); } finally { @@ -238,7 +232,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage } catch (IOException e) { - LOG.debug(e); + LOG.debug("Unable to shutdown output", e); shutdownInput(); filled = -1; } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java index d6bcf20369b..4e555e7878e 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; import java.io.IOException; +import java.util.EventListener; import java.util.List; import java.util.Map; @@ -43,16 +44,33 @@ public interface ClientConnectionFactory { ContainerLifeCycle client = (ContainerLifeCycle)context.get(CLIENT_CONTEXT_KEY); if (client != null) - client.getBeans(Connection.Listener.class).forEach(connection::addListener); + client.getBeans(EventListener.class).forEach(connection::addEventListener); return connection; } + /** + *

      Wraps another ClientConnectionFactory.

      + *

      This is typically done by protocols that send "preface" bytes with some metadata + * before other protocols. The metadata could be, for example, proxying information + * or authentication information.

      + */ + interface Decorator + { + /** + *

      Wraps the given {@code factory}.

      + * + * @param factory the ClientConnectionFactory to wrap + * @return the wrapping ClientConnectionFactory + */ + ClientConnectionFactory apply(ClientConnectionFactory factory); + } + /** *

      A holder for a list of protocol strings identifying a network protocol * (for example {@code ["h2", "h2-17", "h2-16"]}) and a {@link ClientConnectionFactory} * that creates connections that speak that network protocol.

      */ - public static class Info + public static class Info extends ContainerLifeCycle { private final List protocols; private final ClientConnectionFactory factory; @@ -61,6 +79,7 @@ public interface ClientConnectionFactory { this.protocols = protocols; this.factory = factory; + addBean(factory); } public List getProtocols() @@ -81,7 +100,18 @@ public interface ClientConnectionFactory */ public boolean matches(List candidates) { - return protocols.stream().anyMatch(candidates::contains); + return protocols.stream().anyMatch(p -> candidates.stream().anyMatch(c -> c.equalsIgnoreCase(p))); + } + + public void upgrade(EndPoint endPoint, Map context) + { + throw new UnsupportedOperationException(this + " does not support upgrade to another protocol"); + } + + @Override + public String toString() + { + return String.format("%s@%x%s", getClass().getSimpleName(), hashCode(), protocols); } } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java index 4e51d6f912a..abe77a5673e 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -32,12 +32,12 @@ import java.util.concurrent.Executor; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ClientConnector extends ContainerLifeCycle { @@ -45,7 +45,7 @@ public class ClientConnector extends ContainerLifeCycle public static final String REMOTE_SOCKET_ADDRESS_CONTEXT_KEY = CLIENT_CONNECTOR_CONTEXT_KEY + ".remoteSocketAddress"; public static final String CLIENT_CONNECTION_FACTORY_CONTEXT_KEY = CLIENT_CONNECTOR_CONTEXT_KEY + ".clientConnectionFactory"; public static final String CONNECTION_PROMISE_CONTEXT_KEY = CLIENT_CONNECTOR_CONTEXT_KEY + ".connectionPromise"; - private static final Logger LOG = Log.getLogger(ClientConnector.class); + private static final Logger LOG = LoggerFactory.getLogger(ClientConnector.class); private Executor executor; private Scheduler scheduler; @@ -288,7 +288,7 @@ public class ClientConnector extends ContainerLifeCycle } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java index 885aee928cd..def9daa7657 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; import java.io.Closeable; import java.nio.ByteBuffer; +import java.util.EventListener; import org.eclipse.jetty.util.component.Container; @@ -38,14 +39,14 @@ public interface Connection extends Closeable * * @param listener the listener to add */ - public void addListener(Listener listener); + public void addEventListener(EventListener listener); /** *

      Removes a listener of connection events.

      * * @param listener the listener to remove */ - public void removeListener(Listener listener); + public void removeEventListener(EventListener listener); /** *

      Callback method invoked when this connection is opened.

      @@ -133,7 +134,7 @@ public interface Connection extends Closeable * the Connector or ConnectionFactory are added as listeners to all new connections *

      */ - public interface Listener + public interface Listener extends EventListener { public void onOpened(Connection connection); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java index bf062408cb0..1bade4e6320 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java b/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java index 211b1e11ed2..f064941af8e 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -22,9 +22,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.lang.Long.MAX_VALUE; @@ -50,7 +50,7 @@ import static java.lang.Long.MAX_VALUE; */ public abstract class CyclicTimeout implements Destroyable { - private static final Logger LOG = Log.getLogger(CyclicTimeout.class); + private static final Logger LOG = LoggerFactory.getLogger(CyclicTimeout.class); private static final Timeout NOT_SET = new Timeout(MAX_VALUE, null); private static final Scheduler.Task DESTROYED = () -> false; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java index 875ad2521da..09126f49124 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -95,7 +95,17 @@ import org.eclipse.jetty.util.thread.Invocable; */ public interface EndPoint extends Closeable { - + /** + * Marks an EndPoint that wraps another EndPoint. + */ + public interface Wrapper + { + /** + * @return The wrapped EndPoint + */ + EndPoint unwrap(); + } + /** * @return The local Inet address to which this EndPoint is bound, or null * if this EndPoint does not represent a network connection. @@ -269,13 +279,6 @@ public interface EndPoint extends Closeable */ void onClose(Throwable cause); - /** - * Is the endpoint optimized for DirectBuffer usage - * - * @return True if direct buffers can be used optimally. - */ - boolean isOptimizedForDirectBuffers(); - /** * Upgrade connections. * Close the old connection, update the endpoint and open the new connection. diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java index fc8c0aa21e0..de64ec54392 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java b/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java index 6a90d9c2153..b904638d665 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -24,10 +24,10 @@ import java.nio.channels.ReadPendingException; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Invocable; import org.eclipse.jetty.util.thread.Invocable.InvocationType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A Utility class to help implement {@link EndPoint#fillInterested(Callback)} @@ -35,7 +35,7 @@ import org.eclipse.jetty.util.thread.Invocable.InvocationType; */ public abstract class FillInterest { - private static final Logger LOG = Log.getLogger(FillInterest.class); + private static final Logger LOG = LoggerFactory.getLogger(FillInterest.class); private final AtomicReference _interested = new AtomicReference<>(null); protected FillInterest() diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java b/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java index aae4b2c1449..99d4969f1c9 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -22,9 +22,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An Abstract implementation of an Idle Timeout. @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.thread.Scheduler; */ public abstract class IdleTimeout { - private static final Logger LOG = Log.getLogger(IdleTimeout.class); + private static final Logger LOG = LoggerFactory.getLogger(IdleTimeout.class); private final Scheduler _scheduler; private final AtomicReference _timeout = new AtomicReference<>(); private volatile long _idleTimeout; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java index 300fceb2430..d61dce79115 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/LeakTrackingByteBufferPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -24,12 +24,12 @@ import java.util.concurrent.atomic.AtomicLong; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.LeakDetector; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class LeakTrackingByteBufferPool extends ContainerLifeCycle implements ByteBufferPool { - private static final Logger LOG = Log.getLogger(LeakTrackingByteBufferPool.class); + private static final Logger LOG = LoggerFactory.getLogger(LeakTrackingByteBufferPool.class); private final LeakDetector leakDetector = new LeakDetector() { diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index da76d773ed9..afa3410f882 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -36,6 +36,7 @@ import java.util.Deque; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -43,14 +44,15 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ExecutionStrategy; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.strategy.EatWhatYouKill; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      {@link ManagedSelector} wraps a {@link Selector} simplifying non-blocking operations on channels.

      @@ -60,7 +62,7 @@ import org.eclipse.jetty.util.thread.strategy.EatWhatYouKill; */ public class ManagedSelector extends ContainerLifeCycle implements Dumpable { - private static final Logger LOG = Log.getLogger(ManagedSelector.class); + private static final Logger LOG = LoggerFactory.getLogger(ManagedSelector.class); private static final boolean FORCE_SELECT_NOW; static @@ -94,7 +96,6 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable Executor executor = selectorManager.getExecutor(); _strategy = new EatWhatYouKill(producer, executor); addBean(_strategy, true); - setStopTimeout(5000); } public Selector getSelector() @@ -122,12 +123,20 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable start._started.await(); } + protected void onSelectFailed(Throwable cause) + { + // override to change behavior + } + public int size() { Selector s = _selector; if (s == null) return 0; - return s.keys().size(); + Set keys = s.keys(); + if (keys == null) + return 0; + return keys.size(); } @Override @@ -135,7 +144,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable { // doStop might be called for a failed managedSelector, // We do not want to wait twice, so we only stop once for each start - if (_started.compareAndSet(true, false)) + if (_started.compareAndSet(true, false) && _selector != null) { // Close connections, but only wait a single selector cycle for it to take effect CloseConnections closeConnections = new CloseConnections(); @@ -210,7 +219,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable catch (RejectedExecutionException x) { if (task instanceof Closeable) - closeNoExceptions((Closeable)task); + IO.close((Closeable)task); } } @@ -246,17 +255,14 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } } - private static void closeNoExceptions(Closeable closeable) + protected void endPointOpened(EndPoint endPoint) { - try - { - if (closeable != null) - closeable.close(); - } - catch (Throwable x) - { - LOG.ignore(x); - } + _selectorManager.endPointOpened(endPoint); + } + + protected void endPointClosed(EndPoint endPoint) + { + _selectorManager.endPointClosed(endPoint); } private void createEndPoint(SelectableChannel channel, SelectionKey selectionKey) throws IOException @@ -266,7 +272,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable endPoint.setConnection(connection); selectionKey.attach(endPoint); endPoint.onOpen(); - _selectorManager.endPointOpened(endPoint); + endPointOpened(endPoint); _selectorManager.connectionOpened(connection); if (LOG.isDebugEnabled()) LOG.debug("Created {}", endPoint); @@ -297,7 +303,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); return -1; } } @@ -310,7 +316,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); return -1; } } @@ -429,7 +435,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable th) { - LOG.warn(th); + LOG.warn("Cannot update selector {}", _selector, th); } } _updateable.clear(); @@ -496,15 +502,19 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { + IO.close(_selector); _selector = null; + if (isRunning()) - LOG.warn(x); + { + LOG.warn("Fatal select() failure", x); + onSelectFailed(x); + } else { LOG.warn(x.toString()); - LOG.debug(x); + LOG.debug("select() failure", x); } - closeNoExceptions(_selector); } return false; } @@ -541,13 +551,13 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable { LOG.debug("Ignoring cancelled key for channel {}", key.channel()); if (attachment instanceof EndPoint) - closeNoExceptions((EndPoint)attachment); + IO.close((EndPoint)attachment); } catch (Throwable x) { LOG.warn("Could not process key for channel " + key.channel(), x); if (attachment instanceof EndPoint) - closeNoExceptions((EndPoint)attachment); + IO.close((EndPoint)attachment); } } else @@ -556,7 +566,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable LOG.debug("Selector loop ignoring invalid key for channel {}", key.channel()); Object attachment = key.attachment(); if (attachment instanceof EndPoint) - closeNoExceptions((EndPoint)attachment); + IO.close((EndPoint)attachment); } } return null; @@ -630,7 +640,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (InterruptedException x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } return keys; } @@ -661,8 +671,8 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { - closeNoExceptions(_channel); - LOG.warn(x); + IO.close(_channel); + LOG.warn("Unable to register OP_ACCEPT on selector", x); } } @@ -683,7 +693,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { - closeNoExceptions(channel); + IO.close(channel); LOG.warn("Accept failed for channel " + channel, x); } @@ -722,7 +732,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable public void close() { LOG.debug("closed accept of {}", channel); - closeNoExceptions(channel); + IO.close(channel); } @Override @@ -735,9 +745,9 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { - closeNoExceptions(channel); + IO.close(channel); _selectorManager.onAcceptFailed(channel, x); - LOG.debug(x); + LOG.debug("Unable to register update for accept", x); } } @@ -751,16 +761,16 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable x) { - LOG.debug(x); + LOG.debug("Unable to accept", x); failed(x); } } protected void failed(Throwable failure) { - closeNoExceptions(channel); - LOG.warn(String.valueOf(failure)); - LOG.debug(failure); + IO.close(channel); + LOG.warn("ManagedSelector#Accept failure : {}", Objects.toString(failure)); + LOG.debug("ManagedSelector#Accept failure", failure); _selectorManager.onAcceptFailed(channel, failure); } } @@ -808,7 +818,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable if (failed.compareAndSet(false, true)) { timeout.cancel(); - closeNoExceptions(channel); + IO.close(channel); ManagedSelector.this._selectorManager.connectionFailed(channel, failure, attachment); } } @@ -864,12 +874,12 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable { if (_closed == null) { - closeNoExceptions(closeable); + IO.close(closeable); } else if (!_closed.contains(closeable)) { _closed.add(closeable); - closeNoExceptions(closeable); + IO.close(closeable); } } } @@ -894,12 +904,12 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable { Object attachment = key.attachment(); if (attachment instanceof EndPoint) - closeNoExceptions((EndPoint)attachment); + IO.close((EndPoint)attachment); } } _selector = null; - closeNoExceptions(selector); + IO.close(selector); _stopped.countDown(); } } @@ -924,9 +934,9 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } catch (Throwable failure) { - closeNoExceptions(_connect.channel); - LOG.warn(String.valueOf(failure)); - LOG.debug(failure); + IO.close(_connect.channel); + LOG.warn("ManagedSelector#CreateEndpoint failure : {}", Objects.toString(failure)); + LOG.debug("ManagedSelector#CreateEndpoint failure", failure); _connect.failed(failure); } } @@ -957,7 +967,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable Connection connection = endPoint.getConnection(); if (connection != null) _selectorManager.connectionClosed(connection, cause); - _selectorManager.endPointClosed(endPoint); + ManagedSelector.this.endPointClosed(endPoint); } @Override diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java index 603378c95f6..75ff2f9af9b 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java index c9853ea6fd3..79b22580dac 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -24,12 +24,12 @@ import java.util.concurrent.Executor; import javax.net.ssl.SSLEngine; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class NegotiatingClientConnection extends AbstractConnection { - private static final Logger LOG = Log.getLogger(NegotiatingClientConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(NegotiatingClientConnection.class); private final SSLEngine engine; private final ClientConnectionFactory connectionFactory; @@ -108,7 +108,7 @@ public abstract class NegotiatingClientConnection extends AbstractConnection } catch (IOException x) { - LOG.debug(x); + LOG.debug("Unable to fill from endpoint", x); close(); return -1; } @@ -123,7 +123,7 @@ public abstract class NegotiatingClientConnection extends AbstractConnection } catch (Throwable x) { - LOG.debug(x); + LOG.debug("Unable to replace connection", x); close(); } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnectionFactory.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnectionFactory.java index 54b66f791a7..5886341ddc7 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnectionFactory.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficListener.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficListener.java index b2717d0403b..719bab5b04f 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficListener.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java index 5ecf5d57d73..5ff5c11a33c 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -25,13 +25,13 @@ import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.util.List; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NetworkTrafficSelectChannelEndPoint extends SocketChannelEndPoint { - private static final Logger LOG = Log.getLogger(NetworkTrafficSelectChannelEndPoint.class); + private static final Logger LOG = LoggerFactory.getLogger(NetworkTrafficSelectChannelEndPoint.class); private final List listeners; @@ -85,7 +85,7 @@ public class NetworkTrafficSelectChannelEndPoint extends SocketChannelEndPoint } catch (Exception x) { - LOG.warn(x); + LOG.warn("listener.opened failure", x); } } } @@ -105,7 +105,7 @@ public class NetworkTrafficSelectChannelEndPoint extends SocketChannelEndPoint } catch (Exception x) { - LOG.warn(x); + LOG.warn("listener.closed failure", x); } } } @@ -124,7 +124,7 @@ public class NetworkTrafficSelectChannelEndPoint extends SocketChannelEndPoint } catch (Exception x) { - LOG.warn(x); + LOG.warn("listener.incoming() failure", x); } } } @@ -143,7 +143,7 @@ public class NetworkTrafficSelectChannelEndPoint extends SocketChannelEndPoint } catch (Exception x) { - LOG.warn(x); + LOG.warn("listener.outgoing() failure", x); } } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java b/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java index 4e913d8cfb5..19f5766d2a0 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBuffer.java b/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBuffer.java index c605aee6d75..9db15f1b411 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBuffer.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBuffer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -81,14 +81,24 @@ public class RetainableByteBuffer implements Retainable return ref; } + public int remaining() + { + return buffer.remaining(); + } + public boolean hasRemaining() { - return buffer.hasRemaining(); + return remaining() > 0; } public boolean isEmpty() { - return !buffer.hasRemaining(); + return !hasRemaining(); + } + + public void clear() + { + BufferUtil.clear(buffer); } @Override diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/RuntimeIOException.java b/jetty-io/src/main/java/org/eclipse/jetty/io/RuntimeIOException.java index a552ec8c7ec..94f08d6fc0d 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/RuntimeIOException.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/RuntimeIOException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java index 4115e471a77..fb427e68291 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -38,13 +38,14 @@ import java.util.function.IntUnaryOperator; import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.component.Container; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.ThreadPool; import org.eclipse.jetty.util.thread.ThreadPoolBudget; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      {@link SelectorManager} manages a number of {@link ManagedSelector}s that @@ -57,7 +58,7 @@ import org.eclipse.jetty.util.thread.ThreadPoolBudget; public abstract class SelectorManager extends ContainerLifeCycle implements Dumpable { public static final int DEFAULT_CONNECT_TIMEOUT = 15000; - protected static final Logger LOG = Log.getLogger(SelectorManager.class); + protected static final Logger LOG = LoggerFactory.getLogger(SelectorManager.class); private final Executor executor; private final Scheduler scheduler; @@ -389,31 +390,37 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump */ public abstract Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException; - public void addEventListener(EventListener listener) + /** + * @param listener An EventListener + * @see AcceptListener + * @see Container#addEventListener(EventListener) + */ + @Override + public boolean addEventListener(EventListener listener) { if (isRunning()) throw new IllegalStateException(this.toString()); - if (listener instanceof AcceptListener) - addAcceptListener(AcceptListener.class.cast(listener)); + if (super.addEventListener(listener)) + { + if (listener instanceof AcceptListener) + _acceptListeners.add((AcceptListener)listener); + return true; + } + return false; } - public void removeEventListener(EventListener listener) + @Override + public boolean removeEventListener(EventListener listener) { if (isRunning()) throw new IllegalStateException(this.toString()); - if (listener instanceof AcceptListener) - removeAcceptListener(AcceptListener.class.cast(listener)); - } - - public void addAcceptListener(AcceptListener listener) - { - if (!_acceptListeners.contains(listener)) - _acceptListeners.add(listener); - } - - public void removeAcceptListener(AcceptListener listener) - { - _acceptListeners.remove(listener); + if (super.removeEventListener(listener)) + { + if (listener instanceof AcceptListener) + _acceptListeners.remove(listener); + return true; + } + return false; } protected void onAccepting(SelectableChannel channel) @@ -426,7 +433,7 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump } catch (Throwable x) { - LOG.warn(x); + LOG.warn("Failed to notify onAccepting on listener {}", l, x); } } } @@ -441,7 +448,7 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump } catch (Throwable x) { - LOG.warn(x); + LOG.warn("Failed to notify onAcceptFailed on listener {}", l, x); } } } @@ -456,17 +463,21 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump } catch (Throwable x) { - LOG.warn(x); + LOG.warn("Failed to notify onAccepted on listener {}", l, x); } } } + public interface SelectorManagerListener extends EventListener + { + } + /** *

      A listener for accept events.

      *

      This listener is called from either the selector or acceptor thread * and implementations must be non blocking and fast.

      */ - public interface AcceptListener extends EventListener + public interface AcceptListener extends SelectorManagerListener { /** * Called immediately after a new SelectableChannel is accepted, but diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java index 249e8419d47..23809302b8c 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -25,13 +25,13 @@ import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SocketChannelEndPoint extends ChannelEndPoint { - private static final Logger LOG = Log.getLogger(SocketChannelEndPoint.class); + private static final Logger LOG = LoggerFactory.getLogger(SocketChannelEndPoint.class); private final Socket _socket; private final InetSocketAddress _local; private final InetSocketAddress _remote; @@ -77,7 +77,7 @@ public class SocketChannelEndPoint extends ChannelEndPoint } catch (IOException e) { - LOG.debug(e); + LOG.debug("Unable to shutdown output", e); } } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java index 931052bc618..d75415dffee 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -31,10 +31,10 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Invocable; import org.eclipse.jetty.util.thread.Invocable.InvocationType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A Utility class to help implement {@link EndPoint#write(Callback, ByteBuffer...)} by calling @@ -45,7 +45,7 @@ import org.eclipse.jetty.util.thread.Invocable.InvocationType; */ public abstract class WriteFlusher { - private static final Logger LOG = Log.getLogger(WriteFlusher.class); + private static final Logger LOG = LoggerFactory.getLogger(WriteFlusher.class); private static final boolean DEBUG = LOG.isDebugEnabled(); // Easy for the compiler to remove the code if DEBUG==false private static final ByteBuffer[] EMPTY_BUFFERS = new ByteBuffer[]{BufferUtil.EMPTY_BUFFER}; private static final EnumMap> __stateTransitions = new EnumMap<>(StateType.class); @@ -258,7 +258,7 @@ public abstract class WriteFlusher */ public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException { - callback = Objects.requireNonNull(callback); + Objects.requireNonNull(callback); if (isFailed()) { @@ -325,7 +325,7 @@ public abstract class WriteFlusher case IDLE: for (Throwable t : suppressed) { - LOG.warn(t); + LOG.warn("Failed Write Cause", t); } return; @@ -489,7 +489,7 @@ public abstract class WriteFlusher if (DEBUG) { LOG.debug("ignored: {} {}", cause, this); - LOG.ignore(cause); + LOG.trace("IGNORED", cause); } return false; @@ -521,17 +521,35 @@ public abstract class WriteFlusher public void onClose() { - onFail(new ClosedChannelException()); + switch (_state.get().getType()) + { + case IDLE: + case FAILED: + return; + + default: + onFail(new ClosedChannelException()); + } } boolean isFailed() { - return _state.get().getType() == StateType.FAILED; + return isState(StateType.FAILED); } boolean isIdle() { - return _state.get().getType() == StateType.IDLE; + return isState(StateType.IDLE); + } + + public boolean isPending() + { + return isState(StateType.PENDING); + } + + private boolean isState(StateType type) + { + return _state.get().getType() == type; } public String toStateString() @@ -561,7 +579,8 @@ public abstract class WriteFlusher } /** - *

      A listener of {@link WriteFlusher} events.

      + *

      A listener of {@link WriteFlusher} events. + * If implemented by a Connection class, the {@link #onFlushed(long)} event will be delivered to it.

      */ public interface Listener { diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriterOutputStream.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriterOutputStream.java index 126448c1cfc..589c34d7c62 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriterOutputStream.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriterOutputStream.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java b/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java index f32f774ab72..fadd8c32b62 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/ALPNProcessor.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/ALPNProcessor.java index f25a50e05bd..b4fdbc82623 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/ALPNProcessor.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/ALPNProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io.ssl; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslClientConnectionFactory.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslClientConnectionFactory.java index 45b0be514fd..8b03dad06e0 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslClientConnectionFactory.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslClientConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io.ssl; @@ -46,7 +46,7 @@ public class SslClientConnectionFactory implements ClientConnectionFactory private final ClientConnectionFactory connectionFactory; private boolean _directBuffersForEncryption = true; private boolean _directBuffersForDecryption = true; - private boolean allowMissingCloseMessage = true; + private boolean _requireCloseMessage; public SslClientConnectionFactory(SslContextFactory sslContextFactory, ByteBufferPool byteBufferPool, Executor executor, ClientConnectionFactory connectionFactory) { @@ -56,6 +56,11 @@ public class SslClientConnectionFactory implements ClientConnectionFactory this.connectionFactory = connectionFactory; } + public ClientConnectionFactory getClientConnectionFactory() + { + return connectionFactory; + } + public void setDirectBuffersForEncryption(boolean useDirectBuffers) { this._directBuffersForEncryption = useDirectBuffers; @@ -76,14 +81,22 @@ public class SslClientConnectionFactory implements ClientConnectionFactory return _directBuffersForEncryption; } - public boolean isAllowMissingCloseMessage() + /** + * @return whether peers must send the TLS {@code close_notify} message + * @see SslConnection#isRequireCloseMessage() + */ + public boolean isRequireCloseMessage() { - return allowMissingCloseMessage; + return _requireCloseMessage; } - public void setAllowMissingCloseMessage(boolean allowMissingCloseMessage) + /** + * @param requireCloseMessage whether peers must send the TLS {@code close_notify} message + * @see SslConnection#setRequireCloseMessage(boolean) + */ + public void setRequireCloseMessage(boolean requireCloseMessage) { - this.allowMissingCloseMessage = allowMissingCloseMessage; + _requireCloseMessage = requireCloseMessage; } @Override @@ -95,7 +108,6 @@ public class SslClientConnectionFactory implements ClientConnectionFactory context.put(SSL_ENGINE_CONTEXT_KEY, engine); SslConnection sslConnection = newSslConnection(byteBufferPool, executor, endPoint, engine); - endPoint.setConnection(sslConnection); EndPoint appEndPoint = sslConnection.getDecryptedEndPoint(); appEndPoint.setConnection(connectionFactory.newConnection(appEndPoint, context)); @@ -119,7 +131,7 @@ public class SslClientConnectionFactory implements ClientConnectionFactory SslConnection sslConnection = (SslConnection)connection; sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed()); sslConnection.setRenegotiationLimit(sslContextFactory.getRenegotiationLimit()); - sslConnection.setAllowMissingCloseMessage(isAllowMissingCloseMessage()); + sslConnection.setRequireCloseMessage(isRequireCloseMessage()); ContainerLifeCycle client = (ContainerLifeCycle)context.get(ClientConnectionFactory.CLIENT_CONTEXT_KEY); if (client != null) client.getBeans(SslHandshakeListener.class).forEach(sslConnection::addHandshakeListener); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java index 35f603caa35..a23e92e9e9f 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io.ssl; @@ -25,12 +25,14 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.ToIntFunction; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.Status; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSession; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.AbstractEndPoint; @@ -41,9 +43,9 @@ import org.eclipse.jetty.io.WriteFlusher; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Invocable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A Connection that acts as an interceptor between an EndPoint providing SSL encrypted data @@ -77,12 +79,13 @@ import org.eclipse.jetty.util.thread.Invocable; */ public class SslConnection extends AbstractConnection implements Connection.UpgradeTo { - private static final Logger LOG = Log.getLogger(SslConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(SslConnection.class); private static final String TLS_1_3 = "TLSv1.3"; - private enum Handshake + private enum HandshakeState { INITIAL, + HANDSHAKE, SUCCEEDED, FAILED } @@ -113,10 +116,10 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr private boolean _renegotiationAllowed; private int _renegotiationLimit = -1; private boolean _closedOutbound; - private boolean _allowMissingCloseMessage = true; + private boolean _requireCloseMessage; private FlushState _flushState = FlushState.IDLE; private FillState _fillState = FillState.IDLE; - private AtomicReference _handshake = new AtomicReference<>(Handshake.INITIAL); + private AtomicReference _handshake = new AtomicReference<>(HandshakeState.INITIAL); private boolean _underflown; private abstract class RunnableTask implements Runnable, Invocable @@ -146,7 +149,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr @Override public InvocationType getInvocationType() { - return getDecryptedEndPoint().getFillInterest().getCallbackInvocationType(); + return _decryptedEndPoint.getFillInterest().getCallbackInvocationType(); } }; @@ -231,7 +234,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } /** - * @return The number of renegotions allowed for this connection. When the limit + * @return The number of renegotiations allowed for this connection. When the limit * is 0 renegotiation will be denied. If the limit is less than 0 then no limit is applied. */ public int getRenegotiationLimit() @@ -240,7 +243,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } /** - * @param renegotiationLimit The number of renegotions allowed for this connection. + * @param renegotiationLimit The number of renegotiations allowed for this connection. * When the limit is 0 renegotiation will be denied. If the limit is less than 0 then no limit is applied. * Default -1. */ @@ -249,20 +252,75 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr _renegotiationLimit = renegotiationLimit; } - public boolean isAllowMissingCloseMessage() + /** + * @return whether peers must send the TLS {@code close_notify} message + */ + public boolean isRequireCloseMessage() { - return _allowMissingCloseMessage; + return _requireCloseMessage; } - public void setAllowMissingCloseMessage(boolean allowMissingCloseMessage) + /** + *

      Sets whether it is required that a peer send the TLS {@code close_notify} message + * to indicate the will to close the connection, otherwise it may be interpreted as a + * truncation attack.

      + *

      This option is only useful on clients, since typically servers cannot accept + * connection-delimited content that may be truncated.

      + * + * @param requireCloseMessage whether peers must send the TLS {@code close_notify} message + */ + public void setRequireCloseMessage(boolean requireCloseMessage) { - this._allowMissingCloseMessage = allowMissingCloseMessage; + _requireCloseMessage = requireCloseMessage; + } + + private boolean isHandshakeInitial() + { + return _handshake.get() == HandshakeState.INITIAL; + } + + private boolean isHandshakeSucceeded() + { + return _handshake.get() == HandshakeState.SUCCEEDED; + } + + private boolean isHandshakeComplete() + { + HandshakeState state = _handshake.get(); + return state == HandshakeState.SUCCEEDED || state == HandshakeState.FAILED; + } + + private int getApplicationBufferSize() + { + return getBufferSize(SSLSession::getApplicationBufferSize); + } + + private int getPacketBufferSize() + { + return getBufferSize(SSLSession::getPacketBufferSize); + } + + private int getBufferSize(ToIntFunction bufferSizeFn) + { + SSLSession hsSession = _sslEngine.getHandshakeSession(); + SSLSession session = _sslEngine.getSession(); + int size = bufferSizeFn.applyAsInt(session); + if (hsSession == null || hsSession == session) + return size; + int hsSize = bufferSizeFn.applyAsInt(hsSession); + return Math.max(hsSize, size); } private void acquireEncryptedInput() { if (_encryptedInput == null) - _encryptedInput = _bufferPool.acquire(_sslEngine.getSession().getPacketBufferSize(), _encryptedDirectBuffers); + _encryptedInput = _bufferPool.acquire(getPacketBufferSize(), _encryptedDirectBuffers); + } + + private void acquireEncryptedOutput() + { + if (_encryptedOutput == null) + _encryptedOutput = _bufferPool.acquire(getPacketBufferSize(), _encryptedDirectBuffers); } @Override @@ -329,6 +387,16 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr _decryptedEndPoint.onFillableFail(cause == null ? new IOException() : cause); } + protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException + { + return sslEngine.wrap(input, output); + } + + protected SSLEngineResult unwrap(SSLEngine sslEngine, ByteBuffer input, ByteBuffer output) throws SSLException + { + return sslEngine.unwrap(input, output); + } + @Override public String toConnectionString() { @@ -350,6 +418,24 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr connection instanceof AbstractConnection ? ((AbstractConnection)connection).toConnectionString() : connection); } + private void releaseEncryptedInputBuffer() + { + if (_encryptedInput != null && !_encryptedInput.hasRemaining()) + { + _bufferPool.release(_encryptedInput); + _encryptedInput = null; + } + } + + protected void releaseDecryptedInputBuffer() + { + if (_decryptedInput != null && !_decryptedInput.hasRemaining()) + { + _bufferPool.release(_decryptedInput); + _decryptedInput = null; + } + } + private void releaseEncryptedOutputBuffer() { if (!Thread.holdsLock(_decryptedEndPoint)) @@ -361,9 +447,20 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } } - public class DecryptedEndPoint extends AbstractEndPoint + protected int networkFill(ByteBuffer input) throws IOException + { + return getEndPoint().fill(input); + } + + protected boolean networkFlush(ByteBuffer output) throws IOException + { + return getEndPoint().flush(output); + } + + public class DecryptedEndPoint extends AbstractEndPoint implements EndPoint.Wrapper { private final Callback _incompleteWriteCallback = new IncompleteWriteCallback(); + private Throwable _failure; public DecryptedEndPoint() { @@ -372,6 +469,12 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr super.setIdleTimeout(-1); } + @Override + public EndPoint unwrap() + { + return getEndPoint(); + } + @Override public long getIdleTimeout() { @@ -403,7 +506,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } @Override - protected WriteFlusher getWriteFlusher() + public WriteFlusher getWriteFlusher() { return super.getWriteFlusher(); } @@ -451,14 +554,10 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr LOG.debug("onFillableFail {}", SslConnection.this, failure); _fillState = FillState.IDLE; - switch (_flushState) + if (_flushState == FlushState.WAIT_FOR_FILL) { - case WAIT_FOR_FILL: - _flushState = FlushState.IDLE; - fail = true; - break; - default: - break; + _flushState = FlushState.IDLE; + fail = true; } } @@ -478,9 +577,12 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr { if (connection instanceof AbstractConnection) { - AbstractConnection a = (AbstractConnection)connection; - if (a.getInputBufferSize() < _sslEngine.getSession().getApplicationBufferSize()) - a.setInputBufferSize(_sslEngine.getSession().getApplicationBufferSize()); + // This is an optimization to avoid that upper layer connections use small + // buffers and we need to copy decrypted data rather than decrypting in place. + AbstractConnection c = (AbstractConnection)connection; + int appBufferSize = getApplicationBufferSize(); + if (c.getInputBufferSize() < appBufferSize) + c.setInputBufferSize(appBufferSize); } super.setConnection(connection); } @@ -529,12 +631,14 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr case NEED_WRAP: if (_flushState == FlushState.IDLE && flush(BufferUtil.EMPTY_BUFFER)) { + Throwable failure = _failure; + if (failure != null) + rethrow(failure); if (_sslEngine.isInboundDone()) - // TODO this is probably a JVM bug, work around it by -1 - return -1; + return filled = -1; continue; } - // handle in needsFillInterest + // Handle in needsFillInterest(). return filled = 0; default: @@ -545,12 +649,13 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr // can we use the passed buffer if it is big enough ByteBuffer appIn; + int appBufferSize = getApplicationBufferSize(); if (_decryptedInput == null) { - if (BufferUtil.space(buffer) > _sslEngine.getSession().getApplicationBufferSize()) + if (BufferUtil.space(buffer) > appBufferSize) appIn = buffer; else - appIn = _decryptedInput = _bufferPool.acquire(_sslEngine.getSession().getApplicationBufferSize(), _decryptedDirectBuffers); + appIn = _decryptedInput = _bufferPool.acquire(appBufferSize, _decryptedDirectBuffers); } else { @@ -559,14 +664,23 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } // Let's try reading some encrypted data... even if we have some already. - int netFilled = getEndPoint().fill(_encryptedInput); - + int netFilled = networkFill(_encryptedInput); if (LOG.isDebugEnabled()) LOG.debug("net filled={}", netFilled); - if (netFilled > 0 && _handshake.get() == Handshake.INITIAL && isOutboundDone()) + // Workaround for Java 11 behavior. + if (netFilled < 0 && isHandshakeInitial() && BufferUtil.isEmpty(_encryptedInput)) + closeInbound(); + + if (netFilled > 0 && !isHandshakeComplete() && isOutboundDone()) throw new SSLHandshakeException("Closed during handshake"); + if (_handshake.compareAndSet(HandshakeState.INITIAL, HandshakeState.HANDSHAKE)) + { + if (LOG.isDebugEnabled()) + LOG.debug("fill starting handshake {}", SslConnection.this); + } + // Let's unwrap even if we have no net data because in that // case we want to fall through to the handshake handling int pos = BufferUtil.flipToFill(appIn); @@ -574,7 +688,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr try { _underflown = false; - unwrapResult = _sslEngine.unwrap(_encryptedInput, appIn); + unwrapResult = SslConnection.this.unwrap(_sslEngine, _encryptedInput, appIn); } finally { @@ -598,6 +712,9 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr switch (unwrap) { case CLOSED: + Throwable failure = _failure; + if (failure != null) + rethrow(failure); return filled = -1; case BUFFER_UNDERFLOW: @@ -606,13 +723,33 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr _underflown = true; if (netFilled < 0 && _sslEngine.getUseClientMode()) { - closeInbound(); + Throwable closeFailure = closeInbound(); + if (_flushState == FlushState.WAIT_FOR_FILL) + { + Throwable handshakeFailure = new SSLHandshakeException("Abruptly closed by peer"); + if (closeFailure != null) + handshakeFailure.initCause(closeFailure); + throw handshakeFailure; + } return filled = -1; } return filled = netFilled; + case BUFFER_OVERFLOW: + // It's possible that SSLSession.applicationBufferSize has been expanded + // by the SSLEngine implementation. Unwrapping a large encrypted buffer + // causes BUFFER_OVERFLOW because the (old) applicationBufferSize is + // too small. Release the decrypted input buffer so it will be re-acquired + // with the larger capacity. + // See also system property "jsse.SSLEngine.acceptLargeFragments". + if (BufferUtil.isEmpty(_decryptedInput) && appBufferSize < getApplicationBufferSize()) + { + releaseDecryptedInputBuffer(); + continue; + } + throw new IllegalStateException("Unexpected unwrap result " + unwrap); + case OK: - { if (unwrapResult.getHandshakeStatus() == HandshakeStatus.FINISHED) handshakeSucceeded(); @@ -630,7 +767,6 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } break; - } default: throw new IllegalStateException("Unexpected unwrap result " + unwrap); @@ -639,29 +775,19 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - handshakeFailed(x); - + Throwable f = handleException(x, "fill"); + Throwable failure = handshakeFailed(f); if (_flushState == FlushState.WAIT_FOR_FILL) { _flushState = FlushState.IDLE; - getExecutor().execute(() -> _decryptedEndPoint.getWriteFlusher().onFail(x)); + getExecutor().execute(() -> _decryptedEndPoint.getWriteFlusher().onFail(failure)); } - - throw x; + throw failure; } finally { - if (_encryptedInput != null && !_encryptedInput.hasRemaining()) - { - _bufferPool.release(_encryptedInput); - _encryptedInput = null; - } - - if (_decryptedInput != null && !_decryptedInput.hasRemaining()) - { - _bufferPool.release(_decryptedInput); - _decryptedInput = null; - } + releaseEncryptedInputBuffer(); + releaseDecryptedInputBuffer(); if (_flushState == FlushState.WAIT_FOR_FILL) { @@ -676,10 +802,10 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - if (LOG.isDebugEnabled()) - LOG.debug(SslConnection.this.toString(), x); close(x); - throw x; + rethrow(x); + // Never reached. + throw new AssertionError(); } } @@ -694,15 +820,18 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr synchronized (_decryptedEndPoint) { if (LOG.isDebugEnabled()) - { - LOG.debug(">needFillInterest uf={} {}", _underflown, SslConnection.this); - LOG.debug("ei={} di={}", BufferUtil.toDetailString(_encryptedInput), BufferUtil.toDetailString(_decryptedInput)); - } + LOG.debug(">needFillInterest s={}/{} uf={} ei={} di={} {}", + _flushState, + _fillState, + _underflown, + BufferUtil.toDetailString(_encryptedInput), + BufferUtil.toDetailString(_decryptedInput), + SslConnection.this); if (_fillState != FillState.IDLE) return; - // Fillable if we have decrypted Input OR encrypted input that has not yet been underflown. + // Fillable if we have decrypted input OR enough encrypted input. fillable = BufferUtil.hasContent(_decryptedInput) || (BufferUtil.hasContent(_encryptedInput) && !_underflown); HandshakeStatus status = _sslEngine.getHandshakeStatus(); @@ -719,6 +848,11 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr { interest = true; _fillState = FillState.INTERESTED; + if (_flushState == FlushState.IDLE && BufferUtil.hasContent(_encryptedOutput)) + { + _flushState = FlushState.WRITING; + write = _encryptedOutput; + } } break; @@ -760,7 +894,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr private void handshakeSucceeded() throws SSLException { - if (_handshake.compareAndSet(Handshake.INITIAL, Handshake.SUCCEEDED)) + if (_handshake.compareAndSet(HandshakeState.HANDSHAKE, HandshakeState.SUCCEEDED)) { if (LOG.isDebugEnabled()) LOG.debug("handshake succeeded {} {} {}/{}", SslConnection.this, @@ -768,16 +902,16 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr _sslEngine.getSession().getProtocol(), _sslEngine.getSession().getCipherSuite()); notifyHandshakeSucceeded(_sslEngine); } - else if (_handshake.get() == Handshake.SUCCEEDED) + else if (isHandshakeSucceeded()) { if (_renegotiationLimit > 0) _renegotiationLimit--; } } - private void handshakeFailed(Throwable failure) + private Throwable handshakeFailed(Throwable failure) { - if (_handshake.compareAndSet(Handshake.INITIAL, Handshake.FAILED)) + if (_handshake.compareAndSet(HandshakeState.HANDSHAKE, HandshakeState.FAILED)) { if (LOG.isDebugEnabled()) LOG.debug("handshake failed {} {}", SslConnection.this, failure); @@ -785,6 +919,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr failure = new SSLHandshakeException(failure.getMessage()).initCause(failure); notifyHandshakeFailed(_sslEngine, failure); } + return failure; } private void terminateInput() @@ -795,27 +930,29 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } - private void closeInbound() throws SSLException + private Throwable closeInbound() throws SSLException { HandshakeStatus handshakeStatus = _sslEngine.getHandshakeStatus(); try { _sslEngine.closeInbound(); + return null; } catch (SSLException x) { - if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING && !isAllowMissingCloseMessage()) + if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING && isRequireCloseMessage()) throw x; - else - LOG.ignore(x); + LOG.trace("IGNORED", x); + return x; } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); + return x; } } @@ -837,7 +974,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } // finish of any previous flushes - if (BufferUtil.hasContent(_encryptedOutput) && !getEndPoint().flush(_encryptedOutput)) + if (BufferUtil.hasContent(_encryptedOutput) && !networkFlush(_encryptedOutput)) return false; boolean isEmpty = BufferUtil.isEmpty(appOuts); @@ -865,6 +1002,9 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr continue; case NEED_UNWRAP: + // Workaround for Java 11 behavior. + if (isHandshakeInitial() && isOutboundDone()) + break; if (_fillState == FillState.IDLE) { int filled = fill(BufferUtil.EMPTY_BUFFER); @@ -879,16 +1019,23 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr throw new IllegalStateException("Unexpected HandshakeStatus " + status); } - if (_encryptedOutput == null) - _encryptedOutput = _bufferPool.acquire(_sslEngine.getSession().getPacketBufferSize(), _encryptedDirectBuffers); + int packetBufferSize = getPacketBufferSize(); + acquireEncryptedOutput(); - // We call sslEngine.wrap to try to take bytes from appOut buffers and encrypt them into the _netOut buffer + if (_handshake.compareAndSet(HandshakeState.INITIAL, HandshakeState.HANDSHAKE)) + { + if (LOG.isDebugEnabled()) + LOG.debug("flush starting handshake {}", SslConnection.this); + } + + // We call sslEngine.wrap to try to take bytes from appOuts + // buffers and encrypt them into the _encryptedOutput buffer. BufferUtil.compact(_encryptedOutput); int pos = BufferUtil.flipToFill(_encryptedOutput); SSLEngineResult wrapResult; try { - wrapResult = _sslEngine.wrap(appOuts, _encryptedOutput); + wrapResult = wrap(_sslEngine, appOuts, _encryptedOutput); } finally { @@ -907,7 +1054,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr // if we have net bytes, let's try to flush them boolean flushed = true; if (BufferUtil.hasContent(_encryptedOutput)) - flushed = getEndPoint().flush(_encryptedOutput); + flushed = networkFlush(_encryptedOutput); if (LOG.isDebugEnabled()) LOG.debug("net flushed={}, ac={}", flushed, isEmpty); @@ -931,7 +1078,18 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr case BUFFER_OVERFLOW: if (!flushed) return result = false; - continue; + // It's possible that SSLSession.packetBufferSize has been expanded + // by the SSLEngine implementation. Wrapping a large application buffer + // causes BUFFER_OVERFLOW because the (old) packetBufferSize is + // too small. Release the encrypted output buffer so that it will + // be re-acquired with the larger capacity. + // See also system property "jsse.SSLEngine.acceptLargeFragments". + if (packetBufferSize < getPacketBufferSize()) + { + releaseEncryptedOutputBuffer(); + continue; + } + throw new IllegalStateException("Unexpected wrap result " + wrap); case OK: if (wrapResult.getHandshakeStatus() == HandshakeStatus.FINISHED) @@ -966,8 +1124,8 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - handshakeFailed(x); - throw x; + Throwable failure = handleException(x, "flush"); + throw handshakeFailed(failure); } finally { @@ -979,10 +1137,10 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - if (LOG.isDebugEnabled()) - LOG.debug(SslConnection.this.toString(), x); close(x); - throw x; + rethrow(x); + // Never reached. + throw new AssertionError(); } } @@ -1042,7 +1200,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (IOException e) { - LOG.debug(e); + LOG.debug("Incomplete flush?", e); close(e); write = BufferUtil.EMPTY_BUFFER; _flushState = FlushState.WRITING; @@ -1082,17 +1240,17 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr @Override public void doShutdownOutput() { - final EndPoint endp = getEndPoint(); + EndPoint endPoint = getEndPoint(); try { boolean close; boolean flush = false; synchronized (_decryptedEndPoint) { - boolean ishut = endp.isInputShutdown(); - boolean oshut = endp.isOutputShutdown(); + boolean ishut = endPoint.isInputShutdown(); + boolean oshut = endPoint.isOutputShutdown(); if (LOG.isDebugEnabled()) - LOG.debug("shutdownOutput: {} oshut={}, ishut={} {}", SslConnection.this, oshut, ishut); + LOG.debug("shutdownOutput: {} oshut={}, ishut={}", SslConnection.this, oshut, ishut); closeOutbound(); @@ -1110,27 +1268,40 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr { if (!flush(BufferUtil.EMPTY_BUFFER) && !close) { - Thread.yield(); - // if we still can't flush, but we are not closing the endpoint, + // If we still can't flush, but we are not closing the endpoint, // let's just flush the encrypted output in the background. - // and continue as if we are closed. The assumption here is that - // the encrypted buffer will contain the entire close handshake - // and that a call to flush(EMPTY_BUFFER) is not needed. - endp.write(Callback.from(() -> + ByteBuffer write = null; + synchronized (_decryptedEndPoint) { - }, t -> endp.close()), _encryptedOutput); + if (BufferUtil.hasContent(_encryptedOutput)) + { + write = _encryptedOutput; + _flushState = FlushState.WRITING; + } + } + if (write != null) + { + endPoint.write(Callback.from(() -> + { + synchronized (_decryptedEndPoint) + { + _flushState = FlushState.IDLE; + releaseEncryptedOutputBuffer(); + } + }, t -> endPoint.close()), write); + } } } if (close) - endp.close(); + endPoint.close(); else ensureFillInterested(); } catch (Throwable x) { - LOG.ignore(x); - endp.close(); + LOG.trace("IGNORED", x); + endPoint.close(); } } @@ -1142,7 +1313,8 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - LOG.ignore(x); + if (LOG.isDebugEnabled()) + LOG.debug("Unable to close outbound", x); } } @@ -1167,7 +1339,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); return true; } } @@ -1201,7 +1373,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); return true; } } @@ -1248,7 +1420,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr private boolean isRenegotiating() { - if (_handshake.get() == Handshake.INITIAL) + if (!isHandshakeComplete()) return false; if (isTLS13()) return false; @@ -1284,6 +1456,37 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr return TLS_1_3.equals(protocol); } + private Throwable handleException(Throwable x, String context) + { + synchronized (_decryptedEndPoint) + { + if (_failure == null) + { + _failure = x; + if (LOG.isDebugEnabled()) + LOG.debug(this + " stored " + context + " exception", x); + } + else if (x != _failure) + { + _failure.addSuppressed(x); + if (LOG.isDebugEnabled()) + LOG.debug(this + " suppressed " + context + " exception", x); + } + return _failure; + } + } + + private void rethrow(Throwable x) throws IOException + { + if (x instanceof RuntimeException) + throw (RuntimeException)x; + if (x instanceof Error) + throw (Error)x; + if (x instanceof IOException) + throw (IOException)x; + throw new IOException(x); + } + @Override public String toString() { @@ -1296,19 +1499,23 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr public void succeeded() { boolean fillable; + boolean interested; synchronized (_decryptedEndPoint) { if (LOG.isDebugEnabled()) LOG.debug("IncompleteWriteCB succeeded {}", SslConnection.this); - releaseEncryptedOutputBuffer(); _flushState = FlushState.IDLE; + + interested = _fillState == FillState.INTERESTED; fillable = _fillState == FillState.WAIT_FOR_FLUSH; if (fillable) _fillState = FillState.IDLE; } - if (fillable) + if (interested) + ensureFillInterested(); + else if (fillable) _decryptedEndPoint.getFillInterest().fillable(); _decryptedEndPoint.getWriteFlusher().completeWrite(); @@ -1327,7 +1534,8 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr releaseEncryptedOutputBuffer(); _flushState = FlushState.IDLE; - failFillInterest = _fillState == FillState.WAIT_FOR_FLUSH; + failFillInterest = _fillState == FillState.WAIT_FOR_FLUSH || + _fillState == FillState.INTERESTED; if (failFillInterest) _fillState = FillState.IDLE; } @@ -1352,5 +1560,6 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr return String.format("SSL@%h.DEP.writeCallback", SslConnection.this); } } + } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslHandshakeListener.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslHandshakeListener.java index 22c5924c9ac..60afd682883 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslHandshakeListener.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslHandshakeListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io.ssl; @@ -35,6 +35,7 @@ public interface SslHandshakeListener extends EventListener *

      Callback method invoked when the TLS handshake succeeds.

      * * @param event the event object carrying information about the TLS handshake event + * @throws SSLException if any error happen during handshake */ default void handshakeSucceeded(Event event) throws SSLException { diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java index 42403dc5dfe..49ddb335d5a 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java index 57d6b496a6d..0f290c12800 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java index 01dc31af16f..0df2d34c233 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/CyclicTimeoutTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/CyclicTimeoutTest.java index e9438fd43d8..fc002a72b6e 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/CyclicTimeoutTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/CyclicTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -146,10 +146,10 @@ public class CyclicTimeoutTest QueuedThreadPool pool = new QueuedThreadPool(200); pool.start(); - long test_until = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(1500); + long testUntil = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(1500); assertTrue(_timeout.schedule(100, TimeUnit.MILLISECONDS)); - while (System.nanoTime() < test_until) + while (System.nanoTime() < testUntil) { CountDownLatch latch = new CountDownLatch(1); pool.execute(() -> diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java index a9b198eaced..493eea69f9b 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -43,6 +43,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.OS; @@ -53,7 +54,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; public class IOTest { @@ -93,14 +93,8 @@ public class IOTest assertEquals(-1, server.getInputStream().read()); // but cannot write - try - { - client.getOutputStream().write(1); - fail("exception expected"); - } - catch (SocketException expected) - { - } + Assertions.assertThrows(SocketException.class, () -> client.getOutputStream().write(1)); + // but can still write in opposite direction. server.getOutputStream().write(1); @@ -110,14 +104,7 @@ public class IOTest server.shutdownInput(); // now we EOF instead of reading -1 - try - { - server.getInputStream().read(); - fail("exception expected"); - } - catch (SocketException expected) - { - } + Assertions.assertThrows(SocketException.class, () -> server.getInputStream().read()); // but can still write in opposite direction. server.getOutputStream().write(1); @@ -127,14 +114,7 @@ public class IOTest client.shutdownInput(); // now we EOF instead of reading -1 - try - { - client.getInputStream().read(); - fail("exception expected"); - } - catch (SocketException expected) - { - } + Assertions.assertThrows(SocketException.class, () -> client.getInputStream().read()); // But we can still write at the server (data which will never be read) server.getOutputStream().write(1); @@ -146,14 +126,7 @@ public class IOTest server.shutdownOutput(); // and now we can't write - try - { - server.getOutputStream().write(1); - fail("exception expected"); - } - catch (SocketException expected) - { - } + Assertions.assertThrows(SocketException.class, () -> server.getOutputStream().write(1)); // but the sockets are still open assertFalse(client.isClosed()); diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java index 31881fa559d..0ce738e637c 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java index 5bd536b48cf..16e20928e78 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/NIOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/NIOTest.java index 3dd1a65f5b1..1540ae9818f 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/NIOTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/NIOTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectorManagerTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectorManagerTest.java index 0c3845616fd..5d3ca7e2772 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectorManagerTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectorManagerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java index cebf4594434..3ee35a3f160 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java index b3fa6288093..5d6feb44f63 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java index 7970e1e0e8c..537174b8625 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -48,8 +48,6 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.Scheduler; @@ -62,6 +60,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; @@ -75,7 +75,7 @@ import static org.junit.jupiter.api.Assertions.fail; @SuppressWarnings("Duplicates") public class SocketChannelEndPointTest { - private static final Logger LOG = Log.getLogger(SocketChannelEndPoint.class); + private static final Logger LOG = LoggerFactory.getLogger(SocketChannelEndPoint.class); public interface Scenario { @@ -630,10 +630,9 @@ public class SocketChannelEndPointTest public SslScenario(NormalScenario normalScenario) throws Exception { _normalScenario = normalScenario; - File keystore = MavenTestingUtils.getTestResourceFile("keystore"); + File keystore = MavenTestingUtils.getTestResourceFile("keystore.p12"); _sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); _sslCtxFactory.setKeyStorePassword("storepwd"); - _sslCtxFactory.setKeyManagerPassword("keypwd"); _sslCtxFactory.start(); } @@ -674,7 +673,7 @@ public class SocketChannelEndPointTest @SuppressWarnings("Duplicates") public static class TestConnection extends AbstractConnection { - private static final Logger LOG = Log.getLogger(TestConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(TestConnection.class); volatile FutureCallback _blockingRead; final AtomicInteger _blockAt; @@ -744,7 +743,7 @@ public class SocketChannelEndPointTest return; } - EndPoint _endp = getEndPoint(); + EndPoint endp = getEndPoint(); try { _last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); @@ -757,17 +756,17 @@ public class SocketChannelEndPointTest BufferUtil.compact(_in); if (BufferUtil.isFull(_in)) throw new IllegalStateException("FULL " + BufferUtil.toDetailString(_in)); - int filled = _endp.fill(_in); + int filled = endp.fill(_in); if (filled > 0) progress = true; // If the tests wants to block, then block - while (_blockAt.get() > 0 && _endp.isOpen() && _in.remaining() < _blockAt.get()) + while (_blockAt.get() > 0 && endp.isOpen() && _in.remaining() < _blockAt.get()) { FutureCallback future = _blockingRead = new FutureCallback(); fillInterested(); future.get(); - filled = _endp.fill(_in); + filled = endp.fill(_in); progress |= filled > 0; } @@ -783,18 +782,18 @@ public class SocketChannelEndPointTest for (int i = 0; i < _writeCount.get(); i++) { FutureCallback blockingWrite = new FutureCallback(); - _endp.write(blockingWrite, out.asReadOnlyBuffer()); + endp.write(blockingWrite, out.asReadOnlyBuffer()); blockingWrite.get(); } progress = true; } // are we done? - if (_endp.isInputShutdown()) - _endp.shutdownOutput(); + if (endp.isInputShutdown()) + endp.shutdownOutput(); } - if (_endp.isOpen()) + if (endp.isOpen()) fillInterested(); } catch (ExecutionException e) @@ -803,9 +802,9 @@ public class SocketChannelEndPointTest try { FutureCallback blockingWrite = new FutureCallback(); - _endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in))); + endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in))); blockingWrite.get(); - _endp.shutdownOutput(); + endp.shutdownOutput(); } catch (Exception e2) { @@ -815,13 +814,13 @@ public class SocketChannelEndPointTest catch (InterruptedException | EofException e) { if (LOG.isDebugEnabled()) - LOG.debug(e); + LOG.debug("Fill interrupted", e); else LOG.info(e.getClass().getName()); } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to fill from endpoint", e); } } } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java index 92395418ceb..3ad5bdd737e 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -42,7 +42,6 @@ import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.Scheduler; @@ -50,6 +49,8 @@ import org.eclipse.jetty.util.thread.TimerScheduler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -60,6 +61,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class SslConnectionTest { + private static final Logger LOG = LoggerFactory.getLogger(SslConnectionTest.class); + private static final int TIMEOUT = 1000000; private static ByteBufferPool __byteBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()); @@ -141,10 +144,9 @@ public class SslConnectionTest @BeforeEach public void initSSL() throws Exception { - File keystore = MavenTestingUtils.getTestResourceFile("keystore"); + File keystore = MavenTestingUtils.getTestResourceFile("keystore.p12"); _sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); _sslCtxFactory.setKeyStorePassword("storepwd"); - _sslCtxFactory.setKeyManagerPassword("keypwd"); _sslCtxFactory.setRenegotiationAllowed(true); _sslCtxFactory.setRenegotiationLimit(-1); startManager(); @@ -251,11 +253,11 @@ public class SslConnectionTest } catch (InterruptedException | EofException e) { - Log.getRootLogger().ignore(e); + LOG.trace("IGNORED", e); } catch (Exception e) { - Log.getRootLogger().warn(e); + LOG.warn("During onFillable", e); } finally { @@ -460,6 +462,7 @@ public class SslConnectionTest } catch (SocketTimeoutException e) { + // no op } assertTrue(__onIncompleteFlush.get()); @@ -483,9 +486,6 @@ public class SslConnectionTest server.configureBlocking(false); _manager.accept(server); - //__startBlocking.set(5); - //__blockFor.set(3); - client.getOutputStream().write("Short".getBytes(StandardCharsets.UTF_8)); byte[] buffer = new byte[1024]; int len = client.getInputStream().read(buffer); @@ -506,13 +506,14 @@ public class SslConnectionTest } catch (SocketTimeoutException e) { + // no op } __blockFor.set(0); assertTrue(__onIncompleteFlush.get()); ((TestEP)_lastEndp).getWriteFlusher().completeWrite(); len = client.getInputStream().read(buffer); - assertThat(len, is(len)); + assertThat(len, is(-1)); } } } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java index d4b475b2969..24742f85de2 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -44,10 +44,9 @@ public class SslEngineBehaviorTest public static void startSsl() throws Exception { sslCtxFactory = new SslContextFactory.Server(); - File keystore = MavenTestingUtils.getTestResourceFile("keystore"); + File keystore = MavenTestingUtils.getTestResourceFile("keystore.p12"); sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); sslCtxFactory.setKeyStorePassword("storepwd"); - sslCtxFactory.setKeyManagerPassword("keypwd"); sslCtxFactory.start(); } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java index 7a062d9b72a..c2fbc7f91ee 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io; @@ -32,10 +32,10 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; diff --git a/jetty-io/src/test/resources/jetty-logging.properties b/jetty-io/src/test/resources/jetty-logging.properties index 257743ed54b..a83221a9354 100644 --- a/jetty-io/src/test/resources/jetty-logging.properties +++ b/jetty-io/src/test/resources/jetty-logging.properties @@ -1,5 +1,5 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=INFO +# Jetty Logging using jetty-slf4j-impl +#org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.io.AbstractConnection.LEVEL=DEBUG #org.eclipse.jetty.io.ManagedSelector.LEVEL=DEBUG #org.eclipse.jetty.io.ssl.SslConnection.LEVEL=DEBUG diff --git a/jetty-io/src/test/resources/keystore b/jetty-io/src/test/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/jetty-io/src/test/resources/keystore and /dev/null differ diff --git a/jetty-io/src/test/resources/keystore.p12 b/jetty-io/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..db99d3d2734 Binary files /dev/null and b/jetty-io/src/test/resources/keystore.p12 differ diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 6662377bb20..0645ecf6288 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -42,13 +42,17 @@
      - org.eclipse.jetty.toolchain - jetty-test-helper + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl test - org.slf4j - slf4j-simple + org.eclipse.jetty.toolchain + jetty-test-helper test diff --git a/jetty-jaas/src/main/java/module-info.java b/jetty-jaas/src/main/java/module-info.java index c1297ab33a6..848615dea70 100644 --- a/jetty-jaas/src/main/java/module-info.java +++ b/jetty-jaas/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.jaas @@ -22,11 +22,8 @@ module org.eclipse.jetty.jaas exports org.eclipse.jetty.jaas.callback; exports org.eclipse.jetty.jaas.spi; - requires java.naming; - requires jetty.servlet.api; - requires org.eclipse.jetty.security; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.security; + requires org.slf4j; // Only required if using JDBCLoginModule. requires static java.sql; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASLoginService.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASLoginService.java index 60676da4f9b..23ec9436cde 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASLoginService.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; @@ -48,8 +48,8 @@ import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JAASLoginService @@ -60,7 +60,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JAASLoginService extends AbstractLifeCycle implements LoginService { - private static final Logger LOG = Log.getLogger(JAASLoginService.class); + private static final Logger LOG = LoggerFactory.getLogger(JAASLoginService.class); public static final String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.jaas.JAASRole"; public static final String[] DEFAULT_ROLE_CLASS_NAMES = {DEFAULT_ROLE_CLASS_NAME}; @@ -263,7 +263,7 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return null; } @@ -293,7 +293,7 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService } catch (LoginException e) { - LOG.warn(e); + LOG.warn("Failed to logout {}", user, e); } } diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java index 8fc5fdcc60f..a95075dd3ce 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASRole.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASRole.java index dddcf622ff2..4c8a6f8cd1a 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASRole.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASRole.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASUserPrincipal.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASUserPrincipal.java index 7106edd0239..9eb707f2d39 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASUserPrincipal.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASUserPrincipal.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/AbstractCallbackHandler.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/AbstractCallbackHandler.java index 108698b32df..3355e5c8141 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/AbstractCallbackHandler.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/AbstractCallbackHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.callback; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/DefaultCallbackHandler.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/DefaultCallbackHandler.java index 8739b5cc4a1..af79ba52280 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/DefaultCallbackHandler.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/DefaultCallbackHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.callback; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ObjectCallback.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ObjectCallback.java index 80704993b1f..2dc52f03e44 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ObjectCallback.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ObjectCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.callback; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/RequestParameterCallback.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/RequestParameterCallback.java index ab2afd77e80..a8cff55d4c1 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/RequestParameterCallback.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/RequestParameterCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.callback; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ServletRequestCallback.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ServletRequestCallback.java index bfec2f2126c..2d19de16617 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ServletRequestCallback.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/ServletRequestCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.callback; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/package-info.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/package-info.java index 824fdbafb48..073c0e069c2 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/package-info.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/callback/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/package-info.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/package-info.java index 79af1aad7e6..66fbe3c42b2 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/package-info.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractDatabaseLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractDatabaseLoginModule.java index ba6cd500b1c..d28af395ef8 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractDatabaseLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractDatabaseLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; @@ -27,9 +27,9 @@ import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractDatabaseLoginModule @@ -40,7 +40,7 @@ import org.eclipse.jetty.util.security.Credential; */ public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule { - private static final Logger LOG = Log.getLogger(AbstractDatabaseLoginModule.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractDatabaseLoginModule.class); private String userQuery; private String rolesQuery; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractLoginModule.java index 1b56e592633..2bbb253b7f3 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/AbstractLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; @@ -179,10 +179,6 @@ public abstract class AbstractLoginModule implements LoginModule this.commitState = commitState; } - /** - * @throws LoginException if unable to abort - * @see javax.security.auth.spi.LoginModule#abort() - */ @Override public boolean abort() throws LoginException { diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.java index 1ba08cd580d..624bde40db3 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/JDBCLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/JDBCLoginModule.java index 571e3cad6c2..df1b4627acc 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/JDBCLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/JDBCLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; @@ -25,8 +25,8 @@ import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JDBCLoginModule @@ -39,7 +39,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JDBCLoginModule extends AbstractDatabaseLoginModule { - private static final Logger LOG = Log.getLogger(JDBCLoginModule.class); + private static final Logger LOG = LoggerFactory.getLogger(JDBCLoginModule.class); private String dbDriver; private String dbUrl; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java index 6a7e936acca..9aa236f822c 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/LdapLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; @@ -46,9 +46,9 @@ import javax.security.auth.login.LoginException; import org.eclipse.jetty.jaas.callback.ObjectCallback; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A LdapLoginModule for use with JAAS setups @@ -84,7 +84,7 @@ import org.eclipse.jetty.util.security.Credential; */ public class LdapLoginModule extends AbstractLoginModule { - private static final Logger LOG = Log.getLogger(LdapLoginModule.class); + private static final Logger LOG = LoggerFactory.getLogger(LdapLoginModule.class); /** * hostname of the ldap server @@ -450,17 +450,13 @@ public class LdapLoginModule extends AbstractLoginModule catch (IOException e) { if (_debug) - { - LOG.info(e); - } + LOG.info("Login failure", e); throw new LoginException("IO Error performing login."); } catch (AuthenticationException e) { if (_debug) - { - LOG.info(e); - } + LOG.info("Login failure", e); return false; } catch (LoginException e) @@ -470,7 +466,7 @@ public class LdapLoginModule extends AbstractLoginModule catch (Exception e) { if (_debug) - LOG.info(e); + LOG.info("Login failure", e); throw new LoginException("Error obtaining user info"); } } diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.java index 4626e4a7709..73b733e5061 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; @@ -23,16 +23,15 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; - import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import org.eclipse.jetty.security.AbstractLoginService; import org.eclipse.jetty.security.PropertyUserStore; import org.eclipse.jetty.server.UserIdentity; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PropertyFileLoginModule @@ -41,7 +40,7 @@ public class PropertyFileLoginModule extends AbstractLoginModule { public static final String DEFAULT_FILENAME = "realm.properties"; - private static final Logger LOG = Log.getLogger(PropertyFileLoginModule.class); + private static final Logger LOG = LoggerFactory.getLogger(PropertyFileLoginModule.class); private static ConcurrentHashMap _propertyUserStores = new ConcurrentHashMap(); diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/UserInfo.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/UserInfo.java index 18866601d52..5d47d117d70 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/UserInfo.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/UserInfo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/package-info.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/package-info.java index 22b8001adff..6ba6843050a 100644 --- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/package-info.java +++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/spi/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java index fd77a0398fe..0f7b1ff7aed 100644 --- a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java +++ b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLdapLoginServiceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; diff --git a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLoginServiceTest.java b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLoginServiceTest.java index b4e82633eea..75a7cff3871 100644 --- a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLoginServiceTest.java +++ b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/JAASLoginServiceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; diff --git a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/TestLoginModule.java b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/TestLoginModule.java index c09e39f1ac3..20868dbe870 100644 --- a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/TestLoginModule.java +++ b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/TestLoginModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas; diff --git a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModuleTest.java b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModuleTest.java index 7f9cd1cafc5..e3e49923a21 100644 --- a/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModuleTest.java +++ b/jetty-jaas/src/test/java/org/eclipse/jetty/jaas/spi/PropertyFileLoginModuleTest.java @@ -1,38 +1,37 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jaas.spi; +import java.io.File; +import java.util.HashMap; +import javax.security.auth.Subject; + +import org.eclipse.jetty.jaas.callback.DefaultCallbackHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.jupiter.api.Test; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; -import java.io.File; -import java.util.HashMap; - -import javax.security.auth.Subject; - -import org.eclipse.jetty.jaas.callback.DefaultCallbackHandler; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.junit.jupiter.api.Test; - public class PropertyFileLoginModuleTest { @Test diff --git a/jetty-jaas/src/test/resources/jetty-logging.properties b/jetty-jaas/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..f0773d90fa5 --- /dev/null +++ b/jetty-jaas/src/test/resources/jetty-logging.properties @@ -0,0 +1,3 @@ +# Jetty Logging using jetty-slf4j-impl +org.eclipse.jetty.LEVEL=INFO +org.apache.directory.LEVEL=ERROR \ No newline at end of file diff --git a/jetty-jaas/src/test/resources/simplelogger.properties b/jetty-jaas/src/test/resources/simplelogger.properties deleted file mode 100644 index 921e53daa3a..00000000000 --- a/jetty-jaas/src/test/resources/simplelogger.properties +++ /dev/null @@ -1 +0,0 @@ -org.slf4j.simpleLogger.log.org.apache.directory=error \ No newline at end of file diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index d4691812295..6a8f17b899b 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -23,6 +23,24 @@ org.eclipse.jetty.jaspi.* + + org.apache.felix + maven-bundle-plugin + true + + + + manifest + + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory + + + + + @@ -32,6 +50,15 @@ jetty-security ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-jaspi/src/main/java/module-info.java b/jetty-jaspi/src/main/java/module-info.java index cc3333e34dd..c24a9d13b12 100644 --- a/jetty-jaspi/src/main/java/module-info.java +++ b/jetty-jaspi/src/main/java/module-info.java @@ -1,21 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.jaspi.JaspiAuthenticatorFactory; + module org.eclipse.jetty.security.jaspi { exports org.eclipse.jetty.security.jaspi; @@ -24,8 +27,8 @@ module org.eclipse.jetty.security.jaspi requires javax.security.auth.message; requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.security; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.security; + requires org.slf4j; + + provides Authenticator.Factory with JaspiAuthenticatorFactory; } diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java index 122a980edfd..a005f5f6528 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; @@ -44,15 +44,15 @@ import org.eclipse.jetty.security.authentication.SessionAuthentication; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Authentication.User; import org.eclipse.jetty.server.UserIdentity; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ */ public class JaspiAuthenticator extends LoginAuthenticator { - private static final Logger LOG = Log.getLogger(JaspiAuthenticator.class.getName()); + private static final Logger LOG = LoggerFactory.getLogger(JaspiAuthenticator.class.getName()); private final ServerAuthConfig _authConfig; @@ -94,9 +94,6 @@ public class JaspiAuthenticator extends LoginAuthenticator return "JASPI"; } - /** - * @see org.eclipse.jetty.security.authentication.LoginAuthenticator#login(java.lang.String, java.lang.Object, javax.servlet.ServletRequest) - */ @Override public UserIdentity login(String username, Object password, ServletRequest request) { diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java index eba7fcf57e9..cfbf05c9e23 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; @@ -37,12 +37,12 @@ import org.eclipse.jetty.security.DefaultAuthenticatorFactory; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory { - private static final Logger LOG = Log.getLogger(JaspiAuthenticatorFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(JaspiAuthenticatorFactory.class); private static String MESSAGE_LAYER = "HTTP"; @@ -120,7 +120,7 @@ public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory } catch (AuthException e) { - LOG.warn(e); + LOG.warn("Failed to get ServerAuthConfig", e); } return authenticator; } diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java index 7f429a9719d..215a27aa1d7 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java index f342c6618ed..7d11c144791 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/ServletCallbackHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/SimpleAuthConfig.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/SimpleAuthConfig.java index 27d623f6ede..46bcf880e68 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/SimpleAuthConfig.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/SimpleAuthConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java index e2e1a318901..13f0e48395d 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/CredentialValidationCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi.callback; diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/package-info.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/package-info.java index 750d5502692..58ea090280f 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/package-info.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/callback/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java index 3a7bf1487a5..9f47caa1a70 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BaseAuthModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi.modules; diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/UserInfo.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/UserInfo.java index d7c7ea99bfe..d6ad1b1f4b0 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/UserInfo.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/UserInfo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi.modules; diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/package-info.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/package-info.java index eae72c4f105..504e912c841 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/package-info.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/package-info.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/package-info.java index f907bd3fd87..fa169ae24b1 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/package-info.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jaspi/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory b/jetty-jaspi/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory new file mode 100644 index 00000000000..2e24fa8ca2a --- /dev/null +++ b/jetty-jaspi/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory @@ -0,0 +1 @@ +org.eclipse.jetty.security.jaspi.JaspiAuthenticatorFactory \ No newline at end of file diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java b/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/BasicAuthModule.java similarity index 73% rename from jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java rename to jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/BasicAuthModule.java index 16ed2106783..7b7f412af1e 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/modules/BasicAuthModule.java +++ b/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/BasicAuthModule.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.security.jaspi.modules; +package org.eclipse.jetty.security.jaspi; import java.io.IOException; import java.util.Map; @@ -31,14 +31,14 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.security.jaspi.modules.BaseAuthModule; import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -@Deprecated public class BasicAuthModule extends BaseAuthModule { - private static final Logger LOG = Log.getLogger(BasicAuthModule.class); + private static final Logger LOG = LoggerFactory.getLogger(BasicAuthModule.class); private String realmName; diff --git a/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/HttpHeaderAuthModule.java b/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/HttpHeaderAuthModule.java index 533c9837340..4848d589637 100644 --- a/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/HttpHeaderAuthModule.java +++ b/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/HttpHeaderAuthModule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; diff --git a/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/JaspiTest.java b/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/JaspiTest.java index 5b0890de3af..d8f34c2ac18 100644 --- a/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/JaspiTest.java +++ b/jetty-jaspi/src/test/java/org/eclipse/jetty/security/jaspi/JaspiTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.jaspi; @@ -69,18 +69,12 @@ public class JaspiTest _roles.put(username, roles); } - /** - * @see org.eclipse.jetty.security.AbstractLoginService#loadRoleInfo(org.eclipse.jetty.security.AbstractLoginService.UserPrincipal) - */ @Override protected String[] loadRoleInfo(UserPrincipal user) { return _roles.get(user.getName()); } - /** - * @see org.eclipse.jetty.security.AbstractLoginService#loadUserInfo(java.lang.String) - */ @Override protected UserPrincipal loadUserInfo(String username) { diff --git a/jetty-jaspi/src/test/resources/jaspi.xml b/jetty-jaspi/src/test/resources/jaspi.xml index 23a2ba5c7ed..1e31d2c996b 100644 --- a/jetty-jaspi/src/test/resources/jaspi.xml +++ b/jetty-jaspi/src/test/resources/jaspi.xml @@ -10,7 +10,7 @@ true - org.eclipse.jetty.security.jaspi.modules.BasicAuthModule + org.eclipse.jetty.security.jaspi.BasicAuthModule org.eclipse.jetty.security.jaspi.modules.RealmName=TestRealm diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java index 61419271778..1ffa2eb53b5 100644 --- a/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java +++ b/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; @@ -71,37 +71,37 @@ public class StringReplaceBenchmark } @Benchmark - public void testJavaStringReplace_Growth(Blackhole blackhole) + public void testJavaStringReplaceGrowth(Blackhole blackhole) { blackhole.consume(input.replace("'", "FOOBAR")); } @Benchmark - public void testJavaStringReplace_Same(Blackhole blackhole) + public void testJavaStringReplaceSame(Blackhole blackhole) { blackhole.consume(input.replace("'", "X")); } @Benchmark - public void testJavaStringReplace_Reduce(Blackhole blackhole) + public void testJavaStringReplaceReduce(Blackhole blackhole) { blackhole.consume(input.replace("'", "")); } @Benchmark - public void testJettyStringUtilReplace_Growth(Blackhole blackhole) + public void testJettyStringUtilReplaceGrowth(Blackhole blackhole) { blackhole.consume(StringUtil.replace(input, "'", "FOOBAR")); } @Benchmark - public void testJettyStringUtilReplace_Same(Blackhole blackhole) + public void testJettyStringUtilReplaceSame(Blackhole blackhole) { blackhole.consume(StringUtil.replace(input, "'", "X")); } @Benchmark - public void testJettyStringUtilReplace_Reduce(Blackhole blackhole) + public void testJettyStringUtilReplaceReduce(Blackhole blackhole) { blackhole.consume(StringUtil.replace(input, "'", "")); } diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ReservedThreadPoolBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ReservedThreadPoolBenchmark.java new file mode 100644 index 00000000000..e1438561be5 --- /dev/null +++ b/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ReservedThreadPoolBenchmark.java @@ -0,0 +1,147 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.util.thread.jmh; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.ReservedThreadExecutor; +import org.eclipse.jetty.util.thread.TryExecutor; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 2000, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 3, time = 2000, timeUnit = TimeUnit.MILLISECONDS) +public class ReservedThreadPoolBenchmark +{ + public enum Type + { + RTP + } + + @Param({"RTP"}) + Type type; + + @Param({"0", "8", "32"}) + int size; + + QueuedThreadPool qtp; + TryExecutor pool; + + @Setup // (Level.Iteration) + public void buildPool() + { + qtp = new QueuedThreadPool(); + switch (type) + { + case RTP: + { + ReservedThreadExecutor pool = new ReservedThreadExecutor(qtp, size); + pool.setIdleTimeout(1, TimeUnit.SECONDS); + this.pool = pool; + break; + } + } + LifeCycle.start(qtp); + LifeCycle.start(pool); + } + + @TearDown // (Level.Iteration) + public void shutdownPool() + { + LifeCycle.stop(pool); + LifeCycle.stop(qtp); + pool = null; + qtp = null; + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @Threads(1) + public void testFew() throws Exception + { + doJob(); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @Threads(8) + public void testSome() throws Exception + { + doJob(); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @Threads(200) + public void testMany() throws Exception + { + doJob(); + } + + void doJob() throws Exception + { + CountDownLatch latch = new CountDownLatch(1); + Runnable task = () -> + { + Blackhole.consumeCPU(1); + Thread.yield(); + Blackhole.consumeCPU(1); + latch.countDown(); + Blackhole.consumeCPU(1); + }; + if (!pool.tryExecute(task)) + qtp.execute(task); + latch.await(); + } + + public static void main(String[] args) throws RunnerException + { + Options opt = new OptionsBuilder() + .include(ReservedThreadPoolBenchmark.class.getSimpleName()) + .forks(1) + // .threads(400) + // .syncIterations(true) // Don't start all threads at same time + // .addProfiler(CompilerProfiler.class) + // .addProfiler(LinuxPerfProfiler.class) + // .addProfiler(LinuxPerfNormProfiler.class) + // .addProfiler(LinuxPerfAsmProfiler.class) + // .resultFormat(ResultFormatType.CSV) + .build(); + + new Runner(opt).run(); + } +} diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 639ef6aaa5f..b0478007d16 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -18,7 +18,7 @@ maven-surefire-plugin - @{argLine} ${jetty.surefire.argLine} --add-opens org.eclipse.jetty.jmx/org.eclipse.jetty.jmx=ALL-UNNAMED --add-opens org.eclipse.jetty.jmx/org.eclipse.jetty.util.log.jmx=ALL-UNNAMED + @{argLine} ${jetty.surefire.argLine} --add-opens org.eclipse.jetty.jmx/org.eclipse.jetty.jmx=ALL-UNNAMED --add-opens org.eclipse.jetty.jmx/org.eclipse.jetty.logging.jmx=ALL-UNNAMED @@ -32,17 +32,25 @@ - - org.eclipse.jetty.toolchain - jetty-test-helper - test - org.eclipse.jetty jetty-util ${project.version} - + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + com.openpojo openpojo diff --git a/jetty-jmx/src/main/config/etc/jetty-jmx.xml b/jetty-jmx/src/main/config/etc/jetty-jmx.xml index 24c0e2031d4..052fa7cc506 100644 --- a/jetty-jmx/src/main/config/etc/jetty-jmx.xml +++ b/jetty-jmx/src/main/config/etc/jetty-jmx.xml @@ -21,12 +21,5 @@ - - - - - - - diff --git a/jetty-jmx/src/main/java/module-info.java b/jetty-jmx/src/main/java/module-info.java index 908b16a5480..8036a54102b 100644 --- a/jetty-jmx/src/main/java/module-info.java +++ b/jetty-jmx/src/main/java/module-info.java @@ -1,31 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.jmx { exports org.eclipse.jetty.jmx; - requires org.eclipse.jetty.util; + // Applications that use ObjectMBean must use JMX classes too. + requires transitive java.management; + requires transitive org.eclipse.jetty.util; + requires org.slf4j; // Only required if using ConnectorServer. requires static java.management.rmi; requires static java.rmi; - - // Applications that use ObjectMBean must use JMX classes too. - requires transitive java.management; } diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java index 2d8b10f29eb..6a287c07226 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -43,10 +43,10 @@ import javax.rmi.ssl.SslRMIClientSocketFactory; import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.ShutdownThread; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      LifeCycle wrapper for JMXConnectorServer.

      @@ -61,7 +61,7 @@ import org.eclipse.jetty.util.thread.ShutdownThread; public class ConnectorServer extends AbstractLifeCycle { public static final String RMI_REGISTRY_CLIENT_SOCKET_FACTORY_ATTRIBUTE = "com.sun.jndi.rmi.factory.socket"; - private static final Logger LOG = Log.getLogger(ConnectorServer.class); + private static final Logger LOG = LoggerFactory.getLogger(ConnectorServer.class); private JMXServiceURL _jmxURL; private final Map _environment; @@ -183,7 +183,7 @@ public class ConnectorServer extends AbstractLifeCycle } catch (Throwable ex) { - LOG.ignore(ex); + LOG.trace("IGNORED", ex); } RMIClientSocketFactory csf = _sslContextFactory == null ? null : new SslRMIClientSocketFactory(); @@ -208,7 +208,7 @@ public class ConnectorServer extends AbstractLifeCycle } catch (Exception ex) { - LOG.ignore(ex); + LOG.trace("IGNORED", ex); } finally { diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java index 2ce8320c156..f8db4c44bd2 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -45,8 +45,8 @@ import org.eclipse.jetty.util.component.Container; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Destroyable; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Container class for the MBean instances @@ -54,7 +54,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject("The component that registers beans as MBeans") public class MBeanContainer implements Container.InheritedListener, Dumpable, Destroyable { - private static final Logger LOG = Log.getLogger(MBeanContainer.class.getName()); + private static final Logger LOG = LoggerFactory.getLogger(MBeanContainer.class.getName()); private static final ConcurrentMap __unique = new ConcurrentHashMap<>(); private static final Container ROOT = new ContainerLifeCycle(); @@ -436,11 +436,11 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De } catch (MBeanRegistrationException | InstanceNotFoundException x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } catch (Throwable x) { - LOG.warn(x); + LOG.warn("Unable to unregister {}", objectName, x); } } } diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java index 6a12bf17338..7af48fb4f6c 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -47,12 +47,12 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class MetaData { - private static final Logger LOG = Log.getLogger(MetaData.class); + private static final Logger LOG = LoggerFactory.getLogger(MetaData.class); private static final MBeanAttributeInfo[] NO_ATTRIBUTES = new MBeanAttributeInfo[0]; private static final MBeanConstructorInfo[] NO_CONSTRUCTORS = new MBeanConstructorInfo[0]; private static final MBeanOperationInfo[] NO_OPERATIONS = new MBeanOperationInfo[0]; diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java index d49bdf8322c..72478e58b73 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -27,8 +27,8 @@ import javax.management.MBeanInfo; import javax.management.ObjectName; import javax.management.ReflectionException; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A dynamic MBean that can wrap an arbitrary Object instance.

      @@ -44,7 +44,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ObjectMBean implements DynamicMBean { - private static final Logger LOG = Log.getLogger(ObjectMBean.class); + private static final Logger LOG = LoggerFactory.getLogger(ObjectMBean.class); protected final Object _managed; private MetaData _metaData; @@ -154,7 +154,7 @@ public class ObjectMBean implements DynamicMBean catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Unable to get attribute {}", name, x); } } return results; @@ -188,7 +188,7 @@ public class ObjectMBean implements DynamicMBean catch (Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug(x); + LOG.debug("Unable to get Attribute {}", attribute, x); } } return results; diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java index 4a14bafe9b5..76703787e01 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/util/log/jmx/LogMBean.java b/jetty-jmx/src/main/java/org/eclipse/jetty/util/log/jmx/LogMBean.java deleted file mode 100644 index d3f447bad6c..00000000000 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/util/log/jmx/LogMBean.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log.jmx; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jetty.jmx.ObjectMBean; -import org.eclipse.jetty.util.annotation.ManagedAttribute; -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; - -/** - * - */ -@ManagedObject("Jetty Logging") -public class LogMBean extends ObjectMBean -{ - public LogMBean(Object managedObject) - { - super(managedObject); - } - - @ManagedAttribute(value = "list of instantiated loggers") - public List getLoggers() - { - List keySet = new ArrayList(Log.getLoggers().keySet()); - return keySet; - } - - @ManagedOperation(value = "true if debug enabled for the given logger") - public boolean isDebugEnabled(@Name("logger") String logger) - { - return Log.getLogger(logger).isDebugEnabled(); - } - - @ManagedOperation(value = "Set debug enabled for given logger") - public void setDebugEnabled(@Name("logger") String logger, @Name("enabled") Boolean enabled) - { - Log.getLogger(logger).setDebugEnabled(enabled); - } -} diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/util/log/jmx/package-info.java b/jetty-jmx/src/main/java/org/eclipse/jetty/util/log/jmx/package-info.java deleted file mode 100644 index 119069fab0a..00000000000 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/util/log/jmx/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty JMX : Jetty Logging JMX Integration - */ -package org.eclipse.jetty.util.log.jmx; - diff --git a/jetty-jmx/src/test/java/com/acme/Base.java b/jetty-jmx/src/test/java/com/acme/Base.java index 5d6820e9169..9cc5f0ae770 100644 --- a/jetty-jmx/src/test/java/com/acme/Base.java +++ b/jetty-jmx/src/test/java/com/acme/Base.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/Derived.java b/jetty-jmx/src/test/java/com/acme/Derived.java index 7016baf4e37..1078d981854 100644 --- a/jetty-jmx/src/test/java/com/acme/Derived.java +++ b/jetty-jmx/src/test/java/com/acme/Derived.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/DerivedExtended.java b/jetty-jmx/src/test/java/com/acme/DerivedExtended.java index d072d357529..a9a6a3c5ab8 100644 --- a/jetty-jmx/src/test/java/com/acme/DerivedExtended.java +++ b/jetty-jmx/src/test/java/com/acme/DerivedExtended.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/DerivedManaged.java b/jetty-jmx/src/test/java/com/acme/DerivedManaged.java index b539528b0cd..bf4c77ea812 100644 --- a/jetty-jmx/src/test/java/com/acme/DerivedManaged.java +++ b/jetty-jmx/src/test/java/com/acme/DerivedManaged.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/Managed.java b/jetty-jmx/src/test/java/com/acme/Managed.java index 0da7a21b31f..dae0be9b8de 100644 --- a/jetty-jmx/src/test/java/com/acme/Managed.java +++ b/jetty-jmx/src/test/java/com/acme/Managed.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/Signature.java b/jetty-jmx/src/test/java/com/acme/Signature.java index 759df6a1811..63f406749bd 100644 --- a/jetty-jmx/src/test/java/com/acme/Signature.java +++ b/jetty-jmx/src/test/java/com/acme/Signature.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/SuperManaged.java b/jetty-jmx/src/test/java/com/acme/SuperManaged.java index b417abf02ac..9797900bf23 100644 --- a/jetty-jmx/src/test/java/com/acme/SuperManaged.java +++ b/jetty-jmx/src/test/java/com/acme/SuperManaged.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/jetty-jmx/src/test/java/com/acme/jmx/DerivedMBean.java b/jetty-jmx/src/test/java/com/acme/jmx/DerivedMBean.java index 5b91b4c37d1..f3d8782b119 100644 --- a/jetty-jmx/src/test/java/com/acme/jmx/DerivedMBean.java +++ b/jetty-jmx/src/test/java/com/acme/jmx/DerivedMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.jmx; @@ -23,13 +23,13 @@ import org.eclipse.jetty.jmx.ObjectMBean; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject("Derived MBean Wrapper") public class DerivedMBean extends ObjectMBean { - private static final Logger LOG = Log.getLogger(DerivedMBean.class); + private static final Logger LOG = LoggerFactory.getLogger(DerivedMBean.class); public DerivedMBean(Object managedObject) { diff --git a/jetty-jmx/src/test/java/com/acme/jmx/ManagedMBean.java b/jetty-jmx/src/test/java/com/acme/jmx/ManagedMBean.java index 3325f6c1094..0480fcf73d8 100644 --- a/jetty-jmx/src/test/java/com/acme/jmx/ManagedMBean.java +++ b/jetty-jmx/src/test/java/com/acme/jmx/ManagedMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.jmx; diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java index 701027a12bd..9a44308d6c3 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -232,7 +232,7 @@ public class ConnectorServerTest public void testJMXOverTLS() throws Exception { SslContextFactory sslContextFactory = new SslContextFactory.Server(); - String keyStorePath = MavenTestingUtils.getTestResourcePath("keystore.jks").toString(); + String keyStorePath = MavenTestingUtils.getTestResourcePath("keystore.p12").toString(); String keyStorePassword = "storepwd"; sslContextFactory.setKeyStorePath(keyStorePath); sslContextFactory.setKeyStorePassword(keyStorePassword); diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerLifeCycleTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerLifeCycleTest.java index 94dd6fb6d38..bfe2b8ea30c 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerLifeCycleTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerLifeCycleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java index 2b87fa53cfb..abcd1931be6 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java index 51f6cce9c7a..c79226e6d81 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -123,7 +123,7 @@ public class ObjectMBeanTest assertEquals("com.acme.Derived", derivedInfo.getClassName(), "name does not match"); assertEquals("Test the mbean stuff", derivedInfo.getDescription(), "description does not match"); - assertEquals(6, derivedInfo.getAttributes().length, "attribute count does not match"); + assertEquals(5, derivedInfo.getAttributes().length, "attribute count does not match"); assertEquals("Full Name", derivedMBean.getAttribute("fname"), "attribute values does not match"); derivedMBean.setAttribute(new Attribute("fname", "Fuller Name")); diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java index 7a906b6a03e..1c55063bb19 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java index 4356cdbc5ad..3f52ab9245c 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jmx; @@ -26,7 +26,6 @@ import com.openpojo.validation.Validator; import com.openpojo.validation.ValidatorBuilder; import com.openpojo.validation.test.impl.GetterTester; import com.openpojo.validation.test.impl.SetterTester; -import org.eclipse.jetty.util.log.jmx.LogMBean; import org.junit.jupiter.api.Test; /* @@ -38,7 +37,7 @@ public class PojoTest public void testOpenPojo() { Validator validator = ValidatorBuilder.create().with(new SetterTester()).with(new GetterTester()).build(); - List classes = Arrays.asList(MBeanContainer.class, ObjectMBean.class, LogMBean.class); + List classes = Arrays.asList(MBeanContainer.class, ObjectMBean.class); for (Class clazz : classes) { validator.validate(PojoClassFactory.getPojoClass(clazz)); diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/util/log/jmx/LogMBeanTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/util/log/jmx/LogMBeanTest.java deleted file mode 100644 index d3a5afaac9e..00000000000 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/util/log/jmx/LogMBeanTest.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log.jmx; - -import com.acme.Managed; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.in; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class LogMBeanTest -{ - - private Managed managed; - - private LogMBean logMBean; - - private static final String MANAGED_CLASS = "Managed"; - - @BeforeEach - public void setUp() - { - managed = new Managed(); - logMBean = new LogMBean(managed); - } - - @Test - public void testKeySet() - { - // given - assertThat("Managed is not registered with loggers", MANAGED_CLASS, not(is(in(logMBean.getLoggers())))); - - // when - logMBean.setDebugEnabled(MANAGED_CLASS, true); - - // then - assertThat("Managed must be registered with loggers", MANAGED_CLASS, is(in(logMBean.getLoggers()))); - assertTrue(logMBean.isDebugEnabled(MANAGED_CLASS), "This must return true as debug is enabled for this class"); - } -} diff --git a/jetty-jmx/src/test/resources/jetty-logging.properties b/jetty-jmx/src/test/resources/jetty-logging.properties index ad4b63c91cc..1f674758b1c 100644 --- a/jetty-jmx/src/test/resources/jetty-logging.properties +++ b/jetty-jmx/src/test/resources/jetty-logging.properties @@ -1,2 +1,2 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.jmx.LEVEL=DEBUG diff --git a/jetty-jmx/src/test/resources/keystore.jks b/jetty-jmx/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-jmx/src/test/resources/keystore.jks and /dev/null differ diff --git a/jetty-jmx/src/test/resources/keystore.p12 b/jetty-jmx/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..3591f1399d6 Binary files /dev/null and b/jetty-jmx/src/test/resources/keystore.p12 differ diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 2442dd6f097..306faaf19b9 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -17,6 +17,14 @@ + + maven-surefire-plugin + + + @{argLine} ${jetty.surefire.argLine} --add-modules javax.mail.glassfish + + + org.apache.felix maven-bundle-plugin @@ -43,7 +51,15 @@ jetty-util ${project.version}
      - + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-jndi/src/main/java/module-info.java b/jetty-jndi/src/main/java/module-info.java index 48d29037c63..c5c5e41cb48 100644 --- a/jetty-jndi/src/main/java/module-info.java +++ b/jetty-jndi/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.jndi @@ -23,9 +23,9 @@ module org.eclipse.jetty.jndi exports org.eclipse.jetty.jndi.java; exports org.eclipse.jetty.jndi.local; - requires java.naming; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive java.naming; + requires transitive org.eclipse.jetty.server; + requires org.slf4j; // Only required if using DataSourceCloser. requires static java.sql; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/BindingEnumeration.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/BindingEnumeration.java index 41fe5550538..d37d469da94 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/BindingEnumeration.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/BindingEnumeration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java index 5d8c6b93831..96a9a1f2ba0 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; @@ -32,8 +32,8 @@ import javax.naming.spi.ObjectFactory; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ContextFactory @@ -58,7 +58,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ContextFactory implements ObjectFactory { - private static final Logger LOG = Log.getLogger(ContextFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(ContextFactory.class); /** * Map of classloaders to contexts. @@ -259,7 +259,7 @@ public class ContextFactory implements ObjectFactory { synchronized (__contextMap) { - Dumpable.dumpObjects(out, indent, String.format("o.e.j.jndi.ContextFactory@", __contextMap.hashCode()), __contextMap); + Dumpable.dumpObjects(out, indent, String.format("o.e.j.jndi.ContextFactory@%x", __contextMap.hashCode()), __contextMap); } } } diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/DataSourceCloser.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/DataSourceCloser.java index aba28bc3914..c76a7cb0cde 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/DataSourceCloser.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/DataSourceCloser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; @@ -25,8 +25,8 @@ import javax.sql.DataSource; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Close a DataSource. @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class DataSourceCloser implements Destroyable { - private static final Logger LOG = Log.getLogger(DataSourceCloser.class); + private static final Logger LOG = LoggerFactory.getLogger(DataSourceCloser.class); final DataSource _datasource; final String _shutdown; @@ -74,7 +74,7 @@ public class DataSourceCloser implements Destroyable } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to shutdown datasource {}", _datasource, e); } try @@ -85,7 +85,7 @@ public class DataSourceCloser implements Destroyable } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to close datasource {}", _datasource, e); } } } diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java index 3e232dda38a..d25796e7187 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; @@ -27,8 +27,8 @@ import javax.naming.NameParser; import javax.naming.NamingException; import org.eclipse.jetty.jndi.local.localContextRoot; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * InitialContextFactory.java @@ -40,7 +40,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class InitialContextFactory implements javax.naming.spi.InitialContextFactory { - private static final Logger LOG = Log.getLogger(InitialContextFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(InitialContextFactory.class); public static class DefaultParser implements NameParser { diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NameEnumeration.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NameEnumeration.java index ffba9bcd981..87845ed1057 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NameEnumeration.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NameEnumeration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java index 94ebf286c9c..43f803a28e0 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; @@ -46,8 +46,8 @@ import javax.naming.Referenceable; import javax.naming.spi.NamingManager; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * NamingContext @@ -60,7 +60,7 @@ import org.eclipse.jetty.util.log.Logger; @SuppressWarnings("unchecked") public class NamingContext implements Context, Dumpable { - private static final Logger LOG = Log.getLogger(NamingContext.class); + private static final Logger LOG = LoggerFactory.getLogger(NamingContext.class); private static final List __empty = Collections.emptyList(); public static final String DEEP_BINDING = "org.eclipse.jetty.jndi.deepBinding"; public static final String LOCK_PROPERTY = "org.eclipse.jetty.jndi.lock"; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java index b7591c247cc..b24824a973d 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi; @@ -28,15 +28,15 @@ import javax.naming.NameParser; import javax.naming.NamingEnumeration; import javax.naming.NamingException; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Naming Utility Methods */ public class NamingUtil { - private static final Logger LOG = Log.getLogger(NamingUtil.class); + private static final Logger LOG = LoggerFactory.getLogger(NamingUtil.class); /** * Bind an object to a context ensuring all sub-contexts diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java index 5275f88f09d..dd3780a5d8d 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/MailSessionReference.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.factories; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java index 4549efa2878..06a1d1b2b5a 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/factories/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaNameParser.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaNameParser.java index c0c703ad0e0..267987b4780 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaNameParser.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaNameParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.java; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaRootURLContext.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaRootURLContext.java index 674528b2d70..a36353c8023 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaRootURLContext.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaRootURLContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.java; @@ -29,8 +29,8 @@ import javax.naming.StringRefAddr; import org.eclipse.jetty.jndi.ContextFactory; import org.eclipse.jetty.jndi.NamingContext; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; // This is a required name for JNDI // @checkstyle-disable-check : TypeNameCheck @@ -44,7 +44,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class javaRootURLContext implements Context { - private static final Logger LOG = Log.getLogger(javaRootURLContext.class); + private static final Logger LOG = LoggerFactory.getLogger(javaRootURLContext.class); public static final String URL_PREFIX = "java:"; @@ -73,7 +73,7 @@ public class javaRootURLContext implements Context } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to bind default NamingContext to: comp", e); } } diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaURLContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaURLContextFactory.java index a3bda3d78dd..3df8d71013d 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaURLContextFactory.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaURLContextFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.java; @@ -24,8 +24,8 @@ import javax.naming.Name; import javax.naming.NamingException; import javax.naming.spi.ObjectFactory; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; // This is a required name for JNDI // @checkstyle-disable-check : TypeNameCheck @@ -37,7 +37,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class javaURLContextFactory implements ObjectFactory { - private static final Logger LOG = Log.getLogger(javaURLContextFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(javaURLContextFactory.class); /** * Either return a new context or the resolution of a url. diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java index 189f9393067..e8e6899941a 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java index 92b1ee204cc..56ca5bf9dbd 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.local; @@ -38,8 +38,8 @@ import javax.naming.Referenceable; import javax.naming.spi.NamingManager; import org.eclipse.jetty.jndi.NamingContext; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; // This is a required name for JNDI // @checkstyle-disable-check : TypeNameCheck @@ -51,7 +51,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class localContextRoot implements Context { - private static final Logger LOG = Log.getLogger(localContextRoot.class); + private static final Logger LOG = LoggerFactory.getLogger(localContextRoot.class); protected static final NamingContext __root = new NamingRoot(); private final Hashtable _env; @@ -98,44 +98,29 @@ public class localContextRoot implements Context _env = new Hashtable(env); } - /** - * @see javax.naming.Context#close() - */ @Override public void close() throws NamingException { } - /** - * @see javax.naming.Context#getNameInNamespace() - */ @Override public String getNameInNamespace() throws NamingException { return ""; } - /** - * @see javax.naming.Context#destroySubcontext(javax.naming.Name) - */ @Override public void destroySubcontext(Name name) throws NamingException { __root.destroySubcontext(getSuffix(name)); } - /** - * @see javax.naming.Context#destroySubcontext(java.lang.String) - */ @Override public void destroySubcontext(String name) throws NamingException { destroySubcontext(__root.getNameParser("").parse(getSuffix(name))); } - /** - * @see javax.naming.Context#getEnvironment() - */ @Override public Hashtable getEnvironment() throws NamingException { @@ -157,7 +142,7 @@ public class localContextRoot implements Context } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to dereference {}, {}", ctx, firstComponent, e); throw new NamingException(e.getMessage()); } } @@ -186,9 +171,6 @@ public class localContextRoot implements Context return (Context)ctx; } - /** - * @see javax.naming.Context#unbind(javax.naming.Name) - */ @Override public void unbind(Name name) throws NamingException { @@ -219,27 +201,18 @@ public class localContextRoot implements Context } } - /** - * @see javax.naming.Context#unbind(java.lang.String) - */ @Override public void unbind(String name) throws NamingException { unbind(__root.getNameParser("").parse(getSuffix(name))); } - /** - * @see javax.naming.Context#lookupLink(java.lang.String) - */ @Override public Object lookupLink(String name) throws NamingException { return lookupLink(__root.getNameParser("").parse(getSuffix(name))); } - /** - * @see javax.naming.Context#lookupLink(javax.naming.Name) - */ @Override public Object lookupLink(Name name) throws NamingException { @@ -292,18 +265,12 @@ public class localContextRoot implements Context return getContext(cname).lookup(cname.getSuffix(1)); } - /** - * @see javax.naming.Context#removeFromEnvironment(java.lang.String) - */ @Override public Object removeFromEnvironment(String propName) throws NamingException { return _env.remove(propName); } - /** - * @see javax.naming.Context#lookup(javax.naming.Name) - */ @Override public Object lookup(Name name) throws NamingException { @@ -370,27 +337,18 @@ public class localContextRoot implements Context return getContext(cname).lookup(cname.getSuffix(1)); } - /** - * @see javax.naming.Context#lookup(java.lang.String) - */ @Override public Object lookup(String name) throws NamingException { return lookup(__root.getNameParser("").parse(getSuffix(name))); } - /** - * @see javax.naming.Context#bind(java.lang.String, java.lang.Object) - */ @Override public void bind(String name, Object obj) throws NamingException { bind(__root.getNameParser("").parse(getSuffix(name)), obj); } - /** - * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object) - */ @Override public void bind(Name name, Object obj) throws NamingException { @@ -428,9 +386,6 @@ public class localContextRoot implements Context } } - /** - * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object) - */ @Override public void rebind(Name name, Object obj) throws NamingException { @@ -468,36 +423,24 @@ public class localContextRoot implements Context } } - /** - * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object) - */ @Override public void rebind(String name, Object obj) throws NamingException { rebind(__root.getNameParser("").parse(getSuffix(name)), obj); } - /** - * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name) - */ @Override public void rename(Name oldName, Name newName) throws NamingException { throw new OperationNotSupportedException(); } - /** - * @see javax.naming.Context#rename(java.lang.String, java.lang.String) - */ @Override public void rename(String oldName, String newName) throws NamingException { throw new OperationNotSupportedException(); } - /** - * @see javax.naming.Context#createSubcontext(java.lang.String) - */ @Override public Context createSubcontext(String name) throws NamingException { @@ -512,9 +455,6 @@ public class localContextRoot implements Context return createSubcontext(__root.getNameParser("").parse(name)); } - /** - * @see javax.naming.Context#createSubcontext(javax.naming.Name) - */ @Override public Context createSubcontext(Name name) throws NamingException { @@ -557,64 +497,42 @@ public class localContextRoot implements Context return getContext(cname).createSubcontext(cname.getSuffix(1)); } - /** - * @see javax.naming.Context#getNameParser(java.lang.String) - */ @Override public NameParser getNameParser(String name) throws NamingException { return __root.getNameParser(name); } - /** - * @see javax.naming.Context#getNameParser(javax.naming.Name) - */ @Override public NameParser getNameParser(Name name) throws NamingException { return __root.getNameParser(name); } - /** - * @see javax.naming.Context#list(java.lang.String) - */ @Override public NamingEnumeration list(String name) throws NamingException { return __root.list(name); } - /** - * @see javax.naming.Context#list(javax.naming.Name) - */ @Override public NamingEnumeration list(Name name) throws NamingException { return __root.list(name); } - /** - * @see javax.naming.Context#listBindings(javax.naming.Name) - */ @Override public NamingEnumeration listBindings(Name name) throws NamingException { return __root.listBindings(name); } - /** - * @see javax.naming.Context#listBindings(java.lang.String) - */ @Override public NamingEnumeration listBindings(String name) throws NamingException { return __root.listBindings(name); } - /** - * @see javax.naming.Context#addToEnvironment(java.lang.String, - * java.lang.Object) - */ @Override public Object addToEnvironment(String propName, Object propVal) throws NamingException @@ -622,9 +540,6 @@ public class localContextRoot implements Context return _env.put(propName, propVal); } - /** - * @see javax.naming.Context#composeName(java.lang.String, java.lang.String) - */ @Override public String composeName(String name, String prefix) throws NamingException @@ -632,10 +547,6 @@ public class localContextRoot implements Context return __root.composeName(name, prefix); } - /** - * @see javax.naming.Context#composeName(javax.naming.Name, - * javax.naming.Name) - */ @Override public Name composeName(Name name, Name prefix) throws NamingException { diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java index 7538092e2dd..5b9e2b7ad9f 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java index cc5d88a4940..ae229625968 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java index ccbc5386bb1..4a42a518f61 100644 --- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java +++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/factories/TestMailSessionReference.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.factories; diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java index 0b18009b0c0..f173ce5a20e 100644 --- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java +++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.java; @@ -41,10 +41,10 @@ import org.eclipse.jetty.jndi.NamingContext; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.HandlerList; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -58,7 +58,7 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class TestJNDI { - private static final Logger LOG = Log.getLogger(TestJNDI.class); + private static final Logger LOG = LoggerFactory.getLogger(TestJNDI.class); static { @@ -472,9 +472,9 @@ public class TestJNDI ((Context)zzz.lookup("java:comp")).bind("crud2", "xxx2"); fail("Should not be able to write to locked context"); } - catch (NamingException ne) + catch (NamingException e) { - assertThat(ne.getMessage(), Matchers.containsString("immutable")); + assertThat(e.getMessage(), Matchers.containsString("immutable")); } finally { @@ -492,9 +492,9 @@ public class TestJNDI ((Context)zzz.lookup("java:comp")).bind("foo", "bar"); fail("Should not be able to write to locked context"); } - catch (NamingException ne) + catch (NamingException e) { - assertThat(ne.getMessage(), Matchers.containsString("immutable")); + assertThat(e.getMessage(), Matchers.containsString("immutable")); } finally { diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java index 0f49d633ea2..b4b94dec148 100644 --- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java +++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jndi.java; diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 2e260fffbe6..a8d60d89e6c 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -123,16 +123,42 @@ - project-team - mailing-list - cim - issue-tracking - license + team + mailing-lists + ci-management + issue-management + licenses scm + + org.apache.maven.plugins + maven-plugin-plugin + + + + eclipse-release + + + + org.apache.maven.plugins + maven-site-plugin + + + site-jar + + jar + + package + + + + + + + diff --git a/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java b/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java index 2b93292bbe4..870b43580f1 100644 --- a/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java +++ b/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/JspcMojo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.jspc.plugin; diff --git a/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/package-info.java b/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/package-info.java index dc7883db9dc..0c868ce837c 100644 --- a/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/package-info.java +++ b/jetty-jspc-maven-plugin/src/main/java/org/eclipse/jetty/jspc/plugin/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-jspc-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/jetty-jspc-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml index 410520f4c44..590a3ec798a 100644 --- a/jetty-jspc-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml +++ b/jetty-jspc-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-jspc-maven-plugin/src/site/markdown/index.md b/jetty-jspc-maven-plugin/src/site/markdown/index.md new file mode 100644 index 00000000000..639a5a3fbf8 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/site/markdown/index.md @@ -0,0 +1,4 @@ +Eclipse Jetty Jspc Maven Plugin +======================== + +This plugin will help you pre-compile your jsps and works in conjunction with the Maven war plugin to put them inside an assembled war. diff --git a/jetty-jspc-maven-plugin/src/site/site.xml b/jetty-jspc-maven-plugin/src/site/site.xml new file mode 100644 index 00000000000..d37c6e5f9dc --- /dev/null +++ b/jetty-jspc-maven-plugin/src/site/site.xml @@ -0,0 +1,44 @@ + + + + + + ${project.name} + https://www.eclipse.org/jetty/images/jetty-logo-80x22.png + https://eclipse.org/jetty/ + + + https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-426x100.png + + + + org.apache.maven.skins + maven-fluido-skin + 1.7 + + + + + true + true + + ${project.url} + + + eclipse/jetty.project + right + gray + + + + + + + + + + + + diff --git a/jetty-maven-plugin/.gitignore b/jetty-maven-plugin/.gitignore deleted file mode 100644 index 929d903c7d3..00000000000 --- a/jetty-maven-plugin/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.classpath -.project -.settings -target -*.swp diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 60f0d378879..131a3603827 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -16,10 +16,44 @@ + + org.codehaus.mojo + build-helper-maven-plugin + + + test-reserve-ports + process-test-classes + + reserve-network-port + + + + test.stopPort + test.jettyPort + + + + + reserve-ports + pre-integration-test + + reserve-network-port + + + + jetty.stopPort + + + + + maven-surefire-plugin - true + -Dstop.port=@{test.stopPort} -Djetty.port=@{test.jettyPort} + + **/IntegrationTest*.java + @@ -75,24 +109,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - - - reserve-ports - pre-integration-test - - reserve-network-port - - - - jetty.stopPort - - - - - org.jacoco jacoco-maven-plugin @@ -103,6 +119,11 @@ + + org.apache.maven.shared + maven-artifact-transfer + 0.11.0 + org.apache.maven maven-plugin-api @@ -124,11 +145,6 @@ maven-plugin-annotations provided - - org.apache.maven.shared - maven-artifact-transfer - 0.9.1 - org.eclipse.jetty jetty-util @@ -202,12 +218,12 @@ org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} @@ -220,6 +236,11 @@ apache-jstl ${project.version} + + org.slf4j + slf4j-api + ${slf4j.version} + jakarta.transaction jakarta.transaction-api @@ -232,28 +253,56 @@ test zip + + org.eclipse.jetty.toolchain + jetty-test-helper + test + org.apache.maven.plugins maven-project-info-reports-plugin - - false - - project-team - mailing-list - cim - issue-tracking - license + team + mailing-lists + ci-management + issue-management + licenses scm + + org.apache.maven.plugins + maven-plugin-plugin + + + + eclipse-release + + + + org.apache.maven.plugins + maven-site-plugin + + + site-jar + + jar + + package + + + + + + + diff --git a/jetty-maven-plugin/src/it/it-parent-pom/pom.xml b/jetty-maven-plugin/src/it/it-parent-pom/pom.xml index f9fec5b2859..443f71b8ebb 100644 --- a/jetty-maven-plugin/src/it/it-parent-pom/pom.xml +++ b/jetty-maven-plugin/src/it/it-parent-pom/pom.xml @@ -30,11 +30,6 @@ commons-lang3 3.8.1 - - org.jboss.weld.servlet - weld-servlet - @weld.version@ - org.eclipse.jetty.toolchain jetty-perf-helper diff --git a/jetty-maven-plugin/src/it/javax-annotation-api/pom.xml b/jetty-maven-plugin/src/it/javax-annotation-api/pom.xml index 98f982254f0..4d2af3f1b78 100644 --- a/jetty-maven-plugin/src/it/javax-annotation-api/pom.xml +++ b/jetty-maven-plugin/src/it/javax-annotation-api/pom.xml @@ -18,6 +18,8 @@ 8 ${project.build.directory}/jetty-run-mojo-annotation.txt + EMBED + 1.7.30 @@ -40,12 +42,17 @@ org.slf4j slf4j-api - @slf4j.version@ + ${logging.slf4j.version} - org.apache.logging.log4j - log4j-slf4j18-impl - @log4j2.version@ + org.slf4j + slf4j-log4j12 + ${logging.slf4j.version} + + + org.slf4j + jul-to-slf4j + ${logging.slf4j.version} org.springframework.boot @@ -84,12 +91,8 @@ - - jetty.port.file - ${jetty.port.file} - + ${jetty.port.file} - true ${basedir}/src/config/jetty.xml diff --git a/jetty-maven-plugin/src/it/javax-annotation-api/postbuild.groovy b/jetty-maven-plugin/src/it/javax-annotation-api/postbuild.groovy index 9533c9ecc2c..f3d4457eee4 100644 --- a/jetty-maven-plugin/src/it/javax-annotation-api/postbuild.groovy +++ b/jetty-maven-plugin/src/it/javax-annotation-api/postbuild.groovy @@ -17,5 +17,5 @@ * under the License. */ File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) +assert buildLog.text.contains( 'Started Server' ) assert buildLog.text.contains( 'all good guys get a good Beer') diff --git a/jetty-maven-plugin/src/it/javax-annotation-api/src/config/jetty.xml b/jetty-maven-plugin/src/it/javax-annotation-api/src/config/jetty.xml index ced70a66d09..4e43b5305df 100644 --- a/jetty-maven-plugin/src/it/javax-annotation-api/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/javax-annotation-api/src/config/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -24,7 +24,7 @@ - + diff --git a/jetty-maven-plugin/src/it/javax-annotation-api/src/main/java/test/App.java b/jetty-maven-plugin/src/it/javax-annotation-api/src/main/java/test/App.java index ab3b8dc2c77..602f733f4df 100644 --- a/jetty-maven-plugin/src/it/javax-annotation-api/src/main/java/test/App.java +++ b/jetty-maven-plugin/src/it/javax-annotation-api/src/main/java/test/App.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package test; diff --git a/jetty-maven-plugin/src/it/javax-annotation-api/src/main/resources/log4j.xml b/jetty-maven-plugin/src/it/javax-annotation-api/src/main/resources/log4j.xml new file mode 100644 index 00000000000..83a28a67537 --- /dev/null +++ b/jetty-maven-plugin/src/it/javax-annotation-api/src/main/resources/log4j.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/java/test/Greeter.java b/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/java/test/Greeter.java deleted file mode 100644 index 4534448fc90..00000000000 --- a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/java/test/Greeter.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package test; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@WebServlet("/*") -public class Greeter - extends HttpServlet -{ - - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/invoker.properties b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/invoker.properties similarity index 100% rename from jetty-maven-plugin/src/it/jetty-cdi-run-forked/invoker.properties rename to jetty-maven-plugin/src/it/jetty-cdi-start-forked/invoker.properties diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/pom.xml similarity index 76% rename from jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml rename to jetty-maven-plugin/src/it/jetty-cdi-start-forked/pom.xml index 7d42ae6b313..4fadeeb3836 100644 --- a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/pom.xml @@ -8,20 +8,17 @@ 0.0.1-SNAPSHOT - org.eclipse.jetty.its.jetty-cdi-run-forked-mojo-it + org.eclipse.jetty.its.jetty-cdi-start-forked-mojo-it jetty-weld-minimal 1.0-SNAPSHOT war - ${project.build.directory}/jetty-cdi-run-forked-port.txt + ${project.build.directory}/jetty-cdi-start-forked-port.txt + FORK - - org.jboss.weld.servlet - weld-servlet - org.eclipse.jetty.toolchain jetty-servlet-api @@ -52,6 +49,9 @@ org.apache.maven.plugins maven-surefire-plugin + + IntegrationTest*.java + ${jetty.port.file} true @@ -68,35 +68,24 @@ start-jetty - test-compile + process-test-classes - run-forked + start - true - false - ${basedir}/src/main/jetty/jetty-context.xml - ${basedir}/src/main/jetty/jetty.xml + + ${basedir}/src/main/jetty/jetty.xml + @jetty.stopPort@ @jetty.stopKey@ - ${jetty.jvmArgs} - jetty.port.file=${jetty.port.file} + ${jetty.port.file} - diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/postbuild.groovy similarity index 93% rename from jetty-maven-plugin/src/it/jetty-cdi-run-forked/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-cdi-start-forked/postbuild.groovy index 304570382ee..7d8065c3ac0 100644 --- a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/postbuild.groovy @@ -12,6 +12,6 @@ s.close() File buildLog = new File( basedir, 'build.log' ) assert buildLog.text.contains( 'Forked process starting' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') assert buildLog.text.contains( 'helloServlet') diff --git a/jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/java/test/Greeter.java b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/java/test/Greeter.java new file mode 100644 index 00000000000..ad6388a6a11 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/java/test/Greeter.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package test; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/*") +public class Greeter + extends HttpServlet +{ + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/jetty/jetty-context.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty-context.xml rename to jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/jetty/jetty-context.xml diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/jetty/jetty.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml rename to jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/jetty/jetty.xml index 5389324070a..8f1c473fb3f 100644 --- a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/src/main/jetty/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-cdi-start-forked/src/main/jetty/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -24,7 +24,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/postbuild.groovy deleted file mode 100644 index b5f4344c4a6..00000000000 --- a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/postbuild.groovy +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') -assert buildLog.text.contains( 'contentCheck') \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java index cf09b59a299..85e51e03b38 100755 --- a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java +++ b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package test; diff --git a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/postbuild.groovy index 4c12de49d83..1ec1341da06 100644 --- a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/postbuild.groovy @@ -17,5 +17,5 @@ * under the License. */ File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'ClassNotFoundException') \ No newline at end of file +assert buildLog.text.contains( 'Started Server' ) +assert buildLog.text.contains( 'ClassNotFoundException') diff --git a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/pom.xml b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/pom.xml index dd221342be9..eb76aa46b5e 100755 --- a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/pom.xml @@ -9,6 +9,10 @@ web war + + EMBED + + ${project.groupId} @@ -41,13 +45,14 @@ start-jetty - test-compile + pre-integration-test start - true - ${basedir}/src/config/jetty.xml + + ${basedir}/src/config/jetty.xml + diff --git a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml index b2f1ae17431..7df44bd5ad7 100644 --- a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/config/jetty.xml @@ -10,7 +10,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -30,7 +30,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java index e5c41993eb0..61f143ef172 100755 --- a/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java +++ b/jetty-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java @@ -1,23 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package test; +import java.net.URL; +import java.net.URLClassLoader; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @@ -33,16 +35,39 @@ public class ClassLoadingTestingServletContextListener try { Api api = new Api(); + System.err.println("Class " + api.getClass().getName() + " is available and loaded by classloader " + api.getClass().getClassLoader().toString() + ". Expected CNFE."); + ClassLoader cl = api.getClass().getClassLoader(); + while (cl != null) + { + if (cl instanceof URLClassLoader) + { + URLClassLoader ucl = (URLClassLoader)cl; + System.err.println("-----"); + printURLs(ucl); + System.err.println("-----"); + } + cl = cl.getParent(); + } } catch (java.lang.Exception exception) { exception.printStackTrace(); } - //System.out.println("Class " + api.getClass().getName() + " is available and loaded by classloader " + api.getClass().getClassLoader().toString() + ". Expected ClassNotFoundException."); } @Override public void contextDestroyed(ServletContextEvent sce) { } + + private void printURLs(URLClassLoader l) + { + if (l == null) + return; + + for (URL u: l.getURLs()) + { + System.err.println(u); + } + } } diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/invoker.properties deleted file mode 100644 index df6cbf2d0bc..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = test -fae -invoker.debug = true diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_distro_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_distro_mojo_it/HelloServlet.java deleted file mode 100644 index 72553f5395f..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_distro_mojo_it/HelloServlet.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_distro_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - */ -@WebServlet("/hello") -public class HelloServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_distro_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_distro_mojo_it/PingServlet.java deleted file mode 100644 index 4dd7c6f7eb8..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_distro_mojo_it/PingServlet.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_distro_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class PingServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("pong " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/invoker.properties deleted file mode 100644 index 2fc6409821b..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/invoker.properties +++ /dev/null @@ -1 +0,0 @@ -invoker.goals = test -fae \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_forked_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_forked_mojo_it/HelloServlet.java deleted file mode 100644 index 267d52bafaa..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_forked_mojo_it/HelloServlet.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_forked_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - */ -@WebServlet("/hello") -public class HelloServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_forked_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_forked_mojo_it/PingServlet.java deleted file mode 100644 index 386bbe55295..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_forked_mojo_it/PingServlet.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_forked_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class PingServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("pong " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml deleted file mode 100644 index a6f28b51a37..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - FragmentA - - - - - - - Ping - org.eclipse.jetty.its.jetty_run_forked_mojo_it.PingServlet - - extra1123 - - - extra2345 - - - - - Ping - /ping - - - - \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-mojo-it/invoker.properties deleted file mode 100644 index e0222d4d54e..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/invoker.properties +++ /dev/null @@ -1 +0,0 @@ -invoker.goals = test \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java deleted file mode 100644 index 5cf82ccf88e..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - */ -@WebServlet("/hello") -public class HelloServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java deleted file mode 100644 index 48152a7b735..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class PingServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("pong " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/test/java/org/eclipse/jetty/its/jetty_run_mojo_it_test/HelloTestServlet.java b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/test/java/org/eclipse/jetty/its/jetty_run_mojo_it_test/HelloTestServlet.java deleted file mode 100644 index 91c72bacf55..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/test/java/org/eclipse/jetty/its/jetty_run_mojo_it_test/HelloTestServlet.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_mojo_it_test; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - */ -@WebServlet("/testhello") -public class HelloTestServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello from test " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml deleted file mode 100644 index d17cc126f78..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - 4.0.0 - - - org.eclipse.jetty.its.jetty-run-mojo-it - jetty-simple-project - 0.0.1-SNAPSHOT - - - jetty-simple-webapp - war - - Jetty :: Simple :: Webapp - - - ${project.build.directory}/jetty-run-mojo.txt - - - - - org.eclipse.jetty.its.jetty-run-mojo-it - jetty-simple-base - - - org.eclipse.jetty.its.jetty-run-mojo-it - jetty-simple-base - test - test-jar - - - org.slf4j - slf4j-simple - - - org.eclipse.jetty - jetty-servlet - provided - - - org.eclipse.jetty - jetty-client - test - - - org.apache.commons - commons-lang3 - test - - - org.eclipse.jetty - jetty-maven-plugin - tests - test-jar - test - - - * - * - - - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - - - - - org.apache.maven.plugins - maven-war-plugin - - false - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${jetty.port.file} - true - true - true - ${project.groupId}:${project.artifactId} - - - org.eclipse.jetty:jetty-maven-plugin - - - - - org.eclipse.jetty - jetty-maven-plugin - - - start-jetty - test-compile - - start - - - - - jetty.port.file - ${jetty.port.file} - - - true - ${basedir}/src/config/jetty.xml - true - - - - - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/pom.xml deleted file mode 100644 index d082c71bbe5..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - - - org.eclipse.jetty.its - it-parent-pom - 0.0.1-SNAPSHOT - - - org.eclipse.jetty.its.jetty-run-mojo-it - jetty-simple-project - 0.0.1-SNAPSHOT - pom - - Jetty :: Simple - - - UTF-8 - UTF-8 - 1.8 - @project.version@ - - - - jetty-simple-base - jetty-simple-webapp - - - - - - org.eclipse.jetty.its.jetty-run-mojo-it - jetty-simple-base - ${project.version} - - - org.eclipse.jetty.its.jetty-run-mojo-it - jetty-simple-base - ${project.version} - test - test-jar - - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/invoker.properties deleted file mode 100644 index e0222d4d54e..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/invoker.properties +++ /dev/null @@ -1 +0,0 @@ -invoker.goals = test \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/pom.xml deleted file mode 100644 index 2b8d3949624..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/pom.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - 4.0.0 - - - org.eclipse.jetty.its - it-parent-pom - 0.0.1-SNAPSHOT - - - jetty-run-mojo-jsp - war - - Jetty :: Simple :: Webapp - - - ${project.build.directory}/jetty-run-mojo-jsp.txt - - - - - org.slf4j - slf4j-simple - - - - org.eclipse.jetty - jetty-servlet - provided - - - - org.eclipse.jetty - jetty-maven-plugin - tests - test-jar - test - - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - - - - - org.apache.maven.plugins - maven-war-plugin - - false - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${jetty.port.file} - Counter accessed 1 times. - /jsp/bean1.jsp - ${project.groupId}:${project.artifactId} - - - org.eclipse.jetty:jetty-maven-plugin - - - - - org.eclipse.jetty - jetty-maven-plugin - - - start-jetty - test-compile - - start - - - - - jetty.port.file - ${jetty.port.file} - - - true - ${basedir}/src/config/jetty.xml - - - - - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/java/com/acme/Counter.java b/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/java/com/acme/Counter.java deleted file mode 100644 index 4ff284e5dbe..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/java/com/acme/Counter.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package com.acme; - -@SuppressWarnings("serial") -public class Counter implements java.io.Serializable -{ - int counter = 0; - String last; - - public int getCount() - { - counter++; - return counter; - } - - public void setLast(String uri) - { - last = uri; - } - - public String getLast() - { - return last; - } -} - diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java b/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java deleted file mode 100644 index 594d387ae36..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package mca.common; - -public class CommonService -{ - -} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java b/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java deleted file mode 100644 index c5fc25f27d6..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package mca.module; - -public interface ModuleApi -{ - -} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java b/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java deleted file mode 100644 index 4b00df5286a..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package mca.module; - -import mca.common.CommonService; - -public class ModuleImpl implements ModuleApi -{ - - private static final CommonService cs = new CommonService(); -} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml deleted file mode 100644 index ced70a66d09..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - https - - 32768 - 8192 - 8192 - 4096 - - - - - - - - - - - - - - - - - - - - - - - - - 30000 - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/invoker.properties deleted file mode 100644 index b8a016f5093..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -V -#test-compile failsafe:integration-test \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java deleted file mode 100644 index 01cadf64ae9..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_war_exploded_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - */ -@WebServlet("/hello") -public class HelloServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java deleted file mode 100644 index c4abedfae8e..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_war_exploded_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class PingServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("pong " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml deleted file mode 100644 index ced70a66d09..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - https - - 32768 - 8192 - 8192 - 4096 - - - - - - - - - - - - - - - - - - - - - - - - - 30000 - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 2a5ac4b71bf..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Jetty Simple Webapp run-mojo-it - diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/postbuild.groovy deleted file mode 100644 index 323b5da5d72..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/postbuild.groovy +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') -assert buildLog.text.contains( 'pingServlet ok') -assert buildLog.text.contains( 'helloServlet') \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/invoker.properties deleted file mode 100644 index b8a016f5093..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -V -#test-compile failsafe:integration-test \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java deleted file mode 100644 index 5cf82ccf88e..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - */ -@WebServlet("/hello") -public class HelloServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java deleted file mode 100644 index 48152a7b735..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.its.jetty_run_mojo_it; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class PingServlet - extends HttpServlet -{ - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException - { - String who = req.getParameter("name"); - - resp.getWriter().write("pong " + (who == null ? "unknown" : who)); - } -} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml deleted file mode 100644 index ced70a66d09..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - https - - 32768 - 8192 - 8192 - 4096 - - - - - - - - - - - - - - - - - - - - - - - - - 30000 - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 2a5ac4b71bf..00000000000 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Jetty Simple Webapp run-mojo-it - diff --git a/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/invoker.properties new file mode 100644 index 00000000000..2d3d7b8f95c --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = verify -fae +#invoker.debug = true diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/pom.xml b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/pom.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/pom.xml index f89fb007715..0ce81579bc8 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-base/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-forked-mojo-it + org.eclipse.jetty.its.jetty-start-distro-mojo-it jetty-simple-project 0.0.1-SNAPSHOT diff --git a/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java new file mode 100644 index 00000000000..3a185a03210 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_start_distro_mojo_it; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + */ +@WebServlet("/hello") +public class HelloServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java new file mode 100644 index 00000000000..d91547b473c --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_start_distro_mojo_it; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class PingServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("pong " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml similarity index 87% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml index 3f087b00489..3198a38948d 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml @@ -14,7 +14,7 @@ Ping - org.eclipse.jetty.its.jetty_run_distro_mojo_it.PingServlet + org.eclipse.jetty.its.jetty_start_distro_mojo_it.PingServlet 1 extra1123 @@ -30,4 +30,4 @@ - \ No newline at end of file + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/pom.xml similarity index 79% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/pom.xml index 1fd3ec985f2..77e4680f47d 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-distro-mojo-it + org.eclipse.jetty.its.jetty-start-distro-mojo-it jetty-simple-project 0.0.1-SNAPSHOT @@ -14,14 +14,15 @@ Jetty :: Simple :: Webapp - ${project.build.directory}/jetty-run-distro-port.txt + ${project.build.directory}/jetty-start-distro-port.txt @jetty.jvmArgs@ + DISTRO - org.eclipse.jetty.its.jetty-run-distro-mojo-it + org.eclipse.jetty.its.jetty-start-distro-mojo-it jetty-simple-base @@ -65,6 +66,9 @@ org.apache.maven.plugins maven-surefire-plugin + + IntegrationTest*.java + ${jetty.port.file} true @@ -86,24 +90,19 @@ start-jetty - test-compile + process-test-classes - run-distro + start ${basedir}/src/base ${java.home}/bin/java - jetty.server.dumpAfterStart=true - jetty.port.file=${jetty.port.file} - jetty.http.port=0 + true + ${jetty.port.file} + 0 - false - - jsp - jstl - testmod - + jsp,jstl,testmod diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml similarity index 91% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml index 08d848ec4c6..c3df301c562 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml @@ -3,7 +3,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/pom.xml similarity index 89% rename from jetty-maven-plugin/src/it/jetty-run-war-mojo-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/pom.xml index 3ae620b58ad..60f5ba42d7c 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/pom.xml @@ -8,7 +8,7 @@ 0.0.1-SNAPSHOT - org.eclipse.jetty.its.jetty-run-war-mojo-it + org.eclipse.jetty.its.jetty-start-distro-mojo-it jetty-simple-project 0.0.1-SNAPSHOT pom @@ -30,7 +30,7 @@ - org.eclipse.jetty.its.jetty-run-war-mojo-it + org.eclipse.jetty.its.jetty-start-distro-mojo-it jetty-simple-base ${project.version} diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/postbuild.groovy similarity index 84% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/postbuild.groovy index 14242d18b34..5e573b25256 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-distro-mojo-it/postbuild.groovy @@ -12,7 +12,7 @@ s.close() File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Forking command line' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') +assert buildLog.text.contains( 'Distro process starting' ) +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') assert buildLog.text.contains( 'pingServlet ok') assert buildLog.text.contains( 'helloServlet') diff --git a/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/invoker.properties new file mode 100644 index 00000000000..850d38aa127 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/invoker.properties @@ -0,0 +1 @@ +invoker.goals = verify -fae diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/pom.xml b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/pom.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/pom.xml index 5e293380ed8..dbeced3c66b 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-distro-mojo-it + org.eclipse.jetty.its.jetty-start-forked-mojo-it jetty-simple-project 0.0.1-SNAPSHOT diff --git a/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java new file mode 100644 index 00000000000..7d050651872 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_start_forked; + +@SuppressWarnings("serial") +public class Counter implements java.io.Serializable +{ + int counter = 0; + String last; + + public int getCount() + { + counter++; + return counter; + } + + public void setLast(String uri) + { + last = uri; + } + + public String getLast() + { + return last; + } +} + diff --git a/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java new file mode 100644 index 00000000000..bb82dd281c8 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_start_forked; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + */ +@WebServlet("/hello") +public class HelloServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java new file mode 100644 index 00000000000..a80925ea206 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_start_forked; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class PingServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("pong " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml similarity index 88% rename from jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml index a1ec4e27ce4..028bdc91255 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml @@ -14,7 +14,7 @@ Ping - org.eclipse.jetty.its.jetty_run_mojo_it.PingServlet + org.eclipse.jetty.its.jetty_start_forked.PingServlet extra1123 @@ -29,4 +29,4 @@ - \ No newline at end of file + diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/pom.xml similarity index 79% rename from jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/pom.xml index 386ae2e2531..e71d817a94f 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-forked-mojo-it + org.eclipse.jetty.its.jetty-start-forked-mojo-it jetty-simple-project 0.0.1-SNAPSHOT @@ -15,13 +15,14 @@ @jetty.jvmArgs@ - ${project.build.directory}/jetty-run-forked-port.txt + ${project.build.directory}/jetty-start-forked-port.txt + FORK - org.eclipse.jetty.its.jetty-run-forked-mojo-it + org.eclipse.jetty.its.jetty-start-forked-mojo-it jetty-simple-base @@ -65,10 +66,15 @@ org.apache.maven.plugins maven-surefire-plugin + + IntegrationTest*.java + ${jetty.port.file} true true + Counter accessed 1 times. + /jsp/bean1.jsp ${project.groupId}:${project.artifactId} @@ -86,29 +92,20 @@ start-jetty - test-compile + process-test-classes - run-forked + start - true - false - ${basedir}/src/config/jetty.xml + + ${basedir}/src/config/jetty.xml + ${jetty.jvmArgs} - jetty.port.file=${jetty.port.file} + ${jetty.port.file} - diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml index ced70a66d09..4e43b5305df 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -24,7 +24,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml similarity index 80% rename from jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/webapp/WEB-INF/web.xml rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml index 5a6d2867874..b2264670c78 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/webapp/WEB-INF/web.xml +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -3,5 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> - Jetty Simple Webapp run-mojo-jsp + Jetty Simple Webapp start-jetty-forked diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/webapp/jsp/bean1.jsp b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp similarity index 67% rename from jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/webapp/jsp/bean1.jsp rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp index 02a13d85e56..08dd1ce9280 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/main/webapp/jsp/bean1.jsp +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp @@ -1,7 +1,7 @@ <%@ page session="true"%> - +

      JSP1.2 Beans: 1

      diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/pom.xml similarity index 89% rename from jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/pom.xml index 813ecc5bfd0..d3c377f9a86 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/pom.xml @@ -8,7 +8,7 @@ 0.0.1-SNAPSHOT - org.eclipse.jetty.its.jetty-run-forked-mojo-it + org.eclipse.jetty.its.jetty-start-forked-mojo-it jetty-simple-project 0.0.1-SNAPSHOT pom @@ -31,7 +31,7 @@ - org.eclipse.jetty.its.jetty-run-forked-mojo-it + org.eclipse.jetty.its.jetty-start-forked-mojo-it jetty-simple-base ${project.version} diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/postbuild.groovy similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/postbuild.groovy index 860da97a49c..a5dd520fb75 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-forked-mojo-it/postbuild.groovy @@ -14,6 +14,6 @@ s.close() File buildLog = new File( basedir, 'build.log' ) assert buildLog.text.contains( 'Forked process starting' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') assert buildLog.text.contains( 'pingServlet ok') assert buildLog.text.contains( 'helloServlet') diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/pom.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/pom.xml similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/pom.xml diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/src/main/java/org/olamy/App.java b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/java/org/olamy/App.java similarity index 88% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/src/main/java/org/olamy/App.java rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/java/org/olamy/App.java index e6e8d9d8993..19d099dc4c9 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/src/main/java/org/olamy/App.java +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/java/org/olamy/App.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.olamy; @@ -44,9 +44,9 @@ public class App implements EntryPoint * The message displayed to the user when the server cannot be reached or * returns an error. */ - private static final String SERVER_ERROR = "An error occurred while " - + "attempting to contact the server. Please check your network " - + "connection and try again."; + private static final String SERVER_ERROR = "An error occurred while " + + "attempting to contact the server. Please check your network " + + "connection and try again."; /** * Create a remote service proxy to talk to the server-side Greeting service. diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/src/main/module.gwt.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/module.gwt.xml similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-client/src/main/module.gwt.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/module.gwt.xml diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/pom.xml similarity index 87% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/pom.xml index 1417ac27263..16894d63833 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/pom.xml @@ -12,7 +12,8 @@ war - ${project.build.directory}/jetty-run-mojo.txt + ${project.build.directory}/jetty-start-mojo.txt + EMBED @@ -71,6 +72,9 @@ org.apache.maven.plugins maven-surefire-plugin + + IntegrationTest*.java + ${jetty.port.file} Please enter your name @@ -89,18 +93,16 @@ run test-compile - run + start - - jetty.port.file - ${jetty.port.file} - + ${jetty.port.file} - true ${basedir}/src/main/jettyconf/context.xml - ${basedir}/src/config/jetty.xml + + ${basedir}/src/config/jetty.xml + diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/config/jetty.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/config/jetty.xml index ced70a66d09..4e43b5305df 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/config/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024
      @@ -24,7 +24,7 @@
      - + diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java similarity index 56% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java index 190f491ce06..014d08f86c0 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.olamy; diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/jettyconf/context.xml similarity index 61% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/jettyconf/context.xml index eaea86d15cf..e1ab206a186 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/jettyconf/context.xml +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/jettyconf/context.xml @@ -1,3 +1,5 @@ + + org.eclipse.jetty.servlet.Default.useFileMappedBuffer diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml similarity index 67% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml index 4ece79123db..fe9829584d3 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/WEB-INF/web.xml @@ -1,9 +1,7 @@ - + - + greetServlet org.olamy.GreetingServiceImpl diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/beer.css b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/beer.css similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/beer.css rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/beer.css diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/favicon.ico b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/favicon.ico similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/favicon.ico rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/favicon.ico diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/index.html b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/index.html similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/main/webapp/index.html rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/webapp/index.html diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/pom.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/pom.xml similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/pom.xml diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java similarity index 67% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java index 108466ff435..62084035ac2 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.olamy; diff --git a/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java new file mode 100644 index 00000000000..ea8a3928b9b --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java @@ -0,0 +1,59 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.olamy; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public class GreetingResponse implements Serializable +{ + private String greeting; + private String serverInfo; + private String userAgent; + + public String getGreeting() + { + return greeting; + } + + public void setGreeting(String greeting) + { + this.greeting = greeting; + } + + public String getServerInfo() + { + return serverInfo; + } + + public void setServerInfo(String serverInfo) + { + this.serverInfo = serverInfo; + } + + public String getUserAgent() + { + return userAgent; + } + + public void setUserAgent(String userAgent) + { + this.userAgent = userAgent; + } +} diff --git a/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java new file mode 100644 index 00000000000..93b0690016f --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.olamy; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +/** + * The client side stub for the RPC service. + */ +@RemoteServiceRelativePath("greet") +public interface GreetingService extends RemoteService +{ + GreetingResponse greetServer(String name) throws IllegalArgumentException; +} diff --git a/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java new file mode 100644 index 00000000000..9b9e0cafbb9 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.olamy; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +/** + * The async counterpart of GreetingService. + */ +public interface GreetingServiceAsync +{ + void greetServer(String input, AsyncCallback callback) + throws IllegalArgumentException; +} diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-gwt-it/invoker.properties similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/invoker.properties rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/invoker.properties diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-gwt-it/pom.xml similarity index 100% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/pom.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-gwt-it/postbuild.groovy similarity index 89% rename from jetty-maven-plugin/src/it/jetty-run-mojo-jsp/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-gwt-it/postbuild.groovy index 4c4b42e2f2f..5aceb984967 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-jsp/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-gwt-it/postbuild.groovy @@ -17,6 +17,6 @@ * under the License. */ File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') +assert buildLog.text.contains( 'Started Server' ) +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') assert buildLog.text.contains( 'contentCheck') diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java new file mode 100644 index 00000000000..91225fae1b5 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_start_mojo_it; + +@SuppressWarnings("serial") +public class Counter implements java.io.Serializable +{ + int counter = 0; + String last; + + public int getCount() + { + counter++; + return counter; + } + + public void setLast(String uri) + { + last = uri; + } + + public String getLast() + { + return last; + } +} + diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java index 64df66b845e..2ab9f3bb706 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.its.jetty_start_mojo_it; diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java index d4718cc2662..a4fb8d8739c 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.its.jetty_start_mojo_it; diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml index 9c4cf1d1c51..71f60900d19 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml @@ -64,10 +64,16 @@ org.apache.maven.plugins maven-surefire-plugin + + IntegrationTest*.java + ${jetty.port.file} + /setbycontextxml true true + Counter accessed 1 times. + /jsp/bean1.jsp ${project.groupId}:${project.artifactId} @@ -86,13 +92,14 @@ start + ${basedir}/src/config/context.xml - - jetty.port.file - ${jetty.port.file} - + ${jetty.port.file} + EMBED - ${basedir}/src/config/jetty.xml + + ${basedir}/src/config/jetty.xml + diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/context.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/context.xml new file mode 100644 index 00000000000..3eb5570a37d --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/context.xml @@ -0,0 +1,7 @@ + + + + + /setbycontextxml + + diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml index ced70a66d09..4e43b5305df 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -24,7 +24,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp new file mode 100644 index 00000000000..586a27ebf2e --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/main/webapp/jsp/bean1.jsp @@ -0,0 +1,13 @@ + +<%@ page session="true"%> + + + +

      JSP1.2 Beans: 1

      + +Counter accessed times.
      +Counter last accessed by
      + + + + diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-mojo-it/postbuild.groovy index 323b5da5d72..9bc3c598f11 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/postbuild.groovy @@ -17,7 +17,7 @@ * under the License. */ File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') +assert buildLog.text.contains( 'Started Server' ) +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') assert buildLog.text.contains( 'pingServlet ok') -assert buildLog.text.contains( 'helloServlet') \ No newline at end of file +assert buildLog.text.contains( 'helloServlet') diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/common/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/pom.xml similarity index 85% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/common/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/pom.xml index 06de7ece78d..8ac4e43a071 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/common/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it jetty-multi-module-project 1.0-SNAPSHOT diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java new file mode 100644 index 00000000000..591a867ca14 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java @@ -0,0 +1,24 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package mca.common; + +public class CommonService +{ + +} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/invoker.properties similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/invoker.properties rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/invoker.properties diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-api/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/pom.xml similarity index 85% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-api/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/pom.xml index f3a237dbd74..02b7893f051 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-api/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it module 1.0-SNAPSHOT diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java new file mode 100644 index 00000000000..401dbb1049b --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java @@ -0,0 +1,24 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package mca.module; + +public interface ModuleApi +{ + +} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-impl/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/pom.xml similarity index 79% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-impl/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/pom.xml index 0e26990e518..4cca9837cd9 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/module-impl/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it module 1.0-SNAPSHOT @@ -10,7 +10,7 @@ - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it module-api diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java new file mode 100644 index 00000000000..d8e87efe910 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package mca.module; + +import mca.common.CommonService; + +public class ModuleImpl implements ModuleApi +{ + + private static final CommonService cs = new CommonService(); +} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/pom.xml similarity index 83% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/pom.xml index f91edba7216..fe53f4f610a 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/module/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it jetty-multi-module-project 1.0-SNAPSHOT @@ -16,7 +16,7 @@ - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it common diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/pom.xml similarity index 83% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/pom.xml index a098c9a06d1..aff947e2c64 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/pom.xml @@ -8,7 +8,7 @@ 0.0.1-SNAPSHOT - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it jetty-multi-module-project 1.0-SNAPSHOT pom @@ -31,17 +31,17 @@ - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it common ${project.version} - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it module-api ${project.version} - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it module-impl ${project.version} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/postbuild.groovy similarity index 93% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/postbuild.groovy index 202881ac1a1..4e37335b279 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/postbuild.groovy @@ -17,11 +17,11 @@ * under the License. */ File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) +assert buildLog.text.contains( 'Started Server' ) assert buildLog.text.contains( '(1a) >> javax.servlet.ServletContextListener loaded from jar:' ) -assert buildLog.text.contains( '/org/eclipse/jetty/toolchain/jetty-servlet-api/4.0.2/jetty-servlet-api-4.0.2.jar!/javax/servlet/ServletContextListener.class << (1b)' ) +assert buildLog.text.contains( '/org/eclipse/jetty/toolchain/jetty-servlet-api/4.0.3/jetty-servlet-api-4.0.3.jar!/javax/servlet/ServletContextListener.class << (1b)' ) assert buildLog.text.contains( '(2a) >> mca.common.CommonService loaded from file:' ) assert buildLog.text.contains( 'common/target/classes/mca/common/CommonService.class << (2b)' ) diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/pom.xml similarity index 72% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/pom.xml index 99c213c243b..42212b14e2c 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it jetty-multi-module-project 1.0-SNAPSHOT @@ -15,13 +15,14 @@ jetty-servlet
      - test.jetty-run-mojo-multi-module-single-war-it + test.jetty-start-mojo-multi-module-single-war-it module-impl
      - ${project.build.directory}/jetty-run-mojo.txt + ${project.build.directory}/jetty-start-mojo.txt + EMBED @@ -38,13 +39,11 @@ - - jetty.port.file - ${jetty.port.file} - + ${jetty.port.file} - true - ${basedir}/src/config/jetty.xml + + ${basedir}/src/config/jetty.xml + diff --git a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml index ced70a66d09..4e43b5305df 100644 --- a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/config/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -24,7 +24,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java similarity index 58% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java index c7ba86c9802..97249950177 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package mca.webapp; diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-mojo-multi-module-single-war-it/webapp-war/src/main/webapp/WEB-INF/web.xml rename to jetty-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/webapp/WEB-INF/web.xml diff --git a/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/invoker.properties new file mode 100644 index 00000000000..d2583001859 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = verify -V -X +#test-compile failsafe:integration-test diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/pom.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/pom.xml index 601aae0d1d1..c8a7dd2e001 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-mojo-it + org.eclipse.jetty.its.jetty-start-war-distro-mojo-it jetty-simple-project 0.0.1-SNAPSHOT @@ -36,5 +36,4 @@ jackson-databind
      - diff --git a/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java new file mode 100644 index 00000000000..2113fd7ef93 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_run_mojo_it; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + */ +@WebServlet("/hello") +public class HelloServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java new file mode 100644 index 00000000000..4d677e98359 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_run_mojo_it; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class PingServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("pong " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml rename to jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/pom.xml similarity index 73% rename from jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/pom.xml index 67b31e5a081..56dbb00c894 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-war-mojo-it + org.eclipse.jetty.its.jetty-start-war-distro-mojo-it jetty-simple-project 0.0.1-SNAPSHOT @@ -14,11 +14,14 @@ Jetty :: Simple :: Webapp - ${project.build.directory}/jetty-run-war-port.txt + ${project.build.directory}/jetty-start-war-distro-port.txt + @jetty.jvmArgs@ + DISTRO + - org.eclipse.jetty.its.jetty-run-war-mojo-it + org.eclipse.jetty.its.jetty-start-war-distro-mojo-it jetty-simple-base @@ -65,6 +68,9 @@ org.apache.maven.plugins maven-failsafe-plugin + + IntegrationTest*.java + ${jetty.port.file} true @@ -74,9 +80,6 @@ org.eclipse.jetty:jetty-maven-plugin - - **/*TestGetContent* - @@ -99,19 +102,24 @@ start-jetty - test-compile + pre-integration-test - run-war + start-war - true - - - jetty.port.file - ${jetty.port.file} - - - ${basedir}/src/config/jetty.xml + @jetty.stopPort@ + @jetty.stopKey@ + + + + ${basedir}/src/base + ${java.home}/bin/java + + true + ${jetty.port.file} + 0 + + jsp,jstl,testmod diff --git a/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml new file mode 100644 index 00000000000..c3df301c562 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod new file mode 100644 index 00000000000..e451df43f4a --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod @@ -0,0 +1,12 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Enables test setup + +[depend] +http + + +[xml] +etc/test-jetty.xml + diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml rename to jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/pom.xml similarity index 90% rename from jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/pom.xml index b6ac179988a..04d866e7d3d 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/pom.xml @@ -8,7 +8,7 @@ 0.0.1-SNAPSHOT - org.eclipse.jetty.its.jetty-run-war-exploded-mojo-it + org.eclipse.jetty.its.jetty-start-war-distro-mojo-it jetty-simple-project 0.0.1-SNAPSHOT pom @@ -30,7 +30,7 @@ - org.eclipse.jetty.its.jetty-run-war-exploded-mojo-it + org.eclipse.jetty.its.jetty-start-war-distro-mojo-it jetty-simple-base ${project.version} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/postbuild.groovy similarity index 65% rename from jetty-maven-plugin/src/it/jetty-run-war-mojo-it/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/postbuild.groovy index 323b5da5d72..04e88808083 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-war-distro-mojo-it/postbuild.groovy @@ -16,8 +16,20 @@ * specific language governing permissions and limitations * under the License. */ +System.out.println( "running postbuild.groovy port " + jettyStopPort + ", key:" + jettyStopKey ) + +int port = Integer.parseInt( jettyStopPort ) + +Socket s=new Socket(InetAddress.getByName("127.0.0.1"),port ) + +OutputStream out=s.getOutputStream() +out.write(( jettyStopKey +"\r\nforcestop\r\n").getBytes()) +out.flush() +s.close() + + File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') +assert buildLog.text.contains( 'Distro process starting' ) +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') assert buildLog.text.contains( 'pingServlet ok') -assert buildLog.text.contains( 'helloServlet') \ No newline at end of file +assert buildLog.text.contains( 'helloServlet') diff --git a/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/invoker.properties new file mode 100644 index 00000000000..d2583001859 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = verify -V -X +#test-compile failsafe:integration-test diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/pom.xml similarity index 95% rename from jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/pom.xml index 348a3bc6e8d..f5126ccc20c 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-war-exploded-mojo-it + org.eclipse.jetty.its.jetty-start-war-forked-mojo-it jetty-simple-project 0.0.1-SNAPSHOT diff --git a/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java new file mode 100644 index 00000000000..c0d21ec60dc --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_run_war_exploded_mojo_it; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + */ +@WebServlet("/hello") +public class HelloServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("Hello " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java new file mode 100644 index 00000000000..4ad955b67ae --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.its.jetty_run_war_exploded_mojo_it; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class PingServlet + extends HttpServlet +{ + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + String who = req.getParameter("name"); + + resp.getWriter().write("pong " + (who == null ? "unknown" : who)); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/pom.xml similarity index 78% rename from jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/pom.xml index 7c9eae6c588..4a8890ca97d 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/pom.xml @@ -3,9 +3,10 @@ 4.0.0 - org.eclipse.jetty.its.jetty-run-war-exploded-mojo-it + org.eclipse.jetty.its.jetty-start-war-forked-mojo-it jetty-simple-project 0.0.1-SNAPSHOT + ../pom.xml jetty-simple-webapp @@ -14,12 +15,13 @@ Jetty :: Simple :: Webapp - ${project.build.directory}/jetty-run-war-exploded-port.txt + ${project.build.directory}/jetty-start-war-forked-port.txt + FORK - org.eclipse.jetty.its.jetty-run-war-exploded-mojo-it + org.eclipse.jetty.its.jetty-start-war-forked-mojo-it jetty-simple-base @@ -62,6 +64,32 @@ true + + org.eclipse.jetty + jetty-maven-plugin + + + start-jetty + pre-integration-test + + start-war + + + @jetty.stopPort@ + @jetty.stopKey@ + + ${project.build.directory}/${project.artifactId}-${project.version} + + + ${jetty.port.file} + + + ${basedir}/src/config/jetty.xml + + + + + org.apache.maven.plugins maven-failsafe-plugin @@ -94,29 +122,6 @@ - - org.eclipse.jetty - jetty-maven-plugin - - - start-jetty - test-compile - - run-exploded - - - true - - - jetty.port.file - ${jetty.port.file} - - - ${basedir}/src/config/jetty.xml - - - - diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml similarity index 94% rename from jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml index ced70a66d09..4e43b5305df 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -8,7 +8,7 @@ 32768 8192 8192 - 4096 + 1024 @@ -24,7 +24,7 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/pom.xml similarity index 85% rename from jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/pom.xml index 4b7fea358b2..0d5808b0ca0 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/pom.xml @@ -6,9 +6,10 @@ org.eclipse.jetty.its it-parent-pom 0.0.1-SNAPSHOT + ../it-parent-pom/pom.xml - org.eclipse.jetty.its.jetty-run-distro-mojo-it + org.eclipse.jetty.its.jetty-start-war-forked-mojo-it jetty-simple-project 0.0.1-SNAPSHOT pom @@ -30,7 +31,7 @@ - org.eclipse.jetty.its.jetty-run-distro-mojo-it + org.eclipse.jetty.its.jetty-start-war-forked-mojo-it jetty-simple-base ${project.version} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/postbuild.groovy similarity index 54% rename from jetty-maven-plugin/src/it/jetty-run-mojo-it/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/postbuild.groovy index 323b5da5d72..2f165faf210 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-war-forked-mojo-it/postbuild.groovy @@ -16,8 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') -assert buildLog.text.contains( 'pingServlet ok') -assert buildLog.text.contains( 'helloServlet') \ No newline at end of file +System.out.println( "running postbuild.groovy port " + jettyStopPort + ", key:" + jettyStopKey ) + +int port = Integer.parseInt( jettyStopPort ) + +Socket s=new Socket(InetAddress.getByName("127.0.0.1"),port ) + +OutputStream out=s.getOutputStream() +out.write(( jettyStopKey +"\r\nforcestop\r\n").getBytes()) +out.flush() +s.close() + +File outputLog = new File( basedir, 'build.log' ) +assert outputLog.text.contains( 'Forked process starting' ) +assert outputLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') +assert outputLog.text.contains( 'pingServlet ok') +assert outputLog.text.contains( 'helloServlet') diff --git a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/invoker.properties similarity index 100% rename from jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/invoker.properties rename to jetty-maven-plugin/src/it/jetty-start-war-mojo-it/invoker.properties diff --git a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/pom.xml similarity index 70% rename from jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml rename to jetty-maven-plugin/src/it/jetty-start-war-mojo-it/pom.xml index 217882f4361..479aa35257e 100644 --- a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/pom.xml @@ -8,15 +8,15 @@ 0.0.1-SNAPSHOT - org.eclipse.jetty.its.jetty-deploy-war-mojo-it + org.eclipse.jetty.its.jetty-start-war-mojo-it jetty-simple-project 0.0.1-SNAPSHOT pom - Jetty :: Simple deploy war mojo test + Jetty :: Simple start war mojo test - ${project.build.directory}/jetty-deploy-war-port.txt + ${project.build.directory}/jetty-start-war-port.txt @@ -75,24 +75,36 @@ start-jetty test-compile - deploy-war + start-war pom - ${project.build.directory}/bean-validation-webapp-2.25.1.war - true + + ${project.build.directory}/bean-validation-webapp-2.25.1.war + - - jetty.port.file - ${jetty.port.file} - + ${jetty.port.file} - ${basedir}/src/config/jetty.xml + + ${basedir}/src/config/jetty.xml + + + + javax.xml.bind + jaxb-api + 2.4.0-b180830.0359 + + + javax.activation + javax.activation-api + 1.2.0 + + @@ -121,40 +133,7 @@ - - - - jdk9+ - - [1.9,) - - - - - - org.eclipse.jetty - jetty-maven-plugin - - - javax.xml.bind - jaxb-api - 2.4.0-b180830.0359 - - - javax.activation - javax.activation-api - 1.2.0 - - - - - - - - - - diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/postbuild.groovy similarity index 85% rename from jetty-maven-plugin/src/it/run-mojo-gwt-it/postbuild.groovy rename to jetty-maven-plugin/src/it/jetty-start-war-mojo-it/postbuild.groovy index b5f4344c4a6..5aceb984967 100644 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/postbuild.groovy +++ b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/postbuild.groovy @@ -17,6 +17,6 @@ * under the License. */ File buildLog = new File( basedir, 'build.log' ) -assert buildLog.text.contains( 'Started Jetty Server' ) -assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.TestGetContent') -assert buildLog.text.contains( 'contentCheck') \ No newline at end of file +assert buildLog.text.contains( 'Started Server' ) +assert buildLog.text.contains( 'Running org.eclipse.jetty.maven.plugin.it.IntegrationTestGetContent') +assert buildLog.text.contains( 'contentCheck') diff --git a/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/src/config/jetty.xml new file mode 100644 index 00000000000..4e43b5305df --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-start-war-mojo-it/src/config/jetty.xml @@ -0,0 +1,40 @@ + + + + + + https + + 32768 + 8192 + 8192 + 1024 + + + + + + + + + + + + + + + + + + + + + + + + + 30000 + + + + diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml b/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml deleted file mode 100644 index ced70a66d09..00000000000 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/src/config/jetty.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - https - - 32768 - 8192 - 8192 - 4096 - - - - - - - - - - - - - - - - - - - - - - - - - 30000 - - - - diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java b/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java deleted file mode 100644 index aa92eeb22f8..00000000000 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.olamy; - -import java.io.Serializable; - -@SuppressWarnings("serial") -public class GreetingResponse implements Serializable -{ - private String greeting; - private String serverInfo; - private String userAgent; - - public String getGreeting() - { - return greeting; - } - - public void setGreeting(String greeting) - { - this.greeting = greeting; - } - - public String getServerInfo() - { - return serverInfo; - } - - public void setServerInfo(String serverInfo) - { - this.serverInfo = serverInfo; - } - - public String getUserAgent() - { - return userAgent; - } - - public void setUserAgent(String userAgent) - { - this.userAgent = userAgent; - } -} diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java b/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java deleted file mode 100644 index d4084b162c8..00000000000 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.olamy; - -import com.google.gwt.user.client.rpc.RemoteService; -import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; - -/** - * The client side stub for the RPC service. - */ -@RemoteServiceRelativePath("greet") -public interface GreetingService extends RemoteService -{ - GreetingResponse greetServer(String name) throws IllegalArgumentException; -} diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java b/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java deleted file mode 100644 index 7cf480ac432..00000000000 --- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.olamy; - -import com.google.gwt.user.client.rpc.AsyncCallback; - -/** - * The async counterpart of GreetingService. - */ -public interface GreetingServiceAsync -{ - void greetServer(String input, AsyncCallback callback) - throws IllegalArgumentException; -} diff --git a/jetty-maven-plugin/src/it/settings.xml b/jetty-maven-plugin/src/it/settings.xml index c78e01dff9d..d64bdb89034 100644 --- a/jetty-maven-plugin/src/it/settings.xml +++ b/jetty-maven-plugin/src/it/settings.xml @@ -1,13 +1,6 @@ - - - local.mirror - file://@localRepo@ - central - - it-repo diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java new file mode 100644 index 00000000000..7c544dace82 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java @@ -0,0 +1,255 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.util.List; +import java.util.Map; + +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * AbstractForker + * + * Base class for forking jetty. + */ +public abstract class AbstractForker extends AbstractLifeCycle +{ + private static final Logger LOG = LoggerFactory.getLogger(AbstractForker.class); + + protected Map env; + + protected String jvmArgs; + + protected boolean exitVm; + + protected boolean stopAtShutdown; + + protected List jettyXmlFiles; + + protected Map jettyProperties; + + protected int stopPort; + + protected String stopKey; + + protected File jettyOutputFile; + + protected boolean waitForChild; + + protected int maxChildStartChecks = 10; //check up to 10 times for child to start + + protected long maxChildStartCheckMs = 200; //wait 200ms between checks + + protected File tokenFile; + + protected File workDir; + + protected Map systemProperties; + + protected abstract ProcessBuilder createCommand(); + + protected abstract void redeployWebApp() throws Exception; + + public File getWorkDir() + { + return workDir; + } + + public void setWorkDir(File workDir) + { + this.workDir = workDir; + } + + /** + * @return the systemProperties + */ + public Map getSystemProperties() + { + return systemProperties; + } + + /** + * @param systemProperties the systemProperties to set + */ + public void setSystemProperties(Map systemProperties) + { + this.systemProperties = systemProperties; + } + + public Map getEnv() + { + return env; + } + + public void setEnv(Map env) + { + this.env = env; + } + + public String getJvmArgs() + { + return jvmArgs; + } + + public void setJvmArgs(String jvmArgs) + { + this.jvmArgs = jvmArgs; + } + + public boolean isExitVm() + { + return exitVm; + } + + public void setExitVm(boolean exitVm) + { + this.exitVm = exitVm; + } + + public boolean isStopAtShutdown() + { + return stopAtShutdown; + } + + public void setStopAtShutdown(boolean stopAtShutdown) + { + this.stopAtShutdown = stopAtShutdown; + } + + public List getJettyXmlFiles() + { + return jettyXmlFiles; + } + + public void setJettyXmlFiles(List jettyXmlFiles) + { + this.jettyXmlFiles = jettyXmlFiles; + } + + public Map getJettyProperties() + { + return jettyProperties; + } + + public void setJettyProperties(Map jettyProperties) + { + this.jettyProperties = jettyProperties; + } + + public int getStopPort() + { + return stopPort; + } + + public void setStopPort(int stopPort) + { + this.stopPort = stopPort; + } + + public String getStopKey() + { + return stopKey; + } + + public void setStopKey(String stopKey) + { + this.stopKey = stopKey; + } + + public File getJettyOutputFile() + { + return jettyOutputFile; + } + + public void setJettyOutputFile(File jettyOutputFile) + { + this.jettyOutputFile = jettyOutputFile; + } + + public boolean isWaitForChild() + { + return waitForChild; + } + + public void setWaitForChild(boolean waitForChild) + { + this.waitForChild = waitForChild; + } + + public int getMaxChildtartChecks() + { + return maxChildStartChecks; + } + + public void setMaxChildStartChecks(int maxChildStartChecks) + { + this.maxChildStartChecks = maxChildStartChecks; + } + + public long getMaxChildStartCheckMs() + { + return maxChildStartCheckMs; + } + + public void setMaxChildStartCheckMs(long maxChildStartCheckMs) + { + this.maxChildStartCheckMs = maxChildStartCheckMs; + } + + public File getTokenFile() + { + return tokenFile; + } + + public void setTokenFile(File tokenFile) + { + this.tokenFile = tokenFile; + } + + public void doStart() + throws Exception + { + super.doStart(); + + //Create the command to fork + ProcessBuilder command = createCommand(); + Process process = command.start(); + + if (waitForChild) + { + //keep executing until the child dies + process.waitFor(); + } + else + { + //just wait until the child has started successfully + int attempts = maxChildStartChecks; + while (!tokenFile.exists() && attempts > 0) + { + Thread.sleep(maxChildStartCheckMs); + --attempts; + } + if (attempts <= 0) + LOG.info("Couldn't verify success of child startup"); + } + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java deleted file mode 100644 index 9cd178766d4..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java +++ /dev/null @@ -1,725 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.StringUtils; -import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ShutdownMonitor; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.util.PathWatcher; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.resource.PathResource; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; - -/** - * Common base class for most jetty mojos. - */ -public abstract class AbstractJettyMojo extends AbstractMojo -{ - /** - * Whether or not to include dependencies on the plugin's classpath with <scope>provided</scope> - * Use WITH CAUTION as you may wind up with duplicate jars/classes. - * - * @since jetty-7.5.2 - */ - @Parameter(defaultValue = "false") - protected boolean useProvidedScope; - - /** - * List of goals that are NOT to be used - * - * @since jetty-7.5.2 - */ - @Parameter - protected String[] excludedGoals; - - /** - * List of other contexts to set up. Consider using instead - * the <jettyXml> element to specify external jetty xml config file. - * Optional. - */ - @Parameter - protected ContextHandler[] contextHandlers; - - /** - * List of security realms to set up. Consider using instead - * the <jettyXml> element to specify external jetty xml config file. - * Optional. - */ - @Parameter - protected LoginService[] loginServices; - - /** - * A RequestLog implementation to use for the webapp at runtime. - * Consider using instead the <jettyXml> element to specify external jetty xml config file. - * Optional. - */ - @Parameter - protected RequestLog requestLog; - - /** - * An instance of org.eclipse.jetty.webapp.WebAppContext that represents the webapp. - * Use any of its setters to configure the webapp. This is the preferred and most - * flexible method of configuration, rather than using the (deprecated) individual - * parameters like "tmpDirectory", "contextPath" etc. - */ - @Parameter(alias = "webAppConfig") - protected JettyWebAppContext webApp; - - /** - * The interval in seconds to scan the webapp for changes - * and restart the context if necessary. Ignored if reload - * is enabled. Disabled by default. - */ - @Parameter(property = "jetty.scanIntervalSeconds", defaultValue = "0", required = true) - protected int scanIntervalSeconds; - - /** - * reload can be set to either 'automatic' or 'manual' - * - * if 'manual' then the context can be reloaded by a linefeed in the console - * if 'automatic' then traditional reloading on changed files is enabled. - */ - @Parameter(property = "jetty.reload", defaultValue = "automatic") - protected String reload; - - /** - * File containing system properties to be set before execution - * - * Note that these properties will NOT override System properties - * that have been set on the command line, by the JVM, or directly - * in the POM via systemProperties. Optional. - */ - @Parameter(property = "jetty.systemPropertiesFile") - protected File systemPropertiesFile; - - /** - * System properties to set before execution. - * Note that these properties will NOT override System properties - * that have been set on the command line or by the JVM. They WILL - * override System properties that have been set via systemPropertiesFile. - * Optional. - */ - @Parameter - protected SystemProperties systemProperties; - - /** - * Comma separated list of a jetty xml configuration files whose contents - * will be applied before any plugin configuration. Optional. - */ - @Parameter(alias = "jettyConfig") - protected String jettyXml; - - /** - * Port to listen to stop jetty on executing -DSTOP.PORT=<stopPort> - * -DSTOP.KEY=<stopKey> -jar start.jar --stop - */ - @Parameter - protected int stopPort; - - /** - * Key to provide when stopping jetty on executing java -DSTOP.KEY=<stopKey> - * -DSTOP.PORT=<stopPort> -jar start.jar --stop - */ - @Parameter - protected String stopKey; - - /** - * Use the dump() facility of jetty to print out the server configuration to logging - */ - @Parameter(property = "dumponStart", defaultValue = "false") - protected boolean dumpOnStart; - - /** - * Skip this mojo execution. - */ - @Parameter(property = "jetty.skip", defaultValue = "false") - protected boolean skip; - - /** - * Location of a context xml configuration file whose contents - * will be applied to the webapp AFTER anything in <webApp>.Optional. - */ - @Parameter(alias = "webAppXml") - protected String contextXml; - - /** - * The maven project. - */ - @Parameter(defaultValue = "${project}", readonly = true) - protected MavenProject project; - - /** - * The artifacts for the project. - */ - @Parameter(defaultValue = "${project.artifacts}", readonly = true) - protected Set projectArtifacts; - - @Parameter(defaultValue = "${mojoExecution}", readonly = true) - protected MojoExecution execution; - - /** - * The artifacts for the plugin itself. - */ - @Parameter(defaultValue = "${plugin.artifacts}", readonly = true) - protected List pluginArtifacts; - - /** - * A ServerConnector to use. - */ - @Parameter - protected MavenServerConnector httpConnector; - - /** - * A wrapper for the Server object - */ - @Parameter - protected Server server; - - /** - * A scanner to check for changes to the webapp - */ - protected PathWatcher scanner; - - /** - * A scanner to check ENTER hits on the console - */ - protected Thread consoleScanner; - - protected ServerSupport serverSupport; - - /** - *

      - * Determines whether or not the server blocks when started. The default - * behavior (false) will cause the server to pause other processes - * while it continues to handle web requests. This is useful when starting the - * server with the intent to work with it interactively. This is the - * behaviour of the jetty:run, jetty:run-war, jetty:run-war-exploded goals. - *

      - * If true, the server will not block the execution of subsequent code. This - * is the behaviour of the jetty:start and default behaviour of the jetty:deploy goals. - *

      - */ - @Parameter(defaultValue = "false") - protected boolean nonBlocking = false; - - /** - * Per default this goal support only war packaging. - * If your project use an other type please configure it here. - */ - @Parameter - protected List supportedPackagings = Collections.singletonList("war"); - - public abstract void restartWebApp(boolean reconfigureScanner) throws Exception; - - public boolean checkPomConfiguration() throws MojoExecutionException - { - return true; - } - - public abstract void configureScanner() throws MojoExecutionException; - - protected String getSkipMessage(String reason) - { - String projectName = project.getName(); - if (StringUtils.isBlank(projectName)) - { - projectName = project.getGroupId() + ":" + project.getArtifactId(); - } - return "Skipping " + projectName + " : " + reason; - } - - public boolean checkPackagingConfiguration() - { - if (!supportedPackagings.contains(project.getPackaging())) - { - getLog().info(getSkipMessage("packaging type [" + project.getPackaging() + "] is unsupported")); - return false; - } - return true; - } - - /** - * @see org.apache.maven.plugin.Mojo#execute() - */ - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - if (isConfigurationSupported()) - { - if (skip) - { - getLog().info(getSkipMessage("jetty.skip==true")); - return; - } - - getLog().info("Configuring Jetty for project: " + this.project.getName()); - - if (isExcluded(execution.getMojoDescriptor().getGoal())) - { - getLog().info("The goal \"" + execution.getMojoDescriptor().getFullGoalName() + - "\" has been made unavailable for this web application by an configuration."); - return; - } - - configurePluginClasspath(); - PluginLog.setLog(getLog()); - startJetty(); - } - } - - public boolean isConfigurationSupported() throws MojoExecutionException - { - return (checkPackagingConfiguration() && checkPomConfiguration()); - } - - public void configurePluginClasspath() throws MojoExecutionException - { - //if we are configured to include the provided dependencies on the plugin's classpath - //(which mimics being on jetty's classpath vs being on the webapp's classpath), we first - //try and filter out ones that will clash with jars that are plugin dependencies, then - //create a new classloader that we setup in the parent chain. - if (useProvidedScope) - { - try - { - List provided = new ArrayList<>(); - - for (Artifact artifact : projectArtifacts) - { - if (Artifact.SCOPE_PROVIDED.equals(artifact.getScope()) && !isPluginArtifact(artifact)) - { - provided.add(artifact.getFile().toURI().toURL()); - if (getLog().isDebugEnabled()) - { - getLog().debug("Adding provided artifact: " + artifact); - } - } - } - - if (!provided.isEmpty()) - { - URL[] urls = provided.stream().toArray(URL[]::new); - URLClassLoader loader = new URLClassLoader(urls, getClass().getClassLoader()); - Thread.currentThread().setContextClassLoader(loader); - getLog().info("Plugin classpath augmented with provided dependencies: " + Arrays.toString(urls)); - } - } - catch (MalformedURLException e) - { - throw new MojoExecutionException("Invalid url", e); - } - } - } - - public boolean isPluginArtifact(Artifact artifact) - { - if (pluginArtifacts == null || pluginArtifacts.isEmpty()) - return false; - - for (Artifact pluginArtifact : pluginArtifacts) - { - if (getLog().isDebugEnabled()) - { - getLog().debug("Checking " + pluginArtifact); - } - if (pluginArtifact.getGroupId().equals(artifact.getGroupId()) && - pluginArtifact.getArtifactId().equals(artifact.getArtifactId())) - return true; - } - - return false; - } - - public void finishConfigurationBeforeStart() throws Exception - { - HandlerCollection contexts = server.getChildHandlerByClass(ContextHandlerCollection.class); - if (contexts == null) - contexts = server.getChildHandlerByClass(HandlerCollection.class); - - for (int i = 0; (this.contextHandlers != null) && (i < this.contextHandlers.length); i++) - { - contexts.addHandler(this.contextHandlers[i]); - } - } - - public void applyJettyXml() throws Exception - { - Server tmp = ServerSupport.applyXmlConfigurations(server, getJettyXmlFiles()); - if (server == null) - server = tmp; - - if (server == null) - server = new Server(); - } - - public void startJetty() throws MojoExecutionException - { - try - { - getLog().debug("Starting Jetty Server ..."); - - //make sure Jetty does not use URLConnection caches with the plugin - Resource.setDefaultUseCaches(false); - - configureMonitor(); - - printSystemProperties(); - - //apply any config from a jetty.xml file first which is able to - //be overwritten by config in the pom.xml - applyJettyXml(); - - // if a was specified in the pom, use it - if (httpConnector != null) - { - - // check that its port was set - if (httpConnector.getPort() <= 0) - { - //use any jetty.http.port settings provided - String tmp = System.getProperty(MavenServerConnector.PORT_SYSPROPERTY, // - System.getProperty("jetty.port", MavenServerConnector.DEFAULT_PORT_STR)); - httpConnector.setPort(Integer.parseInt(tmp.trim())); - } - httpConnector.setServer(server); - } - - ServerSupport.configureConnectors(server, httpConnector); - - //set up a RequestLog if one is provided and the handle structure - ServerSupport.configureHandlers(server, this.requestLog); - - //Set up list of default Configurations to apply to a webapp - ServerSupport.configureDefaultConfigurationClasses(server); - configureWebApplication(); - ServerSupport.addWebApplication(server, webApp); - - // set up security realms - ServerSupport.configureLoginServices(server, loginServices); - - //do any other configuration required by the - //particular Jetty version - finishConfigurationBeforeStart(); - - // start Jetty - this.server.start(); - - getLog().info("Started Jetty Server"); - - if (dumpOnStart) - { - getLog().info(this.server.dump()); - } - - // start the scanner thread (if necessary) on the main webapp - if (isScanningEnabled()) - { - scanner = new PathWatcher(); - configureScanner(); - startScanner(); - } - - // start the new line scanner thread if necessary - startConsoleScanner(); - - // keep the thread going if not in daemon mode - if (!nonBlocking) - { - server.join(); - } - } - catch (Exception e) - { - throw new MojoExecutionException("Failure", e); - } - finally - { - if (!nonBlocking) - { - getLog().info("Jetty server exiting."); - } - } - } - - public void configureMonitor() - { - if (stopPort > 0 && stopKey != null) - { - ShutdownMonitor monitor = ShutdownMonitor.getInstance(); - monitor.setPort(stopPort); - monitor.setKey(stopKey); - monitor.setExitVm(!nonBlocking); - } - } - - /** - * Subclasses should invoke this to setup basic info - * on the webapp - * - * @throws Exception if unable to configure web application - */ - public void configureWebApplication() throws Exception - { - //As of jetty-7, you must use a element - if (webApp == null) - webApp = new JettyWebAppContext(); - - //Apply any context xml file to set up the webapp - //CAUTION: if you've defined a element then the - //context xml file can OVERRIDE those settings - if (contextXml != null) - { - Path path = Paths.get(contextXml); - if (!path.isAbsolute()) - { - Path workDir = Paths.get(System.getProperty("user.dir")); - path = workDir.resolve(path); - contextXml = path.toFile().getAbsolutePath(); - } - - XmlConfiguration xmlConfiguration = new XmlConfiguration(new PathResource(path)); - getLog().info("Applying context xml file " + contextXml); - xmlConfiguration.configure(webApp); - } - - //If no contextPath was specified, go with default of project artifactid - String cp = webApp.getContextPath(); - if (cp == null || "".equals(cp)) - { - cp = "/" + project.getArtifactId(); - webApp.setContextPath(cp); - } - - //If no tmp directory was specified, and we have one, use it - if (webApp.getTempDirectory() == null) - { - File target = new File(project.getBuild().getDirectory()); - File tmp = new File(target, "tmp"); - if (!tmp.exists()) - tmp.mkdirs(); - webApp.setTempDirectory(tmp); - } - - getLog().info("Context path = " + webApp.getContextPath()); - getLog().info("Tmp directory = " + (webApp.getTempDirectory() == null ? " determined at runtime" : webApp.getTempDirectory())); - getLog().info("Web defaults = " + (webApp.getDefaultsDescriptor() == null ? " jetty default" : webApp.getDefaultsDescriptor())); - getLog().info("Web overrides = " + (webApp.getOverrideDescriptor() == null ? " none" : webApp.getOverrideDescriptor())); - } - - /** - * Run a scanner thread on the given list of files and directories, calling - * stop/start on the given list of LifeCycle objects if any of the watched - * files change. - * - * @throws Exception if unable to start scanner - */ - public void startScanner() throws Exception - { - if (!isScanningEnabled()) - return; - - scanner.setNotifyExistingOnStart(false); - - scanner.start(); - } - - public boolean isScanningEnabled() - { - if (scanIntervalSeconds <= 0 || "manual".equalsIgnoreCase(reload)) - return false; - return true; - } - - public void stopScanner() throws Exception - { - if (!isScanningEnabled()) - return; - - if (scanner != null) - scanner.stop(); - } - - /** - * Run a thread that monitors the console input to detect ENTER hits. - * - * @throws Exception if unable to start the console - */ - protected void startConsoleScanner() throws Exception - { - if ("manual".equalsIgnoreCase(reload)) - { - getLog().info("Console reloading is ENABLED. Hit ENTER on the console to restart the context."); - consoleScanner = new ConsoleScanner(this); - consoleScanner.start(); - } - } - - protected void printSystemProperties() - { - // print out which system properties were set up - if (getLog().isDebugEnabled()) - { - if (systemProperties != null) - { - systemProperties.getSystemProperties().stream().forEach(prop -> - { - getLog().debug("Property " + prop.getName() + "=" + prop.getValue() + " was " + (prop.isSet() ? "set" : "skipped")); - }); - } - } - } - - /** - * Try and find a jetty-web.xml file, using some - * historical naming conventions if necessary. - * - * @param webInfDir the web inf directory - * @return the jetty web xml file - */ - public File findJettyWebXmlFile(File webInfDir) - { - if (webInfDir == null) - return null; - if (!webInfDir.exists()) - return null; - - File f = new File(webInfDir, "jetty-web.xml"); - if (f.exists()) - return f; - - //try some historical alternatives - f = new File(webInfDir, "web-jetty.xml"); - if (f.exists()) - return f; - - return null; - } - - public void setSystemPropertiesFile(File file) throws Exception - { - this.systemPropertiesFile = file; - Properties properties = new Properties(); - try (InputStream propFile = new FileInputStream(systemPropertiesFile)) - { - properties.load(propFile); - } - if (this.systemProperties == null) - this.systemProperties = new SystemProperties(); - - for (Enumeration keys = properties.keys(); keys.hasMoreElements(); ) - { - String key = (String)keys.nextElement(); - if (!systemProperties.containsSystemProperty(key)) - { - SystemProperty prop = new SystemProperty(); - prop.setKey(key); - prop.setValue(properties.getProperty(key)); - - this.systemProperties.setSystemProperty(prop); - } - } - } - - public void setSystemProperties(SystemProperties systemProperties) - { - if (this.systemProperties == null) - this.systemProperties = systemProperties; - else - { - for (SystemProperty prop : systemProperties.getSystemProperties()) - { - this.systemProperties.setSystemProperty(prop); - } - } - } - - public List getJettyXmlFiles() - { - if (this.jettyXml == null) - { - return null; - } - - List jettyXmlFiles = new ArrayList(); - - if (this.jettyXml.indexOf(',') == -1) - { - jettyXmlFiles.add(new File(this.jettyXml)); - } - else - { - String[] files = StringUtil.csvSplit(this.jettyXml); - - for (String file : files) - { - jettyXmlFiles.add(new File(file)); - } - } - - return jettyXmlFiles; - } - - public boolean isExcluded(String goal) - { - if (excludedGoals == null || goal == null) - return false; - - goal = goal.trim(); - if ("".equals(goal)) - return false; - - boolean excluded = false; - for (int i = 0; i < excludedGoals.length && !excluded; i++) - { - if (excludedGoals[i].equalsIgnoreCase(goal)) - excluded = true; - } - - return excluded; - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractUnassembledWebAppMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractUnassembledWebAppMojo.java new file mode 100644 index 00000000000..577e084063c --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractUnassembledWebAppMojo.java @@ -0,0 +1,252 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Parameter; +import org.eclipse.jetty.util.resource.Resource; + +/** + * Base class for all goals that operate on unassembled webapps. + * + */ +public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo +{ + /** + * The default location of the web.xml file. Will be used + * if <webApp><descriptor> is not set. + */ + @Parameter (defaultValue = "${project.baseDir}/src/main/webapp/WEB-INF/web.xml") + protected File webXml; + + /** + * The directory containing generated test classes. + * + */ + @Parameter (defaultValue = "${project.build.testOutputDirectory}", required = true) + protected File testClassesDirectory; + + /** + * An optional pattern for includes/excludes of classes in the testClassesDirectory + */ + @Parameter + protected ScanPattern scanTestClassesPattern; + + /** + * The directory containing generated classes. + */ + @Parameter (defaultValue = "${project.build.outputDirectory}", required = true) + protected File classesDirectory; + + + /** + * An optional pattern for includes/excludes of classes in the classesDirectory + */ + @Parameter + protected ScanPattern scanClassesPattern; + + + /** + * Default root directory for all html/jsp etc files. + * Used to initialize webApp.setBaseResource(). + */ + @Parameter (defaultValue = "${project.basedir}/src/main/webapp", readonly = true) + protected File webAppSourceDirectory; + + protected void verifyPomConfiguration() throws MojoExecutionException + { + //Does the default webapp static resource location exist? + if (!webAppSourceDirectory.exists()) + { + //try last resort of a fake directory + File target = new File(project.getBuild().getDirectory()); + webAppSourceDirectory = new File(target, FAKE_WEBAPP); + } + + // check the classes to form a classpath with + try + { + //allow a webapp with no classes in it (just jsps/html) + if (classesDirectory != null) + { + if (!classesDirectory.exists()) + getLog().info("Classes directory " + classesDirectory.getCanonicalPath() + " does not exist"); + else + getLog().info("Classes = " + classesDirectory.getCanonicalPath()); + } + else + getLog().info("Classes directory not set"); + } + catch (IOException e) + { + throw new MojoExecutionException("Location of classesDirectory does not exist"); + } + } + + @Override + protected void configureWebApp() throws Exception + { + super.configureWebApp(); + configureUnassembledWebApp(); + } + + /** + * Configure a webapp that has not been assembled into a war. + * + * @throws Exception + */ + protected void configureUnassembledWebApp() throws Exception + { + //Set up the location of the webapp. + //There are 2 parts to this: setWar() and setBaseResource(). On standalone jetty, + //the former could be the location of a packed war, while the latter is the location + //after any unpacking. With this mojo, you are running an unpacked, unassembled webapp, + //so the two locations should be equal. + + //The first time we run, remember the original base dir + if (originalBaseResource == null) + { + if (webApp.getBaseResource() == null) + { + //Use the default static resource location + if (!webAppSourceDirectory.exists()) + webAppSourceDirectory.mkdirs(); + originalBaseResource = Resource.newResource(webAppSourceDirectory.getCanonicalPath()); + } + else + originalBaseResource = webApp.getBaseResource(); + } + + //On every subsequent re-run set it back to the original base dir before + //we might have applied any war overlays onto it + webApp.setBaseResource(originalBaseResource); + + if (webApp.getWar() == null) + webApp.setWar(originalBaseResource.getURI().toURL().toExternalForm()); + + if (classesDirectory != null) + webApp.setClasses(classesDirectory); + + if (useTestScope && (testClassesDirectory != null)) + webApp.setTestClasses(testClassesDirectory); + + List webInfLibs = getWebInfLibArtifacts().stream() + .map(a -> + { + Path p = mavenProjectHelper.getPathFor(a); + getLog().debug("Artifact " + a.getId() + " loaded from " + p + " added to WEB-INF/lib"); + return p.toFile(); + }).collect(Collectors.toList()); + + webApp.setWebInfLib(webInfLibs); + + //if we have not already set web.xml location, need to set one up + if (webApp.getDescriptor() == null) + { + //Has an explicit web.xml file been configured to use? + if (webXml != null) + { + Resource r = Resource.newResource(webXml); + if (r.exists() && !r.isDirectory()) + { + webApp.setDescriptor(r.toString()); + } + } + + //Still don't have a web.xml file: try the resourceBase of the webapp, if it is set + if (webApp.getDescriptor() == null && webApp.getBaseResource() != null) + { + Resource r = webApp.getBaseResource().addPath("WEB-INF/web.xml"); + if (r.exists() && !r.isDirectory()) + { + webApp.setDescriptor(r.toString()); + } + } + + //Still don't have a web.xml file: finally try the configured static resource directory if there is one + if (webApp.getDescriptor() == null && (webAppSourceDirectory != null)) + { + File f = new File(new File(webAppSourceDirectory, "WEB-INF"), "web.xml"); + if (f.exists() && f.isFile()) + { + webApp.setDescriptor(f.getCanonicalPath()); + } + } + } + + //process any overlays and the war type artifacts, and + //sets up the base resource collection for the webapp + mavenProjectHelper.getOverlayManager().applyOverlays(webApp); + + getLog().info("web.xml file = " + webApp.getDescriptor()); + getLog().info("Webapp directory = " + webAppSourceDirectory.getCanonicalPath()); + getLog().info("Web defaults = " + (webApp.getDefaultsDescriptor() == null ? " jetty default" : webApp.getDefaultsDescriptor())); + getLog().info("Web overrides = " + (webApp.getOverrideDescriptor() == null ? " none" : webApp.getOverrideDescriptor())); + } + + /** + * Find which dependencies are suitable for addition to the virtual + * WEB-INF lib. + */ + protected Collection getWebInfLibArtifacts() + { + //if this project isn't a war, then don't calculate web-inf lib + String type = project.getArtifact().getType(); + if (!"war".equalsIgnoreCase(type) && !"zip".equalsIgnoreCase(type)) + return Collections.emptyList(); + + return project.getArtifacts().stream() + .filter(this::isArtifactOKForWebInfLib) + .collect(Collectors.toList()); + } + + /** + * Check if the artifact is suitable to be considered part of the + * virtual web-inf/lib. + * + * @param artifact the artifact to check + * @return true if the artifact represents a jar, isn't scope provided and + * is scope test, if useTestScope is enabled. False otherwise. + */ + private boolean isArtifactOKForWebInfLib(Artifact artifact) + { + //The dependency cannot be of type war + if ("war".equalsIgnoreCase(artifact.getType())) + return false; + + //The dependency cannot be scope provided (those should be added to the plugin classpath) + if (Artifact.SCOPE_PROVIDED.equals(artifact.getScope())) + return false; + + //Test dependencies not added by default + if (Artifact.SCOPE_TEST.equals(artifact.getScope()) && !useTestScope) + return false; + + return true; + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java new file mode 100644 index 00000000000..c4b1dd0b7df --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java @@ -0,0 +1,861 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.codehaus.plexus.util.StringUtils; +import org.eclipse.jetty.maven.plugin.utils.MavenProjectHelper; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.server.RequestLog; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.IncludeExcludeSet; +import org.eclipse.jetty.util.Scanner; +import org.eclipse.jetty.util.resource.Resource; + +/** + * AbstractWebAppMojo + * + * Base class for common behaviour of jetty mojos. + */ +public abstract class AbstractWebAppMojo extends AbstractMojo +{ + public static final String JETTY_HOME_GROUPID = "org.eclipse.jetty"; + public static final String JETTY_HOME_ARTIFACTID = "jetty-home"; + public static final String FAKE_WEBAPP = "webapp-synth"; + + public enum DeploymentMode + { + EMBED, + FORK, + DISTRO + } + + /** + * Max number of times to check to see if jetty has started correctly + * when running in FORK or DISTRO mode. + */ + @Parameter (defaultValue = "10") + protected int maxChildStartChecks; + + /** + * How long to wait in msec between checks to see if jetty has started + * correctly when running in FORK or DISTRO mode. + */ + @Parameter (defaultValue = "200") + protected long maxChildStartCheckMs; + /** + * Whether or not to include dependencies on the plugin's classpath with <scope>provided</scope> + * Use WITH CAUTION as you may wind up with duplicate jars/classes. + * + * @since jetty-7.5.2 + */ + @Parameter (defaultValue = "false") + protected boolean useProvidedScope; + + + /** + * List of goals that are NOT to be used + * + * @since jetty-7.5.2 + */ + @Parameter + protected String[] excludedGoals; + + /** + * An instance of org.eclipse.jetty.webapp.WebAppContext that represents the webapp. + * Use any of its setters to configure the webapp. This is the preferred and most + * flexible method of configuration, rather than using the (deprecated) individual + * parameters like "tmpDirectory", "contextPath" etc. + * + */ + @Parameter + protected MavenWebAppContext webApp; + + /** + * Skip this mojo execution. + */ + @Parameter (property = "jetty.skip", defaultValue = "false") + protected boolean skip; + + + /** + * Location of a context xml configuration file whose contents + * will be applied to the webapp AFTER anything in <webApp>.Optional. + */ + @Parameter + protected String contextXml; + + + /** + * The maven project. + */ + @Parameter(defaultValue = "${project}", readonly = true) + protected MavenProject project; + + + /** + * The artifacts for the project. + */ + @Parameter (defaultValue = "${project.artifacts}", readonly = true) + protected Set projectArtifacts; + + /** + * The maven build executing. + */ + @Parameter (defaultValue = "${mojoExecution}", readonly = true) + protected org.apache.maven.plugin.MojoExecution execution; + + + /** + * The artifacts for the plugin itself. + */ + @Parameter (defaultValue = "${plugin.artifacts}", readonly = true) + protected List pluginArtifacts; + + + /** + * If true, the <testOutputDirectory> + * and the dependencies of <scope>test<scope> + * will be put first on the runtime classpath. + */ + @Parameter (defaultValue = "false") + protected boolean useTestScope; + + /** + * List of directories with ant-style <include> and <exclude> patterns + * for extra targets to periodically scan for changes.Optional. + */ + @Parameter + protected List scanTargetPatterns; + + @Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true) + protected List reactorProjects; + + /** + * The target directory + */ + @Parameter (defaultValue = "${project.build.directory}", required = true, readonly = true) + protected File target; + + + /** + * List of jetty xml configuration files whose contents + * will be applied (in order declared) before any plugin configuration. Optional. + */ + @Parameter + protected List jettyXmls; + + + /** + * Optional jetty properties to put on the command line + */ + @Parameter + protected Map jettyProperties; + + + /** + * File containing system properties to be set before execution + * + * Note that these properties will NOT override System properties + * that have been set on the command line, by the JVM, or directly + * in the POM via systemProperties. Optional. + * + * + */ + @Parameter (property = "jetty.systemPropertiesFile") + protected File systemPropertiesFile; + + + /** + * System properties to set before execution. + * Note that these properties will NOT override System properties + * that have been set on the command line or by the JVM. They WILL + * override System properties that have been set via systemPropertiesFile. + * Optional. + */ + @Parameter + protected Map systemProperties; + + /** + * Controls how to run jetty. Valid values are EMBED,FORK,DISTRO. + */ + @Parameter (property = "jetty.deployMode", defaultValue = "EMBED") + protected DeploymentMode deployMode; + + + /** + * List of other contexts to set up. Consider using instead + * the <jettyXml> element to specify external jetty xml config file. + * Optional. + */ + @Parameter + protected List contextHandlers; + + /** + * List of security realms to set up. Consider using instead + * the <jettyXml> element to specify external jetty xml config file. + * Optional. + */ + @Parameter + protected List loginServices; + + /** + * A RequestLog implementation to use for the webapp at runtime. + * Consider using instead the <jettyXml> element to specify external jetty xml config file. + * Optional. + */ + @Parameter + protected RequestLog requestLog; + + /** + * A ServerConnector to use. + */ + @Parameter + protected MavenServerConnector httpConnector; + + + /** + * A wrapper for the Server object + */ + @Parameter + protected Server server; + //End of EMBED only + + + //Start of parameters only valid for FORK/DISTRO + /** + * Extra environment variables to be passed to the forked process + */ + @Parameter + protected Map env = new HashMap(); + + /** + * Arbitrary jvm args to pass to the forked process + */ + @Parameter (property = "jetty.jvmArgs") + protected String jvmArgs; + + /** + * Port to listen to stop jetty on executing -DSTOP.PORT=<stopPort> + * -DSTOP.KEY=<stopKey> -jar start.jar --stop + * + */ + @Parameter + protected int stopPort; + + + /** + * Key to provide when stopping jetty on executing java -DSTOP.KEY=<stopKey> + * -DSTOP.PORT=<stopPort> -jar start.jar --stop + * + */ + @Parameter + protected String stopKey; + //End of FORK or DISTRO parameters + + + //Start of parameters only valid for DISTRO + /** + * Location of jetty home directory + */ + @Parameter + protected File jettyHome; + + /** + * Location of jetty base directory + */ + @Parameter + protected File jettyBase; + + /** + * Optional list of other modules to + * activate. + */ + @Parameter + protected String[] modules; + //End of DISTRO only parameters + + + //Start of parameters only valid for FORK + /** + * The file into which to generate the quickstart web xml for the forked process to use + * + */ + @Parameter (defaultValue = "${project.build.directory}/fork-web.xml") + protected File forkWebXml; + //End of FORK only parameters + + /** + * Helper for interacting with the maven project space + */ + protected MavenProjectHelper mavenProjectHelper; + + /** + * This plugin + */ + @Parameter (defaultValue = "${plugin}", readonly = true, required = true) + protected PluginDescriptor plugin; + + /** + * The project's remote repositories to use for the resolution. + */ + @Parameter (defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true) + private List remoteRepositories; + + /** + * + */ + @Component + private ArtifactResolver artifactResolver; + + /** + * The current maven session + */ + @Parameter (defaultValue = "${session}", required = true, readonly = true) + private MavenSession session; + + /** + * Default supported project type is war packaging. + */ + @Parameter + protected List supportedPackagings = Collections.singletonList("war"); + + /** + * List of deps that are wars + */ + protected List warArtifacts; + + /** + * Webapp base before applying overlays etc + */ + protected Resource originalBaseResource; + + /** + * List of jars with scope=provided + */ + protected List providedJars; + + /** + * System properties from both systemPropertyFile and systemProperties. + */ + protected Map mergedSystemProperties; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + if (isPackagingSupported()) + { + if (skip) + { + getLog().info("Skipping Jetty start: jetty.skip==true"); + return; + } + + if (isExcludedGoal(execution.getMojoDescriptor().getGoal())) + { + getLog().info("The goal \"" + execution.getMojoDescriptor().getFullGoalName() + + "\" is unavailable for this web app because of an configuration."); + return; + } + + getLog().info("Configuring Jetty for project: " + getProjectName()); + mavenProjectHelper = new MavenProjectHelper(project, artifactResolver, remoteRepositories, session); + mergedSystemProperties = mergeSystemProperties(); + configureSystemProperties(); + augmentPluginClasspath(); + PluginLog.setLog(getLog()); + verifyPomConfiguration(); + startJetty(); + } + else + getLog().info("Packaging type [" + project.getPackaging() + "] is unsupported"); + } + + protected void startJetty() + throws MojoExecutionException, MojoFailureException + { + try + { + configureWebApp(); + } + catch (Exception e) + { + throw new MojoExecutionException("Webapp config failure", e); + } + + switch (deployMode) + { + case EMBED: + { + startJettyEmbedded(); + break; + } + case FORK: + { + startJettyForked(); + break; + } + case DISTRO: + { + startJettyDistro(); + break; + } + default: + throw new MojoExecutionException("Unrecognized runType=" + deployMode); + } + + } + + protected abstract void startJettyEmbedded() throws MojoExecutionException; + + protected abstract void startJettyForked() throws MojoExecutionException; + + protected abstract void startJettyDistro() throws MojoExecutionException; + + protected JettyEmbedder newJettyEmbedder() + throws Exception + { + JettyEmbedder jetty = new JettyEmbedder(); + jetty.setStopKey(stopKey); + jetty.setStopPort(stopPort); + jetty.setServer(server); + jetty.setContextHandlers(contextHandlers); + jetty.setRequestLog(requestLog); + jetty.setJettyXmlFiles(jettyXmls); + jetty.setHttpConnector(httpConnector); + jetty.setJettyProperties(jettyProperties); + jetty.setLoginServices(loginServices); + jetty.setContextXml(contextXml); + jetty.setWebApp(webApp); + return jetty; + } + + protected JettyForker newJettyForker() + throws Exception + { + JettyForker jetty = new JettyForker(); + jetty.setServer(server); + jetty.setWorkDir(project.getBasedir()); + jetty.setStopKey(stopKey); + jetty.setStopPort(stopPort); + jetty.setEnv(env); + jetty.setJvmArgs(jvmArgs); + jetty.setSystemProperties(mergedSystemProperties); + jetty.setContainerClassPath(getContainerClassPath()); + jetty.setJettyXmlFiles(jettyXmls); + jetty.setJettyProperties(jettyProperties); + jetty.setForkWebXml(forkWebXml); + jetty.setContextXml(contextXml); + jetty.setWebAppPropsFile(new File(target, "webApp.props")); + Random random = new Random(); + String token = Long.toString(random.nextLong() ^ System.currentTimeMillis(), 36).toUpperCase(Locale.ENGLISH); + jetty.setTokenFile(target.toPath().resolve(token + ".txt").toFile()); + jetty.setWebApp(webApp); + return jetty; + } + + protected JettyDistroForker newJettyDistroForker() + throws Exception + { + JettyDistroForker jetty = new JettyDistroForker(); + jetty.setStopKey(stopKey); + jetty.setStopPort(stopPort); + jetty.setEnv(env); + jetty.setJvmArgs(jvmArgs); + jetty.setJettyXmlFiles(jettyXmls); + jetty.setJettyProperties(jettyProperties); + jetty.setModules(modules); + jetty.setSystemProperties(mergedSystemProperties); + Random random = new Random(); + String token = Long.toString(random.nextLong() ^ System.currentTimeMillis(), 36).toUpperCase(Locale.ENGLISH); + jetty.setTokenFile(target.toPath().resolve(token + ".txt").toFile()); + + List libExtJars = new ArrayList<>(); + + List pdeps = plugin.getPlugin().getDependencies(); + if (pdeps != null && !pdeps.isEmpty()) + { + boolean warned = false; + for (Dependency d:pdeps) + { + if (d.getGroupId().equalsIgnoreCase("org.eclipse.jetty")) + { + if (!warned) + { + getLog().warn("Jetty jars detected in : use in parameter instead to select appropriate jetty modules."); + warned = true; + } + } + else + { + libExtJars.add(mavenProjectHelper.resolveArtifact(d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getType())); + } + } + jetty.setLibExtJarFiles(libExtJars); + } + + jetty.setWebApp(webApp); + jetty.setContextXml(contextXml); + + if (jettyHome == null) + jetty.setJettyDistro(mavenProjectHelper.resolveArtifact(JETTY_HOME_GROUPID, JETTY_HOME_ARTIFACTID, plugin.getVersion(), "zip")); + + jetty.setJettyHome(jettyHome); + jetty.setJettyBase(jettyBase); + jetty.setBaseDir(target); + + return jetty; + } + + /** + * Used by subclasses. + * @throws MojoExecutionException + */ + protected void verifyPomConfiguration() throws MojoExecutionException + { + } + + /** + * Unite system properties set via systemPropertiesFile element and the systemProperties element. + * Properties from the pom override properties from the file. + * + * @return united properties map + * @throws MojoExecutionException + */ + protected Map mergeSystemProperties() + throws MojoExecutionException + { + Map properties = new HashMap<>(); + + //Get the properties from any file first + if (systemPropertiesFile != null) + { + Properties tmp = new Properties(); + try (InputStream propFile = new FileInputStream(systemPropertiesFile)) + { + tmp.load(propFile); + for (Object k:tmp.keySet()) + properties.put(k.toString(), tmp.get(k).toString()); + } + catch (Exception e) + { + throw new MojoExecutionException("Problem applying system properties from file " + systemPropertiesFile.getName(),e); + } + } + //Allow systemProperties defined in the pom to override the file + if (systemProperties != null) + { + properties.putAll(systemProperties); + } + return properties; + } + + protected void configureSystemProperties() + throws MojoExecutionException + { + if (mergedSystemProperties != null) + { + for (Map.Entry e : mergedSystemProperties.entrySet()) + { + System.setProperty(e.getKey(), e.getValue()); + if (getLog().isDebugEnabled()) + getLog().debug("Set system property " + e.getKey() + "=" + e.getValue()); + } + } + } + + /** + * Augment jetty's classpath with dependencies marked as scope=provided + * if useProvidedScope==true. + * + * @throws MojoExecutionException + */ + protected void augmentPluginClasspath() throws MojoExecutionException + { + //Filter out ones that will clash with jars that are plugin dependencies, then + //create a new classloader that we setup in the parent chain. + providedJars = getProvidedJars(); + + if (!providedJars.isEmpty()) + { + try + { + URL[] urls = new URL[providedJars.size()]; + int i = 0; + for (File providedJar:providedJars) + urls[i++] = providedJar.toURI().toURL(); + URLClassLoader loader = new URLClassLoader(urls, getClass().getClassLoader()); + Thread.currentThread().setContextClassLoader(loader); + getLog().info("Plugin classpath augmented with provided dependencies: " + Arrays.toString(urls)); + } + catch (MalformedURLException e) + { + throw new MojoExecutionException("Invalid url", e); + } + } + } + + /** + * Get any dependencies that are scope "provided" if useProvidedScope == true. Ensure + * that only those dependencies that are not already present via the plugin are + * included. + * + * @return provided scope dependencies that are not also plugin dependencies. + * @throws MojoExecutionException + */ + protected List getProvidedJars() throws MojoExecutionException + { + if (useProvidedScope) + { + return project.getArtifacts() + .stream() + .filter(a -> Artifact.SCOPE_PROVIDED.equals(a.getScope()) && !isPluginArtifact(a)) + .map(a -> a.getFile()).collect(Collectors.toList()); + } + else + return Collections.emptyList(); + } + + /** + * Synthesize a classpath appropriate for a forked jetty based off + * the artifacts associated with the jetty plugin, plus any dependencies + * that are marked as provided and useProvidedScope is true. + * + * @return jetty classpath + * @throws Exception + */ + protected String getContainerClassPath() throws Exception + { + //Add in all the plugin artifacts + StringBuilder classPath = new StringBuilder(); + for (Object obj : pluginArtifacts) + { + Artifact artifact = (Artifact)obj; + if ("jar".equals(artifact.getType())) + { + if (classPath.length() > 0) + classPath.append(File.pathSeparator); + classPath.append(artifact.getFile().getAbsolutePath()); + } + else + { + if (artifact.getArtifactId().equals(plugin.getArtifactId())) //get the jetty-maven-plugin jar + classPath.append(artifact.getFile().getAbsolutePath()); + } + } + + //Any jars that we need from the project's dependencies because we're useProvided + if (providedJars != null && !providedJars.isEmpty()) + { + for (File jar:providedJars) + { + classPath.append(File.pathSeparator); + classPath.append(jar.getAbsolutePath()); + if (getLog().isDebugEnabled()) getLog().debug("Adding provided jar: " + jar); + } + } + + return classPath.toString(); + } + + /** + * Check to see if the given artifact is one of the dependency artifacts for this plugin. + * + * @param artifact to check + * @return true if it is a plugin dependency, false otherwise + */ + protected boolean isPluginArtifact(Artifact artifact) + { + if (pluginArtifacts == null) + return false; + + return pluginArtifacts.stream().anyMatch(pa -> pa.getGroupId().equals(artifact.getGroupId()) && pa.getArtifactId().equals(artifact.getArtifactId())); + } + + /** + * Check if the goal that we're executing as is excluded or not. + * + * @param goal the goal to check + * @return true if the goal is excluded, false otherwise + */ + protected boolean isExcludedGoal(String goal) + { + if (excludedGoals == null || goal == null) + return false; + + goal = goal.trim(); + if ("".equals(goal)) + return false; + + boolean excluded = false; + for (int i = 0; i < excludedGoals.length && !excluded; i++) + { + if (excludedGoals[i].equalsIgnoreCase(goal)) + excluded = true; + } + + return excluded; + } + + protected boolean isPackagingSupported() + { + if (!supportedPackagings.contains(project.getPackaging())) + return false; + return true; + } + + protected String getProjectName() + { + String projectName = project.getName(); + if (StringUtils.isBlank(projectName)) + { + projectName = project.getGroupId() + ":" + project.getArtifactId(); + } + return projectName; + } + + /** + * Ensure there is a webapp, and that some basic defaults are applied + * if the user has not supplied them. + * + * @throws Exception + */ + protected void configureWebApp() + throws Exception + { + if (webApp == null) + webApp = new MavenWebAppContext(); + + //If no contextPath was specified, go with default of project artifactid + String cp = webApp.getContextPath(); + if (cp == null || "".equals(cp)) + { + cp = "/" + project.getArtifactId(); + webApp.setContextPath(cp); + } + + //If no tmp directory was specified, and we have one, use it + if (webApp.getTempDirectory() == null) + { + File target = new File(project.getBuild().getDirectory()); + File tmp = new File(target,"tmp"); + if (!tmp.exists()) + tmp.mkdirs(); + webApp.setTempDirectory(tmp); + } + + getLog().info("Context path = " + webApp.getContextPath()); + getLog().info("Tmp directory = " + (webApp.getTempDirectory() == null ? " determined at runtime" : webApp.getTempDirectory())); + } + + /** + * Try and find a jetty-web.xml file, using some + * historical naming conventions if necessary. + * + * @param webInfDir the web inf directory + * @return the jetty web xml file + */ + protected File findJettyWebXmlFile(File webInfDir) + { + if (webInfDir == null) + return null; + if (!webInfDir.exists()) + return null; + + File f = new File(webInfDir, "jetty-web.xml"); + if (f.exists()) + return f; + + //try some historical alternatives + f = new File(webInfDir, "web-jetty.xml"); + if (f.exists()) + return f; + + return null; + } + + /** + * Get a file into which to write output from jetty. + * + * @param name the name of the file + * @return the created file + * @throws Exception + */ + protected File getJettyOutputFile(String name) throws Exception + { + File outputFile = new File(target, name); + if (outputFile.exists()) + outputFile.delete(); + outputFile.createNewFile(); + return outputFile; + } + + /** + * Configure any extra files, directories or patterns thereof for the + * scanner to watch for changes. + * + * @param scanner Scanner that notices changes in files and dirs. + * @throws IOException + */ + protected void configureScanTargetPatterns(Scanner scanner) throws IOException + { + //handle the extra scan patterns + if (scanTargetPatterns != null) + { + for (ScanTargetPattern p : scanTargetPatterns) + { + IncludeExcludeSet includesExcludes = scanner.addDirectory(p.getDirectory().toPath()); + p.configureIncludesExcludeSet(includesExcludes); + } + } + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleReader.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleReader.java new file mode 100644 index 00000000000..8496d99c6f8 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleReader.java @@ -0,0 +1,71 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.Console; +import java.util.EventListener; +import java.util.HashSet; +import java.util.Set; + +/** + * ConsoleReader + * + * Reads lines from the System console and supplies them + * to ConsoleReader.Listeners. + */ +public class ConsoleReader implements Runnable +{ + public interface Listener extends EventListener + { + public void consoleEvent(String line); + } + + public Set listeners = new HashSet<>(); + + public void addListener(ConsoleReader.Listener listener) + { + listeners.add(listener); + } + + public void removeListener(ConsoleReader.Listener listener) + { + listeners.remove(listener); + } + + public void run() + { + Console console = System.console(); + if (console == null) + return; + + String line = ""; + while (true && line != null) + { + line = console.readLine("%nHit to redeploy:%n%n"); + if (line != null) + signalEvent(line); + } + } + + private void signalEvent(String line) + { + for (ConsoleReader.Listener l:listeners) + l.consoleEvent(line); + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleScanner.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleScanner.java deleted file mode 100644 index 2c2c8f06082..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleScanner.java +++ /dev/null @@ -1,126 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.IOException; - -/** - * ConsoleScanner - * - * Read input from stdin - */ -public class ConsoleScanner extends Thread -{ - private final AbstractJettyMojo mojo; - - public ConsoleScanner(AbstractJettyMojo mojo) - { - this.mojo = mojo; - setName("Console scanner"); - setDaemon(true); - } - - @Override - public void run() - { - try - { - while (true) - { - checkSystemInput(); - getSomeSleep(); - } - } - catch (IOException e) - { - mojo.getLog().warn(e); - } - } - - private void getSomeSleep() - { - try - { - Thread.sleep(500); - } - catch (InterruptedException e) - { - mojo.getLog().debug(e); - } - } - - private void checkSystemInput() throws IOException - { - while (System.in.available() > 0) - { - int inputByte = System.in.read(); - if (inputByte >= 0) - { - char c = (char)inputByte; - if (c == '\n') - { - restartWebApp(); - } - } - } - } - - /** - * Skip buffered bytes of system console. - */ - private void clearInputBuffer() - { - try - { - while (System.in.available() > 0) - { - // System.in.skip doesn't work properly. I don't know why - long available = System.in.available(); - for (int i = 0; i < available; i++) - { - if (System.in.read() == -1) - { - break; - } - } - } - } - catch (IOException e) - { - mojo.getLog().warn("Error discarding console input buffer", e); - } - } - - private void restartWebApp() - { - try - { - mojo.restartWebApp(false); - // Clear input buffer to discard anything entered on the console - // while the application was being restarted. - clearInputBuffer(); - } - catch (Exception e) - { - mojo.getLog().error( - "Error reconfiguring/restarting webapp after a new line on the console", - e); - } - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java deleted file mode 100644 index 5f0ad431d3c..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Execute; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; - -/** - *

      - * This goal is used to run Jetty with a pre-assembled war. - *

      - *

      - * It accepts exactly the same options as the run-war goal. - * However, it doesn't assume that the current artifact is a - * webapp and doesn't try to assemble it into a war before its execution. - * So using it makes sense only when used in conjunction with the - * war configuration parameter pointing to a pre-built WAR. - *

      - *

      - * This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested - * HTTP client components. - *

      - * Deploy a pre-assembled war - */ -@Mojo(name = "deploy-war", requiresDependencyResolution = ResolutionScope.RUNTIME) -@Execute(phase = LifecyclePhase.VALIDATE) -public class JettyDeployWar extends JettyRunWarMojo -{ - /** - * If true, the plugin should continue and not block. Otherwise the - * plugin will block further execution and you will need to use - * cntrl-c to stop it. - */ - @Parameter(property = "jetty.daemon", defaultValue = "true") - protected boolean daemon = true; - - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - nonBlocking = daemon; - super.execute(); - } - - @Override - public void finishConfigurationBeforeStart() throws Exception - { - super.finishConfigurationBeforeStart(); - //only stop the server at shutdown if we are blocking - server.setStopAtShutdown(!nonBlocking); - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java new file mode 100644 index 00000000000..641662cc9b4 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java @@ -0,0 +1,409 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; + +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.resource.JarResource; +import org.eclipse.jetty.util.resource.Resource; + +/** + * JettyDistroForker + * + * Unpacks a jetty distribution and configures it with a base that allows it + * to run an unassembled webapp. + */ +public class JettyDistroForker extends AbstractForker +{ + protected MavenWebAppContext webApp; + + protected String contextXml; + + /** + * Location of existing jetty home directory + */ + protected File jettyHome; + + /** + * Zip of jetty distro + */ + protected File jettyDistro; + + /** + * Location of existing jetty base directory + */ + protected File jettyBase; + + protected File baseDir; + + /** + * Optional list of other modules to + * activate. + */ + protected String[] modules; + + protected List libExtJarFiles; + protected Path modulesPath; + protected Path etcPath; + protected Path libPath; + protected Path webappPath; + protected Path mavenLibPath; + + public List getLibExtJarFiles() + { + return libExtJarFiles; + } + + public void setLibExtJarFiles(List libExtJarFiles) + { + this.libExtJarFiles = libExtJarFiles; + } + + public File getJettyHome() + { + return jettyHome; + } + + public void setJettyHome(File jettyHome) + { + this.jettyHome = jettyHome; + } + + public File getJettyBase() + { + return jettyBase; + } + + public void setJettyBase(File jettyBase) + { + this.jettyBase = jettyBase; + } + + public String[] getModules() + { + return modules; + } + + public void setModules(String[] modules) + { + this.modules = modules; + } + + public String getContextXmlFile() + { + return contextXml; + } + + public void setContextXml(String contextXml) + { + this.contextXml = contextXml; + } + + public File getJettyDistro() + { + return jettyDistro; + } + + public void setJettyDistro(File jettyDistro) + { + this.jettyDistro = jettyDistro; + } + + public MavenWebAppContext getWebApp() + { + return webApp; + } + + public void setWebApp(MavenWebAppContext webApp) + { + this.webApp = webApp; + } + + public File getBaseDir() + { + return baseDir; + } + + public void setBaseDir(File baseDir) + { + this.baseDir = baseDir; + } + + @Override + protected ProcessBuilder createCommand() + { + List cmd = new ArrayList<>(); + cmd.add("java"); + cmd.add("-jar"); + cmd.add(new File(jettyHome, "start.jar").getAbsolutePath()); + + cmd.add("-DSTOP.PORT=" + stopPort); + if (stopKey != null) + cmd.add("-DSTOP.KEY=" + stopKey); + + //add any args to the jvm + if (jvmArgs != null) + { + String[] args = jvmArgs.split(" "); + for (String a : args) + { + if (!StringUtil.isBlank(a)) + cmd.add(a.trim()); + } + } + + if (systemProperties != null) + { + for (Map.Entry e : systemProperties.entrySet()) + { + cmd.add("-D" + e.getKey() + "=" + e.getValue()); + } + } + + //set up enabled jetty modules + StringBuilder tmp = new StringBuilder(); + tmp.append("--module="); + tmp.append("server,http,webapp,deploy"); + if (modules != null) + { + for (String m : modules) + { + if (tmp.indexOf(m) < 0) + tmp.append("," + m); + } + } + + if (libExtJarFiles != null && !libExtJarFiles.isEmpty() && tmp.indexOf("ext") < 0) + tmp.append(",ext"); + tmp.append(",maven"); + cmd.add(tmp.toString()); + + //put any jetty properties onto the command line + if (jettyProperties != null) + { + for (Map.Entry e : jettyProperties.entrySet()) + { + cmd.add(e.getKey() + "=" + e.getValue()); + } + } + + //existence of this file signals process started + cmd.add("jetty.token.file=" + tokenFile.getAbsolutePath().toString()); + + ProcessBuilder builder = new ProcessBuilder(cmd); + builder.directory(workDir); + + PluginLog.getLog().info("Distro process starting"); + + //set up extra environment vars if there are any + if (!env.isEmpty()) + builder.environment().putAll(env); + + if (waitForChild) + builder.inheritIO(); + else + { + builder.redirectOutput(jettyOutputFile); + builder.redirectErrorStream(true); + } + return builder; + } + + @Override + public void doStart() throws Exception + { + //set up a jetty-home + configureJettyHome(); + + if (jettyHome == null || !jettyHome.exists()) + throw new IllegalStateException("No jetty home"); + + //set up a jetty-base + configureJettyBase(); + + //convert the webapp to properties + generateWebAppPropertiesFile(); + + super.doStart(); + } + + protected void redeployWebApp() + throws Exception + { + generateWebAppPropertiesFile(); + webappPath.resolve("maven.xml").toFile().setLastModified(System.currentTimeMillis()); + } + + private void generateWebAppPropertiesFile() + throws Exception + { + WebAppPropertyConverter.toProperties(webApp, etcPath.resolve("maven.props").toFile(), contextXml); + } + + /** + * Create or configure a jetty base. + */ + private void configureJettyBase() throws Exception + { + if (jettyBase != null && !jettyBase.exists()) + throw new IllegalStateException(jettyBase.getAbsolutePath() + " does not exist"); + + File targetJettyBase = new File(baseDir, "jetty-base"); + Path targetBasePath = targetJettyBase.toPath(); + if (Files.exists(targetBasePath)) + IO.delete(targetJettyBase); + + targetJettyBase.mkdirs(); + + //jetty-base will be the working directory for the forked command + workDir = targetJettyBase; + + //if there is an existing jetty base, copy parts of it + if (jettyBase != null) + { + Path jettyBasePath = jettyBase.toPath(); + + final File contextXmlFile = (contextXml == null ? null : FileSystems.getDefault().getPath(contextXml).toFile()); + + //copy the existing jetty base + Files.walkFileTree(jettyBasePath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, + new SimpleFileVisitor() + { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException + { + Path targetDir = targetBasePath.resolve(jettyBasePath.relativize(dir)); + try + { + Files.copy(dir, targetDir); + } + catch (FileAlreadyExistsException e) + { + if (!Files.isDirectory(targetDir)) //ignore attempt to recreate dir + throw e; + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException + { + if (contextXmlFile != null && Files.isSameFile(contextXmlFile.toPath(), file)) + return FileVisitResult.CONTINUE; //skip copying the context xml file + Files.copy(file, targetBasePath.resolve(jettyBasePath.relativize(file))); + return FileVisitResult.CONTINUE; + } + }); + } + + //make the jetty base structure + modulesPath = Files.createDirectories(targetBasePath.resolve("modules")); + etcPath = Files.createDirectories(targetBasePath.resolve("etc")); + libPath = Files.createDirectories(targetBasePath.resolve("lib")); + webappPath = Files.createDirectories(targetBasePath.resolve("webapps")); + mavenLibPath = Files.createDirectories(libPath.resolve("maven")); + + //copy in the jetty-maven-plugin jar + URI thisJar = TypeUtil.getLocationOfClass(this.getClass()); + if (thisJar == null) + throw new IllegalStateException("Can't find jar for jetty-maven-plugin"); + + try (InputStream jarStream = thisJar.toURL().openStream(); + FileOutputStream fileStream = new FileOutputStream(mavenLibPath.resolve("plugin.jar").toFile())) + { + IO.copy(jarStream, fileStream); + } + + //copy in the maven.xml webapp file + try (InputStream mavenXmlStream = getClass().getClassLoader().getResourceAsStream("maven.xml"); + FileOutputStream fileStream = new FileOutputStream(webappPath.resolve("maven.xml").toFile())) + { + IO.copy(mavenXmlStream, fileStream); + } + + //copy in the maven.mod file + try (InputStream mavenModStream = getClass().getClassLoader().getResourceAsStream("maven.mod"); + FileOutputStream fileStream = new FileOutputStream(modulesPath.resolve("maven.mod").toFile())) + { + IO.copy(mavenModStream, fileStream); + } + + //copy in the jetty-maven.xml file + try (InputStream jettyMavenStream = getClass().getClassLoader().getResourceAsStream("jetty-maven.xml"); + FileOutputStream fileStream = new FileOutputStream(etcPath.resolve("jetty-maven.xml").toFile())) + { + IO.copy(jettyMavenStream, fileStream); + } + + //if there were plugin dependencies, copy them into lib/ext + if (libExtJarFiles != null && !libExtJarFiles.isEmpty()) + { + Path libExtPath = Files.createDirectories(libPath.resolve("ext")); + for (File f : libExtJarFiles) + { + try (InputStream jarStream = new FileInputStream(f); + FileOutputStream fileStream = new FileOutputStream(libExtPath.resolve(f.getName()).toFile())) + { + IO.copy(jarStream, fileStream); + } + } + } + } + + private void configureJettyHome() + throws Exception + { + if (jettyHome == null && jettyDistro == null) + throw new IllegalStateException("No jettyDistro"); + + if (baseDir == null) + throw new IllegalStateException("No baseDir"); + + if (jettyHome == null) + { + JarResource res = (JarResource)JarResource.newJarResource(Resource.newResource(jettyDistro)); + res.copyTo(baseDir); + //zip will unpack to target/jetty-home- + String name = jettyDistro.getName(); + int i = name.lastIndexOf('.'); + name = (i > 0 ? name.substring(0, i) : "distro"); + jettyHome = new File(baseDir, name); + } + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java index 9749cb16c04..b08cdc133ec 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -21,149 +21,72 @@ package org.eclipse.jetty.maven.plugin; import java.io.File; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Execute; -import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.eclipse.jetty.annotations.AnnotationConfiguration; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.StringUtil; /** - * This goal runs the jetty quickstart feature on an unassembled webapp in order to generate - * a comprehensive web.xml that combines all information from annotations, webdefault.xml and all web-fragment.xml - * files. By default, the web.xml is generated to the console output only. Use the effectiveWebXml parameter - * to provide a file name into which to save the output. + * Generate the effective web.xml for a pre-built webapp. This goal will NOT + * first build the webapp, it must already exist. * - * See http://www.eclipse.org/jetty/documentation for more information on this and other jetty plugins. - * - * Runs jetty on the unassembled webapp to generate the effective web.xml */ -@Mojo(name = "effective-web-xml", requiresDependencyResolution = ResolutionScope.TEST) -@Execute(phase = LifecyclePhase.TEST_COMPILE) -public class JettyEffectiveWebXml extends JettyRunMojo +@Mojo(name = "effective-web-xml", requiresDependencyResolution = ResolutionScope.RUNTIME) +public class JettyEffectiveWebXml extends AbstractUnassembledWebAppMojo { - /** - * The target directory - */ - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - protected File target; - /** * The name of the file to generate into */ - @Parameter + @Parameter (defaultValue = "${project.build.directory}/effective-web.xml") protected File effectiveWebXml; - - protected boolean deleteOnExit = true; - + + @Override + public void configureWebApp() throws Exception + { + //Use a nominated war file for which to generate the effective web.xml, or + //if that is not set, try to use the details of the current project's + //unassembled webapp + super.configureWebApp(); + if (StringUtil.isBlank(webApp.getWar())) + super.configureUnassembledWebApp(); + } + /** - * @see org.apache.maven.plugin.Mojo#execute() + * Override so we can call the parent's method in a different order. */ @Override - public void execute() throws MojoExecutionException, MojoFailureException + protected void configureUnassembledWebApp() throws Exception { - super.execute(); } @Override - public void startJetty() throws MojoExecutionException + protected void startJettyEmbedded() throws MojoExecutionException { - //Only do enough setup to be able to produce a quickstart-web.xml file + generate(); + } - QueuedThreadPool tpool = null; + @Override + protected void startJettyForked() throws MojoExecutionException + { + generate(); + } + @Override + protected void startJettyDistro() throws MojoExecutionException + { + generate(); + } + + private void generate() throws MojoExecutionException + { try { - printSystemProperties(); - - //apply any config from a jetty.xml file first to our "fake" server instance - //TODO probably not necessary - applyJettyXml(); - - ServerSupport.configureHandlers(server, null); - ServerSupport.configureDefaultConfigurationClasses(server); - - //ensure config of the webapp based on settings in plugin - configureWebApplication(); - - //set the webapp up to do very little other than generate the quickstart-web.xml - webApp.setCopyWebDir(false); - webApp.setCopyWebInf(false); - webApp.setGenerateQuickStart(true); - - //if the user didn't nominate a file to generate into, pick the name and - //make sure that it is deleted on exit - if (webApp.getQuickStartWebDescriptor() == null) - { - if (effectiveWebXml == null) - { - deleteOnExit = true; - effectiveWebXml = new File(target, "effective-web.xml"); - effectiveWebXml.deleteOnExit(); - } - - Resource descriptor = Resource.newResource(effectiveWebXml); - - if (!effectiveWebXml.getParentFile().exists()) - effectiveWebXml.getParentFile().mkdirs(); - if (!effectiveWebXml.exists()) - effectiveWebXml.createNewFile(); - - webApp.setQuickStartWebDescriptor(descriptor); - } - - ServerSupport.addWebApplication(server, webApp); - - //if our server has a thread pool associated we can do any annotation scanning multithreaded, - //otherwise scanning will be single threaded - tpool = server.getBean(QueuedThreadPool.class); - if (tpool != null) - tpool.start(); - else - webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString()); - - webApp.start(); //just enough to generate the quickstart + QuickStartGenerator generator = new QuickStartGenerator(effectiveWebXml, webApp); + generator.generate(); } catch (Exception e) { - throw new MojoExecutionException("Effective web.xml generation failed", e); - } - finally - { - try - { - webApp.stop(); - } - catch (Exception ignored) - { - } - - try - { - if (tpool != null) - tpool.stop(); - } - catch (Exception ignored) - { - } - } - - if (deleteOnExit) - { - try - { - //just show the result in the log - getLog().info(IO.toString(webApp.getQuickStartWebDescriptor().getInputStream())); - } - catch (Exception e) - { - throw new MojoExecutionException("Unable to output effective web.xml", e); - } + throw new MojoExecutionException("Error generating effective web xml", e); } } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java new file mode 100644 index 00000000000..2129a935956 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java @@ -0,0 +1,325 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.eclipse.jetty.quickstart.QuickStartConfiguration; +import org.eclipse.jetty.quickstart.QuickStartConfiguration.Mode; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.server.RequestLog; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ShutdownMonitor; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.resource.Resource; + +/** + * JettyEmbedded + * + * Starts jetty within the current process. + */ +public class JettyEmbedder extends AbstractLifeCycle +{ + protected List contextHandlers; + protected List loginServices; + protected RequestLog requestLog; + protected MavenServerConnector httpConnector; + protected Server server; + protected MavenWebAppContext webApp; + protected boolean exitVm; + protected boolean stopAtShutdown; + protected List jettyXmlFiles; + protected Map jettyProperties; + protected ShutdownMonitor shutdownMonitor; + protected int stopPort; + protected String stopKey; + private String contextXml; + private Properties webAppProperties; + + public List getContextHandlers() + { + return contextHandlers; + } + + public void setContextHandlers(List contextHandlers) + { + if (contextHandlers == null) + this.contextHandlers = null; + else + this.contextHandlers = new ArrayList<>(contextHandlers); + } + + public List getLoginServices() + { + return loginServices; + } + + public void setLoginServices(List loginServices) + { + if (loginServices == null) + this.loginServices = null; + else + this.loginServices = new ArrayList<>(loginServices); + } + + public RequestLog getRequestLog() + { + return requestLog; + } + + public void setRequestLog(RequestLog requestLog) + { + this.requestLog = requestLog; + } + + public MavenServerConnector getHttpConnector() + { + return httpConnector; + } + + public void setHttpConnector(MavenServerConnector httpConnector) + { + this.httpConnector = httpConnector; + } + + public Server getServer() + { + return server; + } + + public void setServer(Server server) + { + this.server = server; + } + + public MavenWebAppContext getWebApp() + { + return webApp; + } + + public boolean isExitVm() + { + return exitVm; + } + + public void setExitVm(boolean exitVm) + { + this.exitVm = exitVm; + } + + public boolean isStopAtShutdown() + { + return stopAtShutdown; + } + + public void setStopAtShutdown(boolean stopAtShutdown) + { + this.stopAtShutdown = stopAtShutdown; + } + + public List getJettyXmlFiles() + { + return jettyXmlFiles; + } + + public void setJettyXmlFiles(List jettyXmlFiles) + { + this.jettyXmlFiles = jettyXmlFiles; + } + + public Map getJettyProperties() + { + return jettyProperties; + } + + public void setJettyProperties(Map jettyProperties) + { + this.jettyProperties = jettyProperties; + } + + public ShutdownMonitor getShutdownMonitor() + { + return shutdownMonitor; + } + + public void setShutdownMonitor(ShutdownMonitor shutdownMonitor) + { + this.shutdownMonitor = shutdownMonitor; + } + + public int getStopPort() + { + return stopPort; + } + + public void setStopPort(int stopPort) + { + this.stopPort = stopPort; + } + + public String getStopKey() + { + return stopKey; + } + + public void setStopKey(String stopKey) + { + this.stopKey = stopKey; + } + + public void setWebApp(MavenWebAppContext app) throws Exception + { + webApp = app; + } + + public void setWebAppProperties(Properties props) + { + if (webAppProperties != null) + webAppProperties.clear(); + + if (props != null) + { + if (webAppProperties == null) + webAppProperties = new Properties(); + + webAppProperties.putAll(props); + } + } + + public String getContextXml() + { + return contextXml; + } + + public void setContextXml(String contextXml) + { + this.contextXml = contextXml; + } + + public void doStart() throws Exception + { + super.doStart(); + + Resource.setDefaultUseCaches(false); + + configure(); + configureShutdownMonitor(); + server.start(); + } + + protected void redeployWebApp() throws Exception + { + if (!webApp.isStopped()) + webApp.stop(); + + //regenerate config properties + applyWebAppProperties(); + + webApp.start(); + } + + protected void join() throws InterruptedException + { + server.join(); + } + + /** + * Configure the server and the webapp + * @throws Exception + */ + private void configure() throws Exception + { + /* Configure the server */ + //apply any configs from jetty.xml files first + Server tmp = ServerSupport.applyXmlConfigurations(server, jettyXmlFiles, jettyProperties); + if (server == null) + server = tmp; + + if (server == null) + server = new Server(); + + server.setStopAtShutdown(stopAtShutdown); + + //ensure there's a connector + if (httpConnector != null) + httpConnector.setServer(server); + + ServerSupport.configureConnectors(server, httpConnector, jettyProperties); + + //set up handler structure + ServerSupport.configureHandlers(server, contextHandlers, requestLog); + + //Set up list of default Configurations to apply to a webapp + ServerSupport.configureDefaultConfigurationClasses(server); + + // set up security realms + ServerSupport.configureLoginServices(server, loginServices); + + /* Configure the webapp */ + if (webApp == null) + webApp = new MavenWebAppContext(); + + applyWebAppProperties(); + + //If there is a quickstart file, then quickstart the webapp. + if (webApp.getTempDirectory() != null) + { + File qs = new File(webApp.getTempDirectory(), "quickstart-web.xml"); + if (qs.exists() && qs.isFile()) + { + webApp.setAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML, Resource.newResource(qs)); + webApp.addConfiguration(new MavenQuickStartConfiguration()); + webApp.setAttribute(QuickStartConfiguration.MODE, Mode.QUICKSTART); + } + + } + + //add the webapp to the server + ServerSupport.addWebApplication(server, webApp); + } + + private void applyWebAppProperties() throws Exception + { + //apply properties to the webapp if there are any + if (contextXml != null) + { + if (webAppProperties == null) + webAppProperties = new Properties(); + + webAppProperties.put("context.xml", contextXml); + } + WebAppPropertyConverter.fromProperties(webApp, webAppProperties, server, jettyProperties); + } + + private void configureShutdownMonitor() + { + if (stopPort > 0 && stopKey != null) + { + ShutdownMonitor monitor = ShutdownMonitor.getInstance(); + monitor.setPort(stopPort); + monitor.setKey(stopKey); + monitor.setExitVm(exitVm); + } + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java new file mode 100644 index 00000000000..82885b8d336 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java @@ -0,0 +1,223 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; + +import org.eclipse.jetty.util.PathWatcher; +import org.eclipse.jetty.util.PathWatcher.PathWatchEvent; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JettyForkedChild + * + * This is the class that is executed when the jetty maven plugin + * forks a process when DeploymentMode=FORKED. + */ +public class JettyForkedChild extends AbstractLifeCycle +{ + private static final Logger LOG = LoggerFactory.getLogger(JettyForkedChild.class); + + protected JettyEmbedder jetty; + protected File tokenFile; + protected PathWatcher scanner; + protected File webAppPropsFile; + + /** + * @param args arguments that were passed to main + * @throws Exception + */ + public JettyForkedChild(String[] args) + throws Exception + { + jetty = new JettyEmbedder(); + configure(args); + } + + /** + * Based on the args passed to the program, configure jetty. + * + * @param args args that were passed to the program. + * @throws Exception + */ + public void configure(String[] args) + throws Exception + { + Map jettyProperties = new HashMap<>(); + + for (int i = 0; i < args.length; i++) + { + //--stop-port + if ("--stop-port".equals(args[i])) + { + jetty.setStopPort(Integer.parseInt(args[++i])); + continue; + } + + //--stop-key + if ("--stop-key".equals(args[i])) + { + jetty.setStopKey(args[++i]); + continue; + } + + //--jettyXml + if ("--jetty-xml".equals(args[i])) + { + List jettyXmls = new ArrayList<>(); + String[] names = StringUtil.csvSplit(args[++i]); + for (int j = 0; names != null && j < names.length; j++) + { + jettyXmls.add(new File(names[j].trim())); + } + jetty.setJettyXmlFiles(jettyXmls); + continue; + } + //--webprops + if ("--webprops".equals(args[i])) + { + webAppPropsFile = new File(args[++i].trim()); + jetty.setWebAppProperties(loadWebAppProps()); + continue; + } + + //--token + if ("--token".equals(args[i])) + { + tokenFile = new File(args[++i].trim()); + continue; + } + + if ("--scan".equals(args[i])) + { + scanner = new PathWatcher(); + scanner.setNotifyExistingOnStart(false); + scanner.addListener(new PathWatcher.EventListListener() + { + @Override + public void onPathWatchEvents(List events) + { + if (!Objects.isNull(scanner)) + { + try + { + scanner.stop(); + if (!Objects.isNull(jetty.getWebApp())) + { + //stop the webapp + jetty.getWebApp().stop(); + //reload the props + jetty.setWebAppProperties(loadWebAppProps()); + jetty.setWebApp(jetty.getWebApp()); + //restart the webapp + jetty.redeployWebApp(); + + //restart the scanner + scanner.start(); + } + } + catch (Exception e) + { + LOG.warn("Error restarting webapp", e); + } + } + } + }); + + if (!Objects.isNull(webAppPropsFile)) + scanner.watch(webAppPropsFile.toPath()); + } + + //assume everything else is a jetty property to be passed in + String[] tmp = args[i].trim().split("="); + if (tmp.length == 2) + { + jettyProperties.put(tmp[0], tmp[1]); + } + } + + jetty.setJettyProperties(jettyProperties); + jetty.setExitVm(true); + } + + /** + * Load properties from a file describing the webapp if one is + * present. + * + * @return file contents as properties + * @throws FileNotFoundException + * @throws IOException + */ + private Properties loadWebAppProps() throws FileNotFoundException, IOException + { + Properties props = new Properties(); + if (Objects.nonNull(webAppPropsFile)) + props.load(new FileInputStream(webAppPropsFile)); + return props; + } + + /** + * Start a jetty instance and webapp. This thread will + * wait until jetty exits. + */ + public void doStart() + throws Exception + { + super.doStart(); + + //Start the embedded jetty instance + jetty.start(); + + //touch file to signify start of jetty + Resource r = Resource.newResource(tokenFile); + r.getFile().createNewFile(); + + //Start a watcher on a file that will change if the + //webapp is regenerated; stop the webapp, apply the + //properties and restart it. + if (scanner != null) + scanner.start(); + + //wait for jetty to finish + jetty.join(); + } + + public static void main(String[] args) + throws Exception + { + if (args == null) + System.exit(1); + + JettyForkedChild child = new JettyForkedChild(args); + child.start(); + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java new file mode 100644 index 00000000000..17f3fb67175 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java @@ -0,0 +1,284 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.jetty.server.Server; + +/** + * JettyForker + * + * Uses quickstart to generate a webapp and forks a process to run it. + */ +public class JettyForker extends AbstractForker +{ + protected File forkWebXml; + protected Server server; + protected MavenWebAppContext webApp; + protected String containerClassPath; + protected File webAppPropsFile; + protected String contextXml; + protected boolean scan; + QuickStartGenerator generator; + + /** + * @return the scan + */ + public boolean isScan() + { + return scan; + } + + /** + * @param scan if true, the forked child will scan for changes + */ + public void setScan(boolean scan) + { + this.scan = scan; + } + + public File getWebAppPropsFile() + { + return webAppPropsFile; + } + + public void setWebAppPropsFile(File webAppPropsFile) + { + this.webAppPropsFile = webAppPropsFile; + } + + public File getForkWebXml() + { + return forkWebXml; + } + + public void setForkWebXml(File forkWebXml) + { + this.forkWebXml = forkWebXml; + } + + public String getContextXml() + { + return contextXml; + } + + public void setContextXml(String contextXml) + { + this.contextXml = contextXml; + } + + public String getContainerClassPath() + { + return containerClassPath; + } + + public void setContainerClassPath(String containerClassPath) + { + this.containerClassPath = containerClassPath; + } + + public void setWebApp(MavenWebAppContext app) + { + webApp = app; + } + + public Server getServer() + { + return server; + } + + public void setServer(Server server) + { + this.server = server; + } + + @Override + public void doStart() + throws Exception + { + //Run the webapp to create the quickstart file and properties file + generator = new QuickStartGenerator(forkWebXml, webApp); + generator.setContextXml(contextXml); + generator.setWebAppPropsFile(webAppPropsFile); + generator.setServer(server); + generator.generate(); + + super.doStart(); + } + + protected void redeployWebApp() + throws Exception + { + //regenerating the quickstart will be noticed by the JettyForkedChild process + //which will redeploy the webapp + generator.generate(); + } + + public ProcessBuilder createCommand() + { + List cmd = new ArrayList(); + cmd.add(getJavaBin()); + + if (jvmArgs != null) + { + String[] args = jvmArgs.split(" "); + for (int i = 0;args != null && i < args.length;i++) + { + if (args[i] != null && !"".equals(args[i])) + cmd.add(args[i].trim()); + } + } + + if (systemProperties != null) + { + for (Map.Entry e:systemProperties.entrySet()) + { + cmd.add("-D" + e.getKey() + "=" + e.getValue()); + } + } + + if (containerClassPath != null && containerClassPath.length() > 0) + { + cmd.add("-cp"); + cmd.add(containerClassPath); + } + + cmd.add(JettyForkedChild.class.getCanonicalName()); + + if (stopPort > 0 && stopKey != null) + { + cmd.add("--stop-port"); + cmd.add(Integer.toString(stopPort)); + cmd.add("--stop-key"); + cmd.add(stopKey); + } + if (jettyXmlFiles != null) + { + cmd.add("--jetty-xml"); + StringBuilder tmp = new StringBuilder(); + for (File jettyXml:jettyXmlFiles) + { + if (tmp.length() != 0) + tmp.append(","); + tmp.append(jettyXml.getAbsolutePath()); + } + cmd.add(tmp.toString()); + } + + cmd.add("--webprops"); + cmd.add(webAppPropsFile.getAbsolutePath()); + + cmd.add("--token"); + cmd.add(tokenFile.getAbsolutePath()); + + if (scan) + { + cmd.add("--scan"); + } + + if (jettyProperties != null) + { + for (Map.Entry e:jettyProperties.entrySet()) + { + cmd.add(e.getKey() + "=" + e.getValue()); + } + } + + ProcessBuilder command = new ProcessBuilder(cmd); + command.directory(workDir); + + if (PluginLog.getLog().isDebugEnabled()) + PluginLog.getLog().debug("Forked cli:" + command.command()); + + PluginLog.getLog().info("Forked process starting"); + + //set up extra environment vars if there are any + if (env != null && !env.isEmpty()) + command.environment().putAll(env); + + if (waitForChild) + { + command.inheritIO(); + } + else + { + command.redirectOutput(jettyOutputFile); + command.redirectErrorStream(true); + } + return command; + } + + /** + * @return the location of the java binary + */ + private String getJavaBin() + { + String[] javaexes = new String[]{"java", "java.exe"}; + + File javaHomeDir = new File(System.getProperty("java.home")); + for (String javaexe : javaexes) + { + File javabin = new File(javaHomeDir,fileSeparators("bin/" + javaexe)); + if (javabin.exists() && javabin.isFile()) + { + return javabin.getAbsolutePath(); + } + } + + return "java"; + } + + public static String fileSeparators(String path) + { + StringBuilder ret = new StringBuilder(); + for (char c : path.toCharArray()) + { + if ((c == '/') || (c == '\\')) + { + ret.append(File.separatorChar); + } + else + { + ret.append(c); + } + } + return ret.toString(); + } + + public static String pathSeparators(String path) + { + StringBuilder ret = new StringBuilder(); + for (char c : path.toCharArray()) + { + if ((c == ',') || (c == ':')) + { + ret.append(File.pathSeparatorChar); + } + else + { + ret.append(c); + } + } + return ret.toString(); + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java deleted file mode 100644 index 3c7cb084427..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java +++ /dev/null @@ -1,576 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.FileVisitOption; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.execution.MavenSession; -import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.Execute; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.project.DefaultProjectBuildingRequest; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.artifact.DefaultArtifactCoordinate; -import org.apache.maven.shared.artifact.resolve.ArtifactResolver; -import org.apache.maven.shared.artifact.resolve.ArtifactResolverException; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; - -/** - * This goal is used to deploy the unassembled webapp into a jetty distribution. If the location - * of an existing unpacked distribution is not supplied as the configuration param jettyHome, - * this goal will download and unpack the jetty distro matching the version of this plugin before deploying the webapp. - * - * The webapp will execute in the distro in a forked process. - * - * The stopKey, stopPort configuration elements can be used to control the stopping of the forked process. By default, this plugin will launch - * the forked jetty instance and wait for it to complete (in which case it acts much like the jetty:run goal, and you will need to Cntrl-C to stop). - * By setting the configuration element waitForChild to false, the plugin will terminate after having forked the jetty process. In this case - * you can use the jetty:stop goal to terminate the process. - * - * This goal does NOT support the scanIntervalSeconds parameter: the webapp will be deployed only once. - * - * See http://www.eclipse.org/jetty/documentation for more information on this and other jetty plugins. - * - * Runs unassembled webapp in a locally installed jetty distro - */ -@Mojo(name = "run-distro", requiresDependencyResolution = ResolutionScope.TEST) -@Execute(phase = LifecyclePhase.TEST_COMPILE) -public class JettyRunDistro extends JettyRunMojo -{ - - public static final String JETTY_HOME_GROUPID = "org.eclipse.jetty"; - public static final String JETTY_HOME_ARTIFACTID = "jetty-home"; - - /** - * This plugin - */ - @Parameter(defaultValue = "${plugin}", required = true, readonly = true) - protected PluginDescriptor plugin; - - /** - * The target directory - */ - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - protected File target; - - /** - * Optional jetty.home dir - */ - @Parameter - private File jettyHome; - - /** - * Optional jetty.base dir - */ - @Parameter - private File jettyBase; - - /** - * Optional list of other modules to - * activate. - */ - @Parameter - private String[] modules; - - /** - * Arbitrary jvm args to pass to the forked process - */ - @Parameter(property = "jetty.jvmArgs") - private String jvmArgs; - - /** - * Extra environment variables to be passed to the forked process - */ - @Parameter - private Map env = new HashMap<>(); - - /** - * Optional list of jetty properties to put on the command line - */ - @Parameter - private String[] jettyProperties; - - @Parameter(defaultValue = "${session}", required = true, readonly = true) - private MavenSession session; - - /** - * The project's remote repositories to use for the resolution. - */ - @Parameter(defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true) - private List remoteRepositories; - - @Component - private ArtifactResolver artifactResolver; - - @Parameter(defaultValue = "${plugin.version}", readonly = true) - private String pluginVersion; - - /** - * Whether to wait for the child to finish or not. - */ - @Parameter(defaultValue = "true") - private boolean waitForChild; - - /** - * Max number of times to try checking if the - * child has started successfully. - */ - @Parameter(defaultValue = "10") - private int maxChildChecks; - - /** - * Millisecs to wait between each - * check to see if the child started successfully. - */ - @Parameter(defaultValue = "100") - private long maxChildCheckInterval; - - private File targetBase; - - private List libExtJars; - - private Random random; - - private Path tokenFile; - - @Parameter(property = "jetty.javaPath") - private String javaPath; - - /** - * @see org.eclipse.jetty.maven.plugin.JettyRunMojo#execute() - */ - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - random = new Random(); - List pdeps = plugin.getPlugin().getDependencies(); - if (pdeps != null && !pdeps.isEmpty()) - { - boolean warned = false; - for (Dependency d : pdeps) - { - if (d.getGroupId().equalsIgnoreCase("org.eclipse.jetty")) - { - if (!warned) - { - getLog().warn("Jetty jars detected in : use in parameter instead to select appropriate jetty modules."); - warned = true; - } - } - else - { - if (libExtJars == null) - libExtJars = new ArrayList<>(); - libExtJars.add(d); - } - } - } - - super.execute(); - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#startJetty() - */ - @Override - public void startJetty() throws MojoExecutionException - { - //don't start jetty locally, set up enough configuration to run a new process - //with a jetty distro - try - { - printSystemProperties(); - - //download and install jetty-home if necessary - configureJettyHome(); - - //ensure config of the webapp based on settings in plugin - configureWebApplication(); - - //configure jetty base - configureJettyBase(); - - //create the command to run the new process - ProcessBuilder command = configureCommand(); - - if (waitForChild) - { - command.inheritIO(); - } - else - { - command.redirectOutput(new File(target, "jetty.out")); - command.redirectErrorStream(true); - } - - Process process = command.start(); - - if (waitForChild) - //keep executing until the child dies - process.waitFor(); - else - { - //just wait until the child has started successfully - int attempts = maxChildChecks; - while (!Files.exists(tokenFile) && attempts > 0) - { - Thread.currentThread().sleep(maxChildCheckInterval); - --attempts; - } - if (attempts <= 0) - getLog().info("Couldn't verify success of child startup"); - } - } - catch (Exception e) - { - throw new MojoExecutionException("Failed to start Jetty", e); - } - } - - /** - * If jetty home does not exist, download it and - * unpack to build dir. - * - * @throws Exception if jetty distribution cannot be found neither downloaded - */ - public void configureJettyHome() throws Exception - { - if (jettyHome == null) - { - //no jetty home, download from repo and unpack it. Get the same version as the plugin - Artifact jettyHomeArtifact = resolveArtifact(JETTY_HOME_GROUPID, JETTY_HOME_ARTIFACTID, pluginVersion, "zip"); - JarResource res = (JarResource)JarResource.newJarResource(Resource.newResource(jettyHomeArtifact.getFile())); - res.copyTo(target); - //zip will unpack to target/jetty-home- - jettyHome = new File(target, JETTY_HOME_ARTIFACTID + "-" + pluginVersion); - } - else - { - if (!jettyHome.exists()) - throw new IllegalStateException(jettyHome.getAbsolutePath() + " does not exist"); - } - - getLog().info("jetty.home = " + jettyHome.getAbsolutePath()); - } - - /** - * Resolve an Artifact from remote repo if necessary. - * - * @param groupId the groupid of the artifact - * @param artifactId the artifactId of the artifact - * @param version the version of the artifact - * @param extension the extension type of the artifact eg "zip", "jar" - * @return the artifact from the local or remote repo - * @throws ArtifactResolverException in case of an error while resolving the artifact - */ - public Artifact resolveArtifact(String groupId, String artifactId, String version, String extension) - throws ArtifactResolverException - { - DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); - coordinate.setGroupId(groupId); - coordinate.setArtifactId(artifactId); - coordinate.setVersion(version); - coordinate.setExtension(extension); - - ProjectBuildingRequest buildingRequest = - new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); - - buildingRequest.setRemoteRepositories(remoteRepositories); - - return artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); - } - - /** - * Create or configure a jetty base. - * - * @throws Exception if any error occurred while copying files - */ - public void configureJettyBase() throws Exception - { - if (jettyBase != null && !jettyBase.exists()) - throw new IllegalStateException(jettyBase.getAbsolutePath() + " does not exist"); - - targetBase = new File(target, "jetty-base"); - Path targetBasePath = targetBase.toPath(); - Files.deleteIfExists(targetBase.toPath()); - - targetBase.mkdirs(); - - if (jettyBase != null) - { - Path jettyBasePath = jettyBase.toPath(); - - //copy the existing jetty base - Files.walkFileTree(jettyBasePath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), - Integer.MAX_VALUE, - new SimpleFileVisitor<>() - { - /** - * @see java.nio.file.SimpleFileVisitor#preVisitDirectory(java.lang.Object, java.nio.file.attribute.BasicFileAttributes) - */ - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException - { - Path targetDir = targetBasePath.resolve(jettyBasePath.relativize(dir)); - try - { - Files.copy(dir, targetDir); - } - catch (FileAlreadyExistsException e) - { - if (!Files.isDirectory(targetDir)) //ignore attempt to recreate dir - throw e; - } - return FileVisitResult.CONTINUE; - } - - /** - * @see java.nio.file.SimpleFileVisitor#visitFile(java.lang.Object, java.nio.file.attribute.BasicFileAttributes) - */ - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException - { - if (contextXml != null && Files.isSameFile(Paths.get(contextXml), file)) - return FileVisitResult.CONTINUE; //skip copying the context xml file - Files.copy(file, targetBasePath.resolve(jettyBasePath.relativize(file))); - return FileVisitResult.CONTINUE; - } - }); - } - - //make the jetty base structure - Path modulesPath = Files.createDirectories(targetBasePath.resolve("modules")); - Path etcPath = Files.createDirectories(targetBasePath.resolve("etc")); - Path libPath = Files.createDirectories(targetBasePath.resolve("lib")); - Path webappPath = Files.createDirectories(targetBasePath.resolve("webapps")); - Path mavenLibPath = Files.createDirectories(libPath.resolve("maven")); - - //copy in the jetty-maven-plugin jar - URI thisJar = TypeUtil.getLocationOfClass(this.getClass()); - if (thisJar == null) - throw new IllegalStateException("Can't find jar for jetty-maven-plugin"); - - try (InputStream jarStream = thisJar.toURL().openStream(); - FileOutputStream fileStream = new FileOutputStream(mavenLibPath.resolve("plugin.jar").toFile())) - { - IO.copy(jarStream, fileStream); - } - - //copy in the maven.xml webapp file - try (InputStream mavenXmlStream = getClass().getClassLoader().getResourceAsStream("maven.xml"); - FileOutputStream fileStream = new FileOutputStream(webappPath.resolve("maven.xml").toFile())) - { - IO.copy(mavenXmlStream, fileStream); - } - - //copy in the maven.mod file - try (InputStream mavenModStream = getClass().getClassLoader().getResourceAsStream("maven.mod"); - FileOutputStream fileStream = new FileOutputStream(modulesPath.resolve("maven.mod").toFile())) - { - IO.copy(mavenModStream, fileStream); - } - - //copy in the jetty-maven.xml file - try (InputStream jettyMavenStream = getClass().getClassLoader().getResourceAsStream("jetty-maven.xml"); - FileOutputStream fileStream = new FileOutputStream(etcPath.resolve("jetty-maven.xml").toFile())) - { - IO.copy(jettyMavenStream, fileStream); - } - - //if there were plugin dependencies, copy them into lib/ext - if (libExtJars != null && !libExtJars.isEmpty()) - { - Path libExtPath = Files.createDirectories(libPath.resolve("ext")); - for (Dependency d : libExtJars) - { - Artifact a = resolveArtifact(d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getType()); - try (InputStream jarStream = new FileInputStream(a.getFile()); - FileOutputStream fileStream = new FileOutputStream(libExtPath.resolve(d.getGroupId() + "." + d.getArtifactId() + "-" + d.getVersion() + "." + d.getType()).toFile())) - { - IO.copy(jarStream, fileStream); - } - } - } - - //create properties file that describes the webapp - createPropertiesFile(etcPath.resolve("maven.props").toFile()); - } - - /** - * Convert webapp config to properties - * - * @param file the file to place the properties into - * @throws Exception if any I/O exception during generating the properties file - */ - public void createPropertiesFile(File file) - throws Exception - { - WebAppPropertyConverter.toProperties(webApp, file, contextXml); - } - - /** - * Make the command to spawn a process to - * run jetty from a distro. - * - * @return the command configured - */ - public ProcessBuilder configureCommand() - { - List cmd = new ArrayList<>(); - if (StringUtil.isNotBlank(javaPath)) - { - cmd.add(javaPath); - } - else - { - cmd.add(getJavaBin()); - } - cmd.add("-jar"); - cmd.add(new File(jettyHome, "start.jar").getAbsolutePath()); - - cmd.add("-DSTOP.PORT=" + stopPort); - if (stopKey != null) - cmd.add("-DSTOP.KEY=" + stopKey); - - //add any args to the jvm - if (jvmArgs != null) - { - String[] args = jvmArgs.split(" "); - for (String a : args) - { - if (!StringUtil.isBlank(a)) - cmd.add(a.trim()); - } - } - - //set up enabled jetty modules - StringBuilder tmp = new StringBuilder(); - tmp.append("--module="); - tmp.append("server,http,webapp,deploy"); - if (modules != null) - { - for (String m : modules) - { - if (tmp.indexOf(m) < 0) - tmp.append("," + m); - } - } - - if (libExtJars != null && !libExtJars.isEmpty() && tmp.indexOf("ext") < 0) - tmp.append(",ext"); - tmp.append(",maven"); - cmd.add(tmp.toString()); - - //put any jetty properties onto the command line - if (jettyProperties != null) - { - for (String p : jettyProperties) - { - cmd.add(p); - } - } - - //existence of this file signals process started - tokenFile = target.toPath().resolve(createToken() + ".txt"); - cmd.add("jetty.token.file=" + tokenFile.toAbsolutePath().toString()); - - ProcessBuilder builder = new ProcessBuilder(cmd); - builder.directory(targetBase); - - //set up extra environment vars if there are any - if (!env.isEmpty()) - builder.environment().putAll(env); - - return builder; - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#startScanner() - */ - @Override - public void startScanner() throws Exception - { - //don't scan - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#stopScanner() - */ - @Override - public void stopScanner() throws Exception - { - //don't scan - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean) - */ - @Override - public void restartWebApp(boolean reconfigureScanner) throws Exception - { - //do nothing - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#configureScanner() - */ - @Override - public void configureScanner() throws MojoExecutionException - { - //do nothing - } - - private String createToken() - { - return Long.toString(random.nextLong() ^ System.currentTimeMillis(), 36).toUpperCase(Locale.ENGLISH); - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java deleted file mode 100644 index cd255b6962c..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java +++ /dev/null @@ -1,518 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.apache.maven.plugins.annotations.Execute; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; -import org.eclipse.jetty.annotations.AnnotationConfiguration; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.thread.QueuedThreadPool; - -/** - * This goal is used to deploy your unassembled webapp into a forked JVM. - *

      - * You need to define a jetty.xml file to configure connectors etc. You can use the normal setters of o.e.j.webapp.WebAppContext on the webApp - * configuration element for this plugin. You may also need context xml file for any particularly complex webapp setup. - * - *

      - * Unlike the other jetty goals, this does NOT support the scanIntervalSeconds parameter: the webapp will be deployed only once. - *

      - * The stopKey, stopPort configuration elements can be used to control the stopping of the forked process. By default, this plugin will launch - * the forked jetty instance and wait for it to complete (in which case it acts much like the jetty:run goal, and you will need to Cntrl-C to stop). - * By setting the configuration element waitForChild to false, the plugin will terminate after having forked the jetty process. In this case - * you can use the jetty:stop goal to terminate the process. - *

      - * See http://www.eclipse.org/jetty/documentation for more information on this and other jetty plugins. - * - * Runs Jetty in forked JVM on an unassembled webapp - */ -@Mojo(name = "run-forked", requiresDependencyResolution = ResolutionScope.TEST) -@Execute(phase = LifecyclePhase.TEST_COMPILE) -public class JettyRunForkedMojo extends JettyRunMojo -{ - /** - * The target directory - */ - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - protected File target; - - /** - * The file into which to generate the quickstart web xml for the forked process to use - */ - @Parameter(defaultValue = "${project.build.directory}/fork-web.xml") - protected File forkWebXml; - - /** - * Arbitrary jvm args to pass to the forked process - */ - @Parameter(property = "jetty.jvmArgs") - private String jvmArgs; - - /** - * Optional list of jetty properties to put on the command line - */ - @Parameter - private String[] jettyProperties; - - @Parameter(defaultValue = "${plugin.artifacts}", readonly = true) - private List pluginArtifacts; - - @Parameter(defaultValue = "${plugin}", readonly = true) - private PluginDescriptor plugin; - - @Parameter(defaultValue = "true") - private boolean waitForChild; - - /** - * Max number of times to try checking if the - * child has started successfully. - */ - @Parameter(alias = "maxStartupLines", defaultValue = "50") - private int maxChildChecks; - - /** - * Millisecs to wait between each - * check to see if the child started successfully. - */ - @Parameter(defaultValue = "100") - private long maxChildCheckInterval; - - /** - * Extra environment variables to be passed to the forked process - */ - @Parameter - private Map env = new HashMap<>(); - - /** - * The forked jetty instance - */ - private Process forkedProcess; - - /** - * Random number generator - */ - private Random random; - - /** - * Whether or not the plugin has explicit slf4j dependencies. - * The maven environment will always have slf4j on the classpath, - * which we don't want to put onto the forked process unless the - * pom has an explicit dependency on it. - */ - private boolean hasSlf4jDeps; - - @Parameter(property = "jetty.javaPath") - private String javaPath; - - /** - * ShutdownThread - */ - public class ShutdownThread extends Thread - { - public ShutdownThread() - { - super("RunForkedShutdown"); - } - - @Override - public void run() - { - if (forkedProcess != null && waitForChild) - { - forkedProcess.destroy(); - } - } - } - - /** - * @see org.apache.maven.plugin.Mojo#execute() - */ - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - Runtime.getRuntime().addShutdownHook(new ShutdownThread()); - random = new Random(); - - List deps = plugin.getPlugin().getDependencies(); - for (Dependency d : deps) - { - if (d.getGroupId().contains("slf4j")) - { - hasSlf4jDeps = true; - break; - } - } - - super.execute(); - } - - @Override - public void startJetty() throws MojoExecutionException - { - //Only do enough setup to be able to produce a quickstart-web.xml file to - //pass onto the forked process to run - - try - { - printSystemProperties(); - - //do NOT apply the jettyXml configuration - as the jvmArgs may be needed for it to work - if (server == null) - server = new Server(); - - //ensure handler structure enabled - ServerSupport.configureHandlers(server, null); - - ServerSupport.configureDefaultConfigurationClasses(server); - - //ensure config of the webapp based on settings in plugin - configureWebApplication(); - - //set the webapp up to do very little other than generate the quickstart-web.xml - webApp.setCopyWebDir(false); - webApp.setCopyWebInf(false); - webApp.setGenerateQuickStart(true); - - if (webApp.getQuickStartWebDescriptor() == null) - { - if (forkWebXml == null) - forkWebXml = new File(target, "fork-web.xml"); - - if (!forkWebXml.getParentFile().exists()) - forkWebXml.getParentFile().mkdirs(); - if (!forkWebXml.exists()) - forkWebXml.createNewFile(); - - webApp.setQuickStartWebDescriptor(Resource.newResource(forkWebXml)); - } - - //add webapp to our fake server instance - ServerSupport.addWebApplication(server, webApp); - - //if our server has a thread pool associated we can do annotation scanning multithreaded, - //otherwise scanning will be single threaded - QueuedThreadPool tpool = server.getBean(QueuedThreadPool.class); - if (tpool != null) - tpool.start(); - else - webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString()); - - //leave everything unpacked for the forked process to use - webApp.setPersistTempDirectory(true); - - webApp.start(); //just enough to generate the quickstart - - //save config of the webapp BEFORE we stop - final File props = prepareConfiguration(); - - webApp.stop(); - - if (tpool != null) - tpool.stop(); - - List cmd = new ArrayList<>(); - if (StringUtil.isNotBlank(javaPath)) - { - cmd.add(javaPath); - } - else - { - cmd.add(getJavaBin()); - } - - if (jvmArgs != null) - { - String[] args = jvmArgs.split(" "); - for (int i = 0; args != null && i < args.length; i++) - { - if (args[i] != null && !"".equals(args[i])) - cmd.add(args[i].trim()); - } - } - - String classPath = getContainerClassPath(); - if (classPath != null && classPath.length() > 0) - { - cmd.add("-cp"); - cmd.add(classPath); - } - cmd.add(Starter.class.getCanonicalName()); - - if (stopPort > 0 && stopKey != null) - { - cmd.add("--stop-port"); - cmd.add(Integer.toString(stopPort)); - cmd.add("--stop-key"); - cmd.add(stopKey); - } - if (jettyXml != null) - { - cmd.add("--jetty-xml"); - cmd.add(jettyXml); - } - - cmd.add("--props"); - cmd.add(props.getAbsolutePath()); - - Path tokenFile = target.toPath().resolve(createToken() + ".txt"); - cmd.add("--token"); - cmd.add(tokenFile.toAbsolutePath().toString()); - - if (jettyProperties != null) - { - for (String jettyProp : jettyProperties) - { - cmd.add(jettyProp); - } - } - - ProcessBuilder builder = new ProcessBuilder(cmd); - builder.directory(project.getBasedir()); - - if (PluginLog.getLog().isDebugEnabled()) - PluginLog.getLog().debug("Forked cli:" + Arrays.toString(cmd.toArray())); - - PluginLog.getLog().info("Forked process starting"); - - //set up extra environment vars if there are any - if (!env.isEmpty()) - { - builder.environment().putAll(env); - } - - if (waitForChild) - { - builder.inheritIO(); - } - else - { - builder.redirectOutput(new File(target, "jetty.out")); - builder.redirectErrorStream(true); - } - - forkedProcess = builder.start(); - - if (waitForChild) - { - int exitcode = forkedProcess.waitFor(); - PluginLog.getLog().info("Forked execution exit: " + exitcode); - } - else - { - //just wait until the child has started successfully - int attempts = maxChildChecks; - while (!Files.exists(tokenFile) && attempts > 0) - { - Thread.currentThread().sleep(maxChildCheckInterval); - --attempts; - } - if (attempts <= 0) - getLog().info("Couldn't verify success of child startup"); - } - } - catch (InterruptedException ex) - { - if (forkedProcess != null && waitForChild) - forkedProcess.destroy(); - - throw new MojoExecutionException("Failed to start Jetty within time limit"); - } - catch (Exception ex) - { - if (forkedProcess != null && waitForChild) - forkedProcess.destroy(); - - throw new MojoExecutionException("Failed to create Jetty process", ex); - } - } - - public List getProvidedJars() throws MojoExecutionException - { - //if we are configured to include the provided dependencies on the plugin's classpath - //(which mimics being on jetty's classpath vs being on the webapp's classpath), we first - //try and filter out ones that will clash with jars that are plugin dependencies, then - //create a new classloader that we setup in the parent chain. - if (useProvidedScope) - { - - List provided = new ArrayList<>(); - for (Artifact artifact : project.getArtifacts()) - { - if (Artifact.SCOPE_PROVIDED.equals(artifact.getScope()) && !isPluginArtifact(artifact)) - { - provided.add(artifact.getFile().getAbsolutePath()); - if (getLog().isDebugEnabled()) - { - getLog().debug("Adding provided artifact: " + artifact); - } - } - } - return provided; - } - else - return null; - } - - public File prepareConfiguration() throws MojoExecutionException - { - try - { - //work out the configuration based on what is configured in the pom - File propsFile = new File(target, "fork.props"); - WebAppPropertyConverter.toProperties(webApp, propsFile, contextXml); - return propsFile; - } - catch (Exception e) - { - throw new MojoExecutionException("Prepare webapp configuration", e); - } - } - - @Override - public boolean isPluginArtifact(Artifact artifact) - { - if (pluginArtifacts == null || pluginArtifacts.isEmpty()) - return false; - - for (Artifact pluginArtifact : pluginArtifacts) - { - if (getLog().isDebugEnabled()) - { - getLog().debug("Checking " + pluginArtifact); - } - if (pluginArtifact.getGroupId().equals(artifact.getGroupId()) && pluginArtifact.getArtifactId().equals(artifact.getArtifactId())) - return true; - } - - return false; - } - - private Set getExtraJars() - throws Exception - { - Set extraJars = new HashSet<>(); - - List l = pluginArtifacts; - Artifact pluginArtifact = null; - - if (l != null) - { - - Iterator itor = l.iterator(); - while (itor.hasNext() && pluginArtifact == null) - { - Artifact a = (Artifact)itor.next(); - if (a.getArtifactId().equals(plugin.getArtifactId())) //get the jetty-maven-plugin jar - { - extraJars.add(a); - } - } - } - - return extraJars; - } - - public String getContainerClassPath() throws Exception - { - StringBuilder classPath = new StringBuilder(); - for (Artifact artifact : pluginArtifacts) - { - if ("jar".equals(artifact.getType())) - { - //ignore slf4j from inside maven - if (artifact.getGroupId().contains("slf4j") && !hasSlf4jDeps) - continue; - if (classPath.length() > 0) - { - classPath.append(File.pathSeparator); - } - classPath.append(artifact.getFile().getAbsolutePath()); - } - } - - //Any jars that we need from the plugin environment (like the ones containing Starter class) - Set extraJars = getExtraJars(); - for (Artifact a : extraJars) - { - classPath.append(File.pathSeparator); - classPath.append(a.getFile().getAbsolutePath()); - } - - //Any jars that we need from the project's dependencies because we're useProvided - List providedJars = getProvidedJars(); - if (providedJars != null && !providedJars.isEmpty()) - { - for (String jar : providedJars) - { - classPath.append(File.pathSeparator); - classPath.append(jar); - if (getLog().isDebugEnabled()) - getLog().debug("Adding provided jar: " + jar); - } - } - - return classPath.toString(); - } - - public static String pathSeparators(String path) - { - StringBuilder ret = new StringBuilder(); - for (char c : path.toCharArray()) - { - if ((c == ',') || (c == ':')) - { - ret.append(File.pathSeparatorChar); - } - else - { - ret.append(c); - } - } - return ret.toString(); - } - - private String createToken() - { - return Long.toString(random.nextLong() ^ System.currentTimeMillis(), 36).toUpperCase(Locale.ENGLISH); - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java index 176fb6a7406..5a026388d7c 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java @@ -1,35 +1,28 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import java.io.File; -import java.io.IOException; -import java.net.URL; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.nio.file.PathMatcher; import java.util.Date; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; @@ -39,289 +32,153 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.project.MavenProject; -import org.eclipse.jetty.maven.plugin.utils.MavenProjectHelper; -import org.eclipse.jetty.util.PathWatcher; -import org.eclipse.jetty.util.PathWatcher.PathWatchEvent; -import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.IncludeExcludeSet; +import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceCollection; import org.eclipse.jetty.webapp.WebAppContext; /** - * This goal is used in-situ on a Maven project without first requiring that the project - * is assembled into a war, saving time during the development cycle. - *

      - * The plugin forks a parallel lifecycle to ensure that the "compile" phase has been completed before invoking Jetty. This means - * that you do not need to explicitly execute a "mvn compile" first. It also means that a "mvn clean jetty:run" will ensure that - * a full fresh compile is done before invoking Jetty. - *

      - * Once invoked, the plugin can be configured to run continuously, scanning for changes in the project and automatically performing a - * hot redeploy when necessary. This allows the developer to concentrate on coding changes to the project using their IDE of choice and have those changes - * immediately and transparently reflected in the running web container, eliminating development time that is wasted on rebuilding, reassembling and redeploying. - *

      - * You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. - * This can be used, for example, to deploy a static webapp that is not part of your maven build. - *

      - * There is a reference guide to the configuration parameters for this plugin. - * - * Runs jetty directly from a maven project + * This goal is used in-situ on a Maven project without first requiring that the project + * is assembled into a war, saving time during the development cycle. + *

      + * The plugin runs a parallel lifecycle to ensure that the "test-compile" phase has been completed before invoking Jetty. This means + * that you do not need to explicity execute a "mvn compile" first. It also means that a "mvn clean jetty:run" will ensure that + * a full fresh compile is done before invoking Jetty. + *

      + * Once invoked, the plugin can be configured to run continuously, scanning for changes in the project and automatically performing a + * hot redeploy when necessary. This allows the developer to concentrate on coding changes to the project using their IDE of choice and have those changes + * immediately and transparently reflected in the running web container, eliminating development time that is wasted on rebuilding, reassembling and redeploying. + * Alternatively, you can configure the plugin to wait for an <enter> at the command line to manually control redeployment. + *

      + * You can configure this goal to run your unassembled webapp either in-process with maven, or forked into a new process, or deployed into a + * jetty distribution. */ -@Mojo(name = "run", requiresDependencyResolution = ResolutionScope.TEST) -@Execute(phase = LifecyclePhase.TEST_COMPILE) -public class JettyRunMojo extends AbstractJettyMojo +@Mojo (name = "run", requiresDependencyResolution = ResolutionScope.TEST) +@Execute (phase = LifecyclePhase.TEST_COMPILE) +public class JettyRunMojo extends AbstractUnassembledWebAppMojo { - public static final String DEFAULT_WEBAPP_SRC = "src" + File.separator + "main" + File.separator + "webapp"; - public static final String FAKE_WEBAPP = "webapp-tmp"; - + //Start of parameters only valid for runType=inprocess /** - * If true, the <testOutputDirectory> - * and the dependencies of <scope>test<scope> - * will be put first on the runtime classpath. + * The interval in seconds to pause before checking if changes + * have occurred and re-deploying as necessary. A value + * of 0 indicates no re-deployment will be done. In that case, you + * can force redeployment by typing a linefeed character at the command line. */ - @Parameter(alias = "useTestClasspath", defaultValue = "false") - protected boolean useTestScope; - + @Parameter(defaultValue = "0", property = "jetty.scan", required = true) + protected int scan; + /** - * The default location of the web.xml file. Will be used - * if <webApp><descriptor> is not set. + * Scanner to check for files changes to cause redeploy */ - @Parameter(defaultValue = "${maven.war.webxml}", readonly = true) - protected String webXml; - + protected Scanner scanner; + /** - * The directory containing generated classes. + * Only one of the following will be used, depending the mode + * the mojo is started in: EMBED, FORK, DISTRO */ - @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) - protected File classesDirectory; + protected JettyEmbedder embedder; + protected JettyForker forker; + protected JettyDistroForker distroForker; - /** - * An optional pattern for includes/excludes of classes in the classesDirectory - */ - @Parameter - protected ScanPattern scanClassesPattern; - - /** - * The directory containing generated test classes. - */ - @Parameter(defaultValue = "${project.build.testOutputDirectory}", required = true) - protected File testClassesDirectory; - - /** - * An optional pattern for includes/excludes of classes in the testClassesDirectory - */ - @Parameter - protected ScanPattern scanTestClassesPattern; - - /** - * Root directory for all html/jsp etc files - */ - @Parameter(defaultValue = "${maven.war.src}") - protected File webAppSourceDirectory; - - /** - * List of files or directories to additionally periodically scan for changes. Optional. - */ - @Parameter - protected File[] scanTargets; - - /** - * List of directories with ant-style <include> and <exclude> patterns - * for extra targets to periodically scan for changes. Can be used instead of, - * or in conjunction with <scanTargets>.Optional. - */ - @Parameter - protected ScanTargetPattern[] scanTargetPatterns; - - /** - * maven-war-plugin reference - */ - protected WarPluginInfo warPluginInfo; - - /** - * List of deps that are wars - */ - protected List warArtifacts; - - protected Resource originalBaseResource; - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#execute() - */ @Override public void execute() throws MojoExecutionException, MojoFailureException { - warPluginInfo = new WarPluginInfo(project); super.execute(); } - /** - * Verify the configuration given in the pom. - * - * @see AbstractJettyMojo#checkPomConfiguration() - */ @Override - public boolean checkPomConfiguration() throws MojoExecutionException + public void startJettyEmbedded() throws MojoExecutionException { - // check the location of the static content/jsps etc try { - if ((webAppSourceDirectory == null) || !webAppSourceDirectory.exists()) - { - getLog().info("webAppSourceDirectory" + (webAppSourceDirectory == null ? " not set." : (webAppSourceDirectory.getAbsolutePath() + " does not exist.")) + " Trying " + DEFAULT_WEBAPP_SRC); - webAppSourceDirectory = new File(project.getBasedir(), DEFAULT_WEBAPP_SRC); - if (!webAppSourceDirectory.exists()) - { - getLog().info("webAppSourceDirectory " + webAppSourceDirectory.getAbsolutePath() + " does not exist. Trying " + project.getBuild().getDirectory() + File.separator + FAKE_WEBAPP); - - //try last resort of making a fake empty dir - File target = new File(project.getBuild().getDirectory()); - webAppSourceDirectory = new File(target, FAKE_WEBAPP); - if (!webAppSourceDirectory.exists()) - webAppSourceDirectory.mkdirs(); - } - } - else - getLog().info("Webapp source directory = " + webAppSourceDirectory.getCanonicalPath()); + //start jetty + embedder = newJettyEmbedder(); + embedder.setExitVm(true); + embedder.setStopAtShutdown(true); + embedder.start(); + startScanner(); + embedder.join(); } - catch (IOException e) + catch (Exception e) { - throw new MojoExecutionException("Webapp source directory does not exist", e); + throw new MojoExecutionException("Error starting jetty", e); } + } - // check reload mechanic - if (!"automatic".equalsIgnoreCase(reload) && !"manual".equalsIgnoreCase(reload)) + @Override + public void startJettyForked() throws MojoExecutionException + { + try { - throw new MojoExecutionException("invalid reload mechanic specified, must be 'automatic' or 'manual'"); + forker = newJettyForker(); + forker.setWaitForChild(true); //we run at the command line, echo child output and wait for it + forker.setScan(true); //have the forked child notice changes to the webapp + //TODO is it ok to start the scanner before we start jetty? + startScanner(); + forker.start(); //forks jetty instance + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + @Override + public void startJettyDistro() throws MojoExecutionException + { + try + { + distroForker = newJettyDistroForker(); + distroForker.setWaitForChild(true); //we always run at the command line, echo child output and wait for it + //TODO is it ok to start the scanner before we start jetty? + startScanner(); + distroForker.start(); //forks a jetty distro + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + private void startScanner() + throws Exception + { + // start scanning for changes, or wait for linefeed on stdin + if (scan > 0) + { + scanner = new Scanner(); + scanner.setScanInterval(scan); + scanner.setScanDepth(Scanner.MAX_SCAN_DEPTH); //always fully walk directory hierarchies + scanner.setReportExistingFilesOnStartup(false); + configureScanner(); + getLog().info("Scan interval ms = " + scan); + scanner.start(); } else { - getLog().info("Reload Mechanic: " + reload); - } - getLog().info("nonBlocking:" + nonBlocking); - - // check the classes to form a classpath with - try - { - //allow a webapp with no classes in it (just jsps/html) - if (classesDirectory != null) + ConsoleReader creader = new ConsoleReader(); + creader.addListener(new ConsoleReader.Listener() { - if (!classesDirectory.exists()) - getLog().info("Classes directory " + classesDirectory.getCanonicalPath() + " does not exist"); - else - getLog().info("Classes = " + classesDirectory.getCanonicalPath()); - } - else - getLog().info("Classes directory not set"); + @Override + public void consoleEvent(String line) + { + try + { + restartWebApp(false); + } + catch (Exception e) + { + getLog().debug(e); + } + } + }); + Thread cthread = new Thread(creader, "ConsoleReader"); + cthread.setDaemon(true); + cthread.start(); } - catch (IOException e) - { - throw new MojoExecutionException("Location of classesDirectory does not exist"); - } - - return true; } - @Override - public void finishConfigurationBeforeStart() throws Exception - { - server.setStopAtShutdown(true); //as we will normally be stopped with a cntrl-c, ensure server stopped - super.finishConfigurationBeforeStart(); - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#configureWebApplication() - */ - @Override - public void configureWebApplication() throws Exception - { - super.configureWebApplication(); - - //Set up the location of the webapp. - //There are 2 parts to this: setWar() and setBaseResource(). On standalone jetty, - //the former could be the location of a packed war, while the latter is the location - //after any unpacking. With this mojo, you are running an unpacked, unassembled webapp, - //so the two locations should be equal. - Resource webAppSourceDirectoryResource = Resource.newResource(webAppSourceDirectory.getCanonicalPath()); - if (webApp.getWar() == null) - webApp.setWar(webAppSourceDirectoryResource.toString()); - - //The first time we run, remember the original base dir - if (originalBaseResource == null) - { - if (webApp.getBaseResource() == null) - originalBaseResource = webAppSourceDirectoryResource; - else - originalBaseResource = webApp.getBaseResource(); - } - - //On every subsequent re-run set it back to the original base dir before - //we might have applied any war overlays onto it - webApp.setBaseResource(originalBaseResource); - - if (classesDirectory != null) - webApp.setClasses(classesDirectory); - if (useTestScope && (testClassesDirectory != null)) - webApp.setTestClasses(testClassesDirectory); - - MavenProjectHelper mavenProjectHelper = new MavenProjectHelper(project); - List webInfLibs = getWebInfLibArtifacts(project).stream() - .map(a -> - { - Path p = mavenProjectHelper.getArtifactPath(a); - getLog().debug("Artifact " + a.getId() + " loaded from " + p + " added to WEB-INF/lib"); - return p.toFile(); - }).collect(Collectors.toList()); - getLog().debug("WEB-INF/lib initialized (at root)"); - webApp.setWebInfLib(webInfLibs); - - //if we have not already set web.xml location, need to set one up - if (webApp.getDescriptor() == null) - { - //Has an explicit web.xml file been configured to use? - if (webXml != null) - { - Resource r = Resource.newResource(webXml); - if (r.exists() && !r.isDirectory()) - { - webApp.setDescriptor(r.toString()); - } - } - - //Still don't have a web.xml file: try the resourceBase of the webapp, if it is set - if (webApp.getDescriptor() == null && webApp.getBaseResource() != null) - { - Resource r = webApp.getBaseResource().addPath("WEB-INF/web.xml"); - if (r.exists() && !r.isDirectory()) - { - webApp.setDescriptor(r.toString()); - } - } - - //Still don't have a web.xml file: finally try the configured static resource directory if there is one - if (webApp.getDescriptor() == null && (webAppSourceDirectory != null)) - { - File f = new File(new File(webAppSourceDirectory, "WEB-INF"), "web.xml"); - if (f.exists() && f.isFile()) - { - webApp.setDescriptor(f.getCanonicalPath()); - } - } - } - - //process any overlays and the war type artifacts - List overlays = getOverlays(); - unpackOverlays(overlays); //this sets up the base resource collection - - getLog().info("web.xml file = " + webApp.getDescriptor()); - getLog().info("Webapp directory = " + webAppSourceDirectory.getCanonicalPath()); - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#configureScanner() - */ - @Override - public void configureScanner() + protected void configureScanner() throws MojoExecutionException { try @@ -332,33 +189,18 @@ public class JettyRunMojo extends AbstractJettyMojo { throw new MojoExecutionException("Error forming scan list", e); } - - scanner.addListener(new PathWatcher.EventListListener() + scanner.addListener(new Scanner.BulkListener() { - - @Override - public void onPathWatchEvents(List events) + public void filesChanged(List changes) { try { - boolean reconfigure = false; - if (events != null) - { - for (PathWatchEvent e : events) - { - if (e.getPath().equals(project.getFile().toPath())) - { - reconfigure = true; - break; - } - } - } - + boolean reconfigure = changes.contains(project.getFile().getCanonicalPath()); restartWebApp(reconfigure); } catch (Exception e) { - getLog().error("Error reconfiguring/restarting webapp after change in watched files", e); + getLog().error("Error reconfiguring/restarting webapp after change in watched files",e); } } }); @@ -369,379 +211,194 @@ public class JettyRunMojo extends AbstractJettyMojo if (webApp.getDescriptor() != null) { Resource r = Resource.newResource(webApp.getDescriptor()); - scanner.watch(r.getFile().toPath()); + scanner.addFile(r.getFile().toPath()); } - + if (webApp.getJettyEnvXml() != null) - scanner.watch(new File(webApp.getJettyEnvXml()).toPath()); + scanner.addFile(new File(webApp.getJettyEnvXml()).toPath()); if (webApp.getDefaultsDescriptor() != null) { if (!WebAppContext.WEB_DEFAULTS_XML.equals(webApp.getDefaultsDescriptor())) - scanner.watch(new File(webApp.getDefaultsDescriptor()).toPath()); + scanner.addFile(new File(webApp.getDefaultsDescriptor()).toPath()); } if (webApp.getOverrideDescriptor() != null) { - scanner.watch(new File(webApp.getOverrideDescriptor()).toPath()); + scanner.addFile(new File(webApp.getOverrideDescriptor()).toPath()); } - - File jettyWebXmlFile = findJettyWebXmlFile(new File(webAppSourceDirectory, "WEB-INF")); + + File jettyWebXmlFile = findJettyWebXmlFile(new File(webAppSourceDirectory,"WEB-INF")); if (jettyWebXmlFile != null) { - scanner.watch(jettyWebXmlFile.toPath()); + scanner.addFile(jettyWebXmlFile.toPath()); } - + //make sure each of the war artifacts is added to the scanner - for (Artifact a : getWarArtifacts()) + for (Artifact a:mavenProjectHelper.getWarPluginInfo().getWarArtifacts()) { - scanner.watch(a.getFile().toPath()); + File f = a.getFile(); + if (a.getFile().isDirectory()) + scanner.addDirectory(f.toPath()); + else + scanner.addFile(f.toPath()); } + + //set up any extra files or dirs to watch + configureScanTargetPatterns(scanner); - //handle the explicit extra scan targets - if (scanTargets != null) - { - for (File f : scanTargets) - { - if (f.isDirectory()) - { - PathWatcher.Config config = new PathWatcher.Config(f.toPath()); - config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); - scanner.watch(config); - } - else - scanner.watch(f.toPath()); - } - } - - //handle the extra scan patterns - if (scanTargetPatterns != null) - { - for (ScanTargetPattern p : scanTargetPatterns) - { - PathWatcher.Config config = new PathWatcher.Config(p.getDirectory().toPath()); - config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); - for (String pattern : p.getExcludes()) - { - config.addExcludeGlobRelative(pattern); - } - for (String pattern : p.getIncludes()) - { - config.addIncludeGlobRelative(pattern); - } - scanner.watch(config); - } - } - - scanner.watch(project.getFile().toPath()); + scanner.addFile(project.getFile().toPath()); if (webApp.getTestClasses() != null && webApp.getTestClasses().exists()) { - PathWatcher.Config config = new PathWatcher.Config(webApp.getTestClasses().toPath()); - config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); + Path p = webApp.getTestClasses().toPath(); + IncludeExcludeSet includeExcludeSet = scanner.addDirectory(p); if (scanTestClassesPattern != null) { - for (String p : scanTestClassesPattern.getExcludes()) + for (String s : scanTestClassesPattern.getExcludes()) { - config.addExcludeGlobRelative(p); + if (!s.startsWith("glob:")) + s = "glob:" + s; + includeExcludeSet.exclude(p.getFileSystem().getPathMatcher(s)); } - for (String p : scanTestClassesPattern.getIncludes()) + for (String s : scanTestClassesPattern.getIncludes()) { - config.addIncludeGlobRelative(p); + if (!s.startsWith("glob:")) + s = "glob:" + s; + includeExcludeSet.include(p.getFileSystem().getPathMatcher(s)); } } - scanner.watch(config); } - + if (webApp.getClasses() != null && webApp.getClasses().exists()) { - PathWatcher.Config config = new PathWatcher.Config(webApp.getClasses().toPath()); - config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); + Path p = webApp.getClasses().toPath(); + IncludeExcludeSet includeExcludes = scanner.addDirectory(p); if (scanClassesPattern != null) { - for (String p : scanClassesPattern.getExcludes()) + for (String s : scanClassesPattern.getExcludes()) { - config.addExcludeGlobRelative(p); + if (!s.startsWith("glob:")) + s = "glob:" + s; + includeExcludes.exclude(p.getFileSystem().getPathMatcher(s)); } - for (String p : scanClassesPattern.getIncludes()) + for (String s : scanClassesPattern.getIncludes()) { - config.addIncludeGlobRelative(p); + if (!s.startsWith("glob:")) + s = "glob:" + s; + includeExcludes.include(p.getFileSystem().getPathMatcher(s)); } - } - scanner.watch(config); + } } if (webApp.getWebInfLib() != null) { for (File f : webApp.getWebInfLib()) { - PathWatcher.Config config = new PathWatcher.Config(f.toPath()); - config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); - scanner.watch(config); + if (f.isDirectory()) + scanner.addDirectory(f.toPath()); + else + scanner.addFile(f.toPath()); } } } - + /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean) + * Stop an executing webapp and restart it after optionally + * reconfiguring it. + * + * @param reconfigure if true, the scanner will + * be reconfigured after changes to the pom. If false, only + * the webapp will be reconfigured. + * + * @throws Exception */ - @Override - public void restartWebApp(boolean reconfigureScanner) throws Exception + public void restartWebApp(boolean reconfigure) throws Exception { - getLog().info("restarting " + webApp); + getLog().info("Restarting " + webApp); getLog().debug("Stopping webapp ..."); - stopScanner(); - webApp.stop(); - - getLog().debug("Reconfiguring webapp ..."); - - checkPomConfiguration(); - configureWebApplication(); - - // check if we need to reconfigure the scanner, - // which is if the pom changes - if (reconfigureScanner) + if (scanner != null) + scanner.stop(); + + switch (deployMode) { - getLog().info("Reconfiguring scanner after change to pom.xml ..."); - scanner.reset(); - warArtifacts = null; - configureScanner(); - } - - getLog().debug("Restarting webapp ..."); - webApp.start(); - startScanner(); - getLog().info("Restart completed at " + new Date().toString()); - } - - private Collection getWebInfLibArtifacts(Set artifacts) - { - return artifacts.stream() - .filter(this::canPutArtifactInWebInfLib) - .collect(Collectors.toList()); - } - - private Collection getWebInfLibArtifacts(MavenProject mavenProject) - { - String type = mavenProject.getArtifact().getType(); - if (!"war".equalsIgnoreCase(type) && !"zip".equalsIgnoreCase(type)) - { - return Collections.emptyList(); - } - return getWebInfLibArtifacts(mavenProject.getArtifacts()); - } - - private boolean canPutArtifactInWebInfLib(Artifact artifact) - { - if ("war".equalsIgnoreCase(artifact.getType())) - { - return false; - } - if (Artifact.SCOPE_PROVIDED.equals(artifact.getScope())) - { - return false; - } - if (Artifact.SCOPE_TEST.equals(artifact.getScope()) && !useTestScope) - { - return false; - } - return true; - } - - private List getOverlays() - throws Exception - { - //get copy of a list of war artifacts - Set matchedWarArtifacts = new HashSet<>(); - List overlays = new ArrayList<>(); - for (OverlayConfig config : warPluginInfo.getMavenWarOverlayConfigs()) - { - //overlays can be individually skipped - if (config.isSkip()) - continue; - - //an empty overlay refers to the current project - important for ordering - if (config.isCurrentProject()) + case EMBED: { - Overlay overlay = new Overlay(config, null); - overlays.add(overlay); - continue; - } - - //if a war matches an overlay config - Artifact a = getArtifactForOverlay(config, getWarArtifacts()); - if (a != null) - { - matchedWarArtifacts.add(a); - SelectiveJarResource r = new SelectiveJarResource(new URL("jar:" + Resource.toURL(a.getFile()).toString() + "!/")); - r.setIncludes(config.getIncludes()); - r.setExcludes(config.getExcludes()); - Overlay overlay = new Overlay(config, r); - overlays.add(overlay); - } - } - - //iterate over the left over war artifacts and unpack them (without include/exclude processing) as necessary - for (Artifact a : getWarArtifacts()) - { - if (!matchedWarArtifacts.contains(a)) - { - Overlay overlay = new Overlay(null, Resource.newResource(new URL("jar:" + Resource.toURL(a.getFile()).toString() + "!/"))); - overlays.add(overlay); - } - } - return overlays; - } - - public void unpackOverlays(List overlays) - throws Exception - { - if (overlays == null || overlays.isEmpty()) - return; - - List resourceBaseCollection = new ArrayList<>(); - - for (Overlay o : overlays) - { - //can refer to the current project in list of overlays for ordering purposes - if (o.getConfig() != null && o.getConfig().isCurrentProject() && webApp.getBaseResource().exists()) - { - resourceBaseCollection.add(webApp.getBaseResource()); - continue; - } - - Resource unpacked = unpackOverlay(o); - //_unpackedOverlayResources.add(unpacked); //remember the unpacked overlays for later so we can delete the tmp files - resourceBaseCollection.add(unpacked); //add in the selectively unpacked overlay in the correct order to the webapps resource base - } - - if (!resourceBaseCollection.contains(webApp.getBaseResource()) && webApp.getBaseResource().exists()) - { - if (webApp.getBaseAppFirst()) - { - resourceBaseCollection.add(0, webApp.getBaseResource()); - } - else - { - resourceBaseCollection.add(webApp.getBaseResource()); - } - } - webApp.setBaseResource(new ResourceCollection(resourceBaseCollection.toArray(new Resource[resourceBaseCollection.size()]))); - } - - public Resource unpackOverlay(Overlay overlay) - throws IOException - { - if (overlay.getResource() == null) - return null; //nothing to unpack - - //Get the name of the overlayed war and unpack it to a dir of the - //same name in the temporary directory - String name = overlay.getResource().getName(); - if (name.endsWith("!/")) - name = name.substring(0, name.length() - 2); - int i = name.lastIndexOf('/'); - if (i > 0) - name = name.substring(i + 1, name.length()); - name = StringUtil.replace(name, '.', '_'); - //name = name+(++COUNTER); //add some digits to ensure uniqueness - File overlaysDir = new File(project.getBuild().getDirectory(), "jetty_overlays"); - File dir = new File(overlaysDir, name); - - //if specified targetPath, unpack to that subdir instead - File unpackDir = dir; - if (overlay.getConfig() != null && overlay.getConfig().getTargetPath() != null) - unpackDir = new File(dir, overlay.getConfig().getTargetPath()); - - //only unpack if the overlay is newer - if (!unpackDir.exists() || (overlay.getResource().lastModified() > unpackDir.lastModified())) - { - boolean made = unpackDir.mkdirs(); - overlay.getResource().copyTo(unpackDir); - } - - //use top level of unpacked content - return Resource.newResource(dir.getCanonicalPath()); - } - - /** - * - */ - private List getWarArtifacts() - { - if (warArtifacts != null) - return warArtifacts; - - warArtifacts = new ArrayList<>(); - for (Artifact artifact : projectArtifacts) - { - if (artifact.getType().equals("war") || artifact.getType().equals("zip")) - { - try + getLog().debug("Reconfiguring webapp ..."); + + verifyPomConfiguration(); + // check if we need to reconfigure the scanner, + // which is if the pom changes + if (reconfigure) { - warArtifacts.add(artifact); - getLog().info("Dependent war artifact " + artifact.getId()); + getLog().info("Reconfiguring scanner after change to pom.xml ..."); + warArtifacts = null; //will be regenerated by configureWebApp + if (scanner != null) + { + scanner.reset(); + configureScanner(); + } } - catch (Exception e) + + embedder.getWebApp().stop(); + configureWebApp(); + embedder.redeployWebApp(); + if (scanner != null) + scanner.start(); + getLog().info("Restart completed at " + new Date().toString()); + + break; + } + case FORK: + { + verifyPomConfiguration(); + if (reconfigure) { - throw new RuntimeException(e); + getLog().info("Reconfiguring scanner after change to pom.xml ..."); + warArtifacts = null; ///TODO if the pom changes for the forked case, how would we get the forked process to stop and restart? + if (scanner != null) + { + scanner.reset(); + configureScanner(); + } } + configureWebApp(); + //regenerate with new config and restart the webapp + forker.redeployWebApp(); + //restart scanner + if (scanner != null) + scanner.start(); + break; + } + case DISTRO: + { + verifyPomConfiguration(); + if (reconfigure) + { + getLog().info("Reconfiguring scanner after change to pom.xml ..."); + + warArtifacts = null; //TODO if there are any changes to the pom, then we would have to tell the + //existing forked distro process to stop, then rerun the configuration and then refork - too complicated??! + if (scanner != null) + { + scanner.reset(); + configureScanner(); + } + } + configureWebApp(); + //regenerate the webapp and redeploy it + distroForker.redeployWebApp(); + //restart scanner + if (scanner != null) + scanner.start(); + + break; + } + default: + { + throw new IllegalStateException("Unrecognized run type " + deployMode); } } - return warArtifacts; - } - - protected Artifact getArtifactForOverlay(OverlayConfig o, List warArtifacts) - { - if (o == null || warArtifacts == null || warArtifacts.isEmpty()) - return null; - - for (Artifact a : warArtifacts) - { - if (o.matchesArtifact(a.getGroupId(), a.getArtifactId(), a.getClassifier())) - { - return a; - } - } - - return null; - } - - /** - * - */ - protected String getJavaBin() - { - String[] javaexes = {"java", "java.exe"}; - - File javaHomeDir = new File(System.getProperty("java.home")); - for (String javaexe : javaexes) - { - File javabin = new File(javaHomeDir, fileSeparators("bin/" + javaexe)); - if (javabin.exists() && javabin.isFile()) - { - return javabin.getAbsolutePath(); - } - } - - return "java"; - } - - public static String fileSeparators(String path) - { - StringBuilder ret = new StringBuilder(); - for (char c : path.toCharArray()) - { - if ((c == '/') || (c == '\\')) - { - ret.append(File.separatorChar); - } - else - { - ret.append(c); - } - } - return ret.toString(); } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java deleted file mode 100644 index e41aa04f7ee..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java +++ /dev/null @@ -1,173 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.File; -import java.util.List; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Execute; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; -import org.eclipse.jetty.util.PathWatcher; -import org.eclipse.jetty.util.PathWatcher.PathWatchEvent; - -/** - *

      - * This goal is used to assemble your webapp into an exploded war and automatically deploy it to Jetty. - *

      - *

      - * Once invoked, the plugin runs continuously, and can be configured to scan for changes in the pom.xml and - * to WEB-INF/web.xml, WEB-INF/classes or WEB-INF/lib and hot redeploy when a change is detected. - *

      - *

      - * You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. - * This can be used, for example, to deploy a static webapp that is not part of your maven build. - *

      - */ -@Mojo(name = "run-exploded", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) -@Execute(phase = LifecyclePhase.PACKAGE) -public class JettyRunWarExplodedMojo extends AbstractJettyMojo -{ - - /** - * The location of the war file. - */ - @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}", required = true) - private File war; - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#execute() - */ - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - super.execute(); - } - - @Override - public void finishConfigurationBeforeStart() throws Exception - { - server.setStopAtShutdown(true); //as we will normally be stopped with a cntrl-c, ensure server stopped - super.finishConfigurationBeforeStart(); - } - - /** - * @see AbstractJettyMojo#configureScanner() - */ - @Override - public void configureScanner() throws MojoExecutionException - { - scanner.watch(project.getFile().toPath()); - File webInfDir = new File(war, "WEB-INF"); - File webXml = new File(webInfDir, "web.xml"); - if (webXml.exists()) - scanner.watch(webXml.toPath()); - File jettyWebXmlFile = findJettyWebXmlFile(webInfDir); - if (jettyWebXmlFile != null) - scanner.watch(jettyWebXmlFile.toPath()); - File jettyEnvXmlFile = new File(webInfDir, "jetty-env.xml"); - if (jettyEnvXmlFile.exists()) - scanner.watch(jettyEnvXmlFile.toPath()); - - File classes = new File(webInfDir, "classes"); - if (classes.exists()) - { - PathWatcher.Config classesConfig = new PathWatcher.Config(classes.toPath()); - classesConfig.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); - scanner.watch(classesConfig); - } - - File lib = new File(webInfDir, "lib"); - if (lib.exists()) - { - PathWatcher.Config libConfig = new PathWatcher.Config(lib.toPath()); - libConfig.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH); - scanner.watch(libConfig); - } - - scanner.addListener(new PathWatcher.EventListListener() - { - - @Override - public void onPathWatchEvents(List events) - { - try - { - boolean reconfigure = false; - for (PathWatchEvent e : events) - { - if (e.getPath().equals(project.getFile().toPath())) - { - reconfigure = true; - break; - } - } - restartWebApp(reconfigure); - } - catch (Exception e) - { - getLog().error("Error reconfiguring/restarting webapp after change in watched files", e); - } - } - }); - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean) - */ - @Override - public void restartWebApp(boolean reconfigureScanner) throws Exception - { - getLog().info("Restarting webapp"); - getLog().debug("Stopping webapp ..."); - stopScanner(); - webApp.stop(); - getLog().debug("Reconfiguring webapp ..."); - - checkPomConfiguration(); - - // check if we need to reconfigure the scanner, - // which is if the pom changes - if (reconfigureScanner) - { - getLog().info("Reconfiguring scanner after change to pom.xml ..."); - scanner.reset(); - configureScanner(); - } - - getLog().debug("Restarting webapp ..."); - webApp.start(); - startScanner(); - getLog().info("Restart completed."); - } - - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#configureWebApplication() - */ - @Override - public void configureWebApplication() throws Exception - { - super.configureWebApplication(); - webApp.setWar(war.getCanonicalPath()); - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java index df69738a26a..8bc5f8f8d52 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java @@ -1,147 +1,296 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; -import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Date; import java.util.List; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Execute; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.eclipse.jetty.util.PathWatcher; -import org.eclipse.jetty.util.PathWatcher.PathWatchEvent; +import org.eclipse.jetty.util.Scanner; +import org.eclipse.jetty.util.StringUtil; /** - *

      - * This goal is used to assemble your webapp into a war and automatically deploy it to Jetty. - *

      - *

      - * Once invoked, the plugin runs continuously and can be configured to scan for changes in the project and to the - * war file and automatically perform a hot redeploy when necessary. - *

      - *

      - * You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. - * This can be used, for example, to deploy a static webapp that is not part of your maven build. - *

      - * Runs jetty on a war file - */ +*

      +* This goal is used to assemble your webapp into a war and automatically deploy it to Jetty. +*

      +*

      +* Once invoked, the plugin runs continuously and can be configured to scan for changes in the project and to the +* war file and automatically perform a hot redeploy when necessary. +*

      +*

      +* You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. +*

      +*

      +* You can configure this goal to run your webapp either in-process with maven, or forked into a new process, or deployed into a +* jetty distribution. +*

      +*/ @Mojo(name = "run-war", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) @Execute(phase = LifecyclePhase.PACKAGE) -public class JettyRunWarMojo extends AbstractJettyMojo -{ - +public class JettyRunWarMojo extends AbstractWebAppMojo +{ /** - * The location of the war file. + * The interval in seconds to pause before checking if changes + * have occurred and re-deploying as necessary. A value + * of 0 indicates no re-deployment will be done. In that case, you + * can force redeployment by typing a linefeed character at the command line. */ - @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.war", required = true) - private File war; - + @Parameter(defaultValue = "0", property = "jetty.scan", required = true) + protected int scan; + /** - * @see org.apache.maven.plugin.Mojo#execute() + * Scanner to check for files changes to cause redeploy */ + protected Scanner scanner; + protected JettyEmbedder embedder; + protected JettyForker forker; + protected JettyDistroForker distroForker; + protected Path war; + @Override - public void execute() throws MojoExecutionException, MojoFailureException + public void configureWebApp() throws Exception { - super.execute(); - } - - @Override - public void finishConfigurationBeforeStart() throws Exception - { - server.setStopAtShutdown(true); //as we will normally be stopped with a cntrl-c, ensure server stopped - super.finishConfigurationBeforeStart(); - } - - @Override - public void configureWebApplication() throws Exception - { - super.configureWebApplication(); - - webApp.setWar(war.getCanonicalPath()); + super.configureWebApp(); + //if no war has been explicitly configured, use the one from the webapp project + if (StringUtil.isBlank(webApp.getWar())) + { + war = target.toPath().resolve(project.getBuild().getFinalName() + ".war"); + webApp.setWar(war.toFile().getAbsolutePath()); + } + else + war = Paths.get(webApp.getWar()); + + getLog().info("War = " + war); } /** - * @see AbstractJettyMojo#configureScanner() + * Start a jetty instance in process to run the built war. */ @Override + public void startJettyEmbedded() throws MojoExecutionException + { + try + { + embedder = newJettyEmbedder(); + embedder.setExitVm(true); + embedder.setStopAtShutdown(true); + embedder.start(); + startScanner(); + embedder.join(); + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + + /** + * Fork a jetty instance to run the built war. + */ + @Override + public void startJettyForked() throws MojoExecutionException + { + try + { + forker = newJettyForker(); + forker.setWaitForChild(true); //we run at the command line, echo child output and wait for it + startScanner(); + forker.start(); //forks jetty instance + + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + /** + * Deploy the built war to a jetty distro. + */ + @Override + public void startJettyDistro() throws MojoExecutionException + { + try + { + distroForker = newJettyDistroForker(); + distroForker.setWaitForChild(true); //we always run at the command line, echo child output and wait for it + startScanner(); + distroForker.start(); //forks a jetty distro + + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + public void startScanner() + throws Exception + { + // start scanning for changes, or wait for linefeed on stdin + if (scan > 0) + { + scanner = new Scanner(); + scanner.setScanInterval(scan); + scanner.setScanDepth(Scanner.MAX_SCAN_DEPTH); //always fully walk directory hierarchies + scanner.setReportExistingFilesOnStartup(false); + configureScanner(); + getLog().info("Scan interval ms = " + scan); + scanner.start(); + } + else + { + ConsoleReader creader = new ConsoleReader(); + creader.addListener(new ConsoleReader.Listener() + { + @Override + public void consoleEvent(String line) + { + try + { + restartWebApp(false); + } + catch (Exception e) + { + getLog().debug(e); + } + } + }); + Thread cthread = new Thread(creader, "ConsoleReader"); + cthread.setDaemon(true); + cthread.start(); + } + } + public void configureScanner() throws MojoExecutionException { - scanner.watch(project.getFile().toPath()); - scanner.watch(war.toPath()); - - scanner.addListener(new PathWatcher.EventListListener() + try { + scanner.addFile(project.getFile().toPath()); + scanner.addFile(war); - @Override - public void onPathWatchEvents(List events) + //set up any extra files or dirs to watch + configureScanTargetPatterns(scanner); + scanner.addListener(new Scanner.BulkListener() { - try + public void filesChanged(List changes) { - boolean reconfigure = false; - for (PathWatchEvent e : events) + try { - if (e.getPath().equals(project.getFile().toPath())) - { - reconfigure = true; - break; - } + boolean reconfigure = changes.contains(project.getFile().getCanonicalPath()); + restartWebApp(reconfigure); + } + catch (Exception e) + { + getLog().error("Error reconfiguring/restarting webapp after change in watched files",e); } - restartWebApp(reconfigure); } - catch (Exception e) - { - getLog().error("Error reconfiguring/restarting webapp after change in watched files", e); - } - } - }); + }); + } + catch (IOException e) + { + throw new MojoExecutionException("Error configuring scanner", e); + } } - /** - * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean) - */ - @Override - public void restartWebApp(boolean reconfigureScanner) throws Exception + public void restartWebApp(boolean reconfigure) throws Exception { getLog().info("Restarting webapp ..."); - getLog().debug("Stopping webapp ..."); - stopScanner(); - webApp.stop(); - getLog().debug("Reconfiguring webapp ..."); - - checkPomConfiguration(); - - // check if we need to reconfigure the scanner, - // which is if the pom changes - if (reconfigureScanner) + getLog().debug("Stopping scanner ..."); + if (scanner != null) + scanner.stop(); + + switch (deployMode) { - getLog().info("Reconfiguring scanner after change to pom.xml ..."); - scanner.reset(); - configureScanner(); - } + case EMBED: + { + getLog().debug("Reconfiguring webapp ..."); + + verifyPomConfiguration(); + // check if we need to reconfigure the scanner, + // which is if the pom changes + if (reconfigure) + { + getLog().info("Reconfiguring scanner after change to pom.xml ..."); + scanner.reset(); + warArtifacts = null; + configureScanner(); + } + embedder.getWebApp().stop(); + configureWebApp(); + embedder.redeployWebApp(); + scanner.start(); + getLog().info("Restart completed at " + new Date().toString()); + + break; + } + case FORK: + { + verifyPomConfiguration(); + if (reconfigure) + { + getLog().info("Reconfiguring scanner after change to pom.xml ..."); + scanner.reset(); + warArtifacts = null; + configureScanner(); + } + + configureWebApp(); + //regenerate with new config and restart the webapp + forker.redeployWebApp(); + //restart scanner + scanner.start(); + + break; + } + case DISTRO: + { + verifyPomConfiguration(); + if (reconfigure) + { + getLog().info("Reconfiguring scanner after change to pom.xml ..."); + scanner.reset(); + warArtifacts = null; + configureScanner(); + } + configureWebApp(); + //regenerate the webapp and redeploy it + distroForker.redeployWebApp(); + //restart scanner + scanner.start(); - getLog().debug("Restarting webapp ..."); - webApp.start(); - startScanner(); + break; + } + default: + { + throw new IllegalStateException("Unrecognized run type " + deployMode); + } + } getLog().info("Restart completed."); } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java index 239a6d3389c..e5720529b97 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java @@ -1,59 +1,110 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Execute; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; /** + *

      + * This goal is similar to the jetty:run goal in that it it starts jetty on an unassembled webapp, + * EXCEPT that it is designed to be bound to an execution inside your pom. Thus, this goal does NOT + * run a parallel build cycle, so you must be careful to ensure that you bind it to a phase in + * which all necessary generated files and classes for the webapp have been created. + *

      *

      - * This goal is similar to the jetty:run goal, EXCEPT that it is designed to be bound to an execution inside your pom, rather - * than being run from the command line. + * This goal will NOT scan for changes in either the webapp project or any scanTargets or scanTargetPatterns. *

      *

      - * When using it, be careful to ensure that you bind it to a phase in which all necessary generated files and classes for the webapp - * will have been created. If you run it from the command line, then also ensure that all necessary generated files and classes for - * the webapp already exist. - *

      - * - * Runs jetty directly from a maven project from a binding to an execution in your pom + * You can configure this goal to run your webapp either in-process with maven, or forked into a new process, or deployed into a + * jetty distribution. + *

      */ @Mojo(name = "start", requiresDependencyResolution = ResolutionScope.TEST) @Execute(phase = LifecyclePhase.VALIDATE) -public class JettyStartMojo extends JettyRunMojo +public class JettyStartMojo extends AbstractUnassembledWebAppMojo { + /** + * Starts the webapp - without first compiling the classes - + * in the same process as maven. + */ @Override - public void execute() throws MojoExecutionException, MojoFailureException + public void startJettyEmbedded() throws MojoExecutionException { - nonBlocking = true; //ensure that starting jetty won't hold up the thread - super.execute(); + try + { + JettyEmbedder jetty = newJettyEmbedder(); + jetty.setExitVm(false); + jetty.setStopAtShutdown(false); + jetty.start(); + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } } + /** + * Start the webapp in a forked jetty process. Use the + * jetty:stop goal to terminate. + */ @Override - public void finishConfigurationBeforeStart() throws Exception + public void startJettyForked() throws MojoExecutionException { - super.finishConfigurationBeforeStart(); - server.setStopAtShutdown(false); //as we will normally be stopped with a cntrl-c, ensure server stopped + try + { + JettyForker jetty = newJettyForker(); + jetty.setWaitForChild(false); //we never wait for child to finish + jetty.setMaxChildStartChecks(maxChildStartChecks); + jetty.setMaxChildStartCheckMs(maxChildStartCheckMs); + jetty.setJettyOutputFile(getJettyOutputFile("jetty-start.out")); + jetty.start(); //forks jetty instance + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + /** + * Start the webapp in a forked jetty distribution. Use the + * jetty:stop goal to terminate + */ + @Override + public void startJettyDistro() throws MojoExecutionException + { + try + { + JettyDistroForker jetty = newJettyDistroForker(); + jetty.setWaitForChild(false); //never wait for child to finish + jetty.setMaxChildStartChecks(maxChildStartChecks); + jetty.setMaxChildStartCheckMs(maxChildStartCheckMs); + jetty.setJettyOutputFile(getJettyOutputFile("jetty-start.out")); + jetty.start(); //forks a jetty distro + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartWarMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartWarMojo.java new file mode 100644 index 00000000000..5c6374b1909 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartWarMojo.java @@ -0,0 +1,149 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.nio.file.Path; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.eclipse.jetty.util.StringUtil; + +/** + *

      + * This goal is used to run Jetty with any pre-assembled war. This goal does not have + * to be used with a project of packaging type "war". + *

      + *

      + * You can configure the "webApp" element with the location of either a war file or + * an unpacked war that you wish to deploy - in either case, the webapp must be + * fully compiled and assembled as this goal does not do anything other than start + * jetty with the given webapp. If you do not configure the "webApp" element, then + * the goal will default to using the war of the webapp project. + *

      + *

      + * This goal is designed to be bound to a build phase, and NOT to be run at the + * command line. It will not block waiting for jetty to execute, but rather continue + * execution. + *

      + *

      + * This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested + * HTTP client components via binding to the test-integration build phase. + *

      + *

      + * You can configure this goal to run the webapp either in-process with maven, or + * forked into a new process, or deployed into a jetty distribution. + *

      + */ +@Mojo(name = "start-war", requiresDependencyResolution = ResolutionScope.RUNTIME) +public class JettyStartWarMojo extends AbstractWebAppMojo +{ + @Parameter (defaultValue = "${project.baseDir}/src/main/webapp") + protected File webAppSourceDirectory; + + protected JettyEmbedder embedder; + protected JettyForker forker; + protected JettyDistroForker distroForker; + + @Override + public void configureWebApp() throws Exception + { + super.configureWebApp(); + //if a war has not been explicitly configured, use the one from the project + if (StringUtil.isBlank(webApp.getWar())) + { + Path war = target.toPath().resolve(project.getBuild().getFinalName() + ".war"); + webApp.setWar(war.toFile().getAbsolutePath()); + } + + getLog().info("War = " + webApp.getWar()); + } + + /** + * Start a jetty instance in process to run given war. + */ + @Override + public void startJettyEmbedded() throws MojoExecutionException + { + try + { + embedder = newJettyEmbedder(); + embedder.setExitVm(false); + embedder.setStopAtShutdown(false); + embedder.start(); + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + /** + * Fork a jetty instance to run the given war. + */ + @Override + public void startJettyForked() throws MojoExecutionException + { + try + { + forker = newJettyForker(); + forker.setWaitForChild(false); //we never wait for child to finish + forker.setMaxChildStartChecks(maxChildStartChecks); + forker.setMaxChildStartCheckMs(maxChildStartCheckMs); + forker.setJettyOutputFile(getJettyOutputFile("jetty-start-war.out")); + forker.start(); //forks jetty instance + + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + /** + * Fork a jetty distro to run the given war. + */ + @Override + public void startJettyDistro() throws MojoExecutionException + { + try + { + distroForker = newJettyDistroForker(); + distroForker.setWaitForChild(false); //never wait for child tofinish + distroForker.setMaxChildStartCheckMs(maxChildStartCheckMs); + distroForker.setMaxChildStartChecks(maxChildStartChecks); + distroForker.setJettyOutputFile(getJettyOutputFile("jetty-start-war.out")); + distroForker.start(); //forks a jetty distro + } + catch (Exception e) + { + throw new MojoExecutionException("Error starting jetty", e); + } + } + + @Override + protected void verifyPomConfiguration() throws MojoExecutionException + { + //Do nothing here, as we want the user to configure a war to deploy, + //or we default to the webapp that is running the jetty plugin, but + //we need to delay that decision until configureWebApp(). + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java index c1a6f4c8be0..08d6de9c8fb 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -25,42 +25,47 @@ import java.net.ConnectException; import java.net.InetAddress; import java.net.Socket; -import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; + /** * This goal stops a running instance of jetty. * * The stopPort and stopKey parameters can be used to * configure which jetty to stop. - * - * Stops jetty that is configured with <stopKey> and <stopPort>. */ @Mojo(name = "stop") -public class JettyStopMojo extends AbstractMojo +public class JettyStopMojo extends AbstractWebAppMojo { - - /** - * Port to listen to stop jetty on sending stop command - */ - @Parameter(required = true) - protected int stopPort; - - /** - * Key to provide when stopping jetty on executing java -DSTOP.KEY=<stopKey> - * -DSTOP.PORT=<stopPort> -jar start.jar --stop - */ - @Parameter(required = true) - protected String stopKey; - /** * Max time in seconds that the plugin will wait for confirmation that jetty has stopped. */ @Parameter protected int stopWait; + + @Override + protected void startJettyEmbedded() throws MojoExecutionException + { + //Does not start jetty + return; + } + + @Override + protected void startJettyForked() throws MojoExecutionException + { + //Does not start jetty + return; + } + + @Override + protected void startJettyDistro() throws MojoExecutionException + { + //Does not start jetty + return; + } @Override public void execute() throws MojoExecutionException, MojoFailureException @@ -70,8 +75,6 @@ public class JettyStopMojo extends AbstractMojo if (stopKey == null) throw new MojoExecutionException("Please specify a valid stopKey"); - //Ensure jetty Server instance stops. Whether or not the remote process - //also stops depends whether or not it was started with ShutdownMonitor.exitVm=true String command = "forcestop"; try (Socket s = new Socket(InetAddress.getByName("127.0.0.1"), stopPort);) @@ -108,24 +111,4 @@ public class JettyStopMojo extends AbstractMojo getLog().error(e); } } - - public int getStopPort() - { - return stopPort; - } - - public void setStopPort(int stopPort) - { - this.stopPort = stopPort; - } - - public String getStopKey() - { - return stopKey; - } - - public void setStopKey(String stopKey) - { - this.stopKey = stopKey; - } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenMetaInfConfiguration.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenMetaInfConfiguration.java index f70eda576db..ac0175e77bb 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenMetaInfConfiguration.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenMetaInfConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -23,12 +23,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MavenWebInfConfiguration @@ -38,7 +38,7 @@ import org.eclipse.jetty.webapp.WebAppContext; */ public class MavenMetaInfConfiguration extends MetaInfConfiguration { - private static final Logger LOG = Log.getLogger(MavenMetaInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(MavenMetaInfConfiguration.class); protected static int COUNTER = 0; @@ -61,7 +61,7 @@ public class MavenMetaInfConfiguration extends MetaInfConfiguration throws Exception { List list = new ArrayList<>(); - JettyWebAppContext jwac = (JettyWebAppContext)context; + MavenWebAppContext jwac = (MavenWebAppContext)context; List files = jwac.getWebInfLib(); if (files != null) { @@ -90,15 +90,13 @@ public class MavenMetaInfConfiguration extends MetaInfConfiguration /** * Add in the classes dirs from test/classes and target/classes - * - * @see org.eclipse.jetty.webapp.MetaInfConfiguration#findClassDirs(org.eclipse.jetty.webapp.WebAppContext) */ @Override protected List findClassDirs(WebAppContext context) throws Exception { List list = new ArrayList<>(); - JettyWebAppContext jwac = (JettyWebAppContext)context; + MavenWebAppContext jwac = (MavenWebAppContext)context; List files = jwac.getWebInfClasses(); if (files != null) { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenQuickStartConfiguration.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenQuickStartConfiguration.java index 597c313555e..6199d45a7d1 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenQuickStartConfiguration.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenQuickStartConfiguration.java @@ -1,91 +1,45 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; -import java.io.File; - import org.eclipse.jetty.quickstart.QuickStartConfiguration; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; -import org.eclipse.jetty.webapp.WebAppClassLoader; +import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MavenQuickStartConfiguration */ public class MavenQuickStartConfiguration extends QuickStartConfiguration { - private static final Logger LOG = Log.getLogger(QuickStartConfiguration.class); - - private Resource _quickStartWebXml; //the descriptor to use for starting/generating quickstart - - public void setQuickStartWebXml(Resource quickStartWebXml) - { - _quickStartWebXml = quickStartWebXml; - } - + private static final Logger LOG = LoggerFactory.getLogger(QuickStartConfiguration.class); + @Override - public Resource getQuickStartWebXml(WebAppContext context) throws Exception + public Class replaces() { - if (_quickStartWebXml == null) - return super.getQuickStartWebXml(context); - - return _quickStartWebXml; + return QuickStartConfiguration.class; } - - @Override - public void preConfigure(WebAppContext context) throws Exception - { - //check that webapp is suitable for quick start - if (context.getBaseResource() == null) - throw new IllegalStateException("No location for webapp"); - - //look for quickstart-web.xml in WEB-INF of webapp - Resource quickStartWebXml = getQuickStartWebXml(context); - if (LOG.isDebugEnabled()) - LOG.debug("quickStartWebXml={}", quickStartWebXml); - super.preConfigure(context); - } - - @Override - public void configure(WebAppContext context) throws Exception - { - JettyWebAppContext jwac = (JettyWebAppContext)context; - - //put the classes dir and all dependencies into the classpath - if (jwac.getClassPathFiles() != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("Setting up classpath ..."); - for (File classPathFile : jwac.getClassPathFiles()) - { - ((WebAppClassLoader)context.getClassLoader()).addClassPath(classPathFile.getCanonicalPath()); - } - } - - //Set up the quickstart environment for the context - super.configure(context); - } - + @Override public void deconfigure(WebAppContext context) throws Exception { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenServerConnector.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenServerConnector.java index 4cb641a379a..a886de76abc 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenServerConnector.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenServerConnector.java @@ -1,27 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.concurrent.Future; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; @@ -121,7 +121,7 @@ public class MavenServerConnector extends ContainerLifeCycle implements Connecto } @Override - public Future shutdown() + public CompletableFuture shutdown() { return checkDelegate().shutdown(); } @@ -144,72 +144,48 @@ public class MavenServerConnector extends ContainerLifeCycle implements Connecto return checkDelegate().getExecutor(); } - /** - * @see org.eclipse.jetty.server.Connector#getScheduler() - */ @Override public Scheduler getScheduler() { return checkDelegate().getScheduler(); } - /** - * @see org.eclipse.jetty.server.Connector#getByteBufferPool() - */ @Override public ByteBufferPool getByteBufferPool() { return checkDelegate().getByteBufferPool(); } - /** - * @see org.eclipse.jetty.server.Connector#getConnectionFactory(java.lang.String) - */ @Override public ConnectionFactory getConnectionFactory(String nextProtocol) { return checkDelegate().getConnectionFactory(nextProtocol); } - /** - * @see org.eclipse.jetty.server.Connector#getConnectionFactory(java.lang.Class) - */ @Override public T getConnectionFactory(Class factoryType) { return checkDelegate().getConnectionFactory(factoryType); } - /** - * @see org.eclipse.jetty.server.Connector#getDefaultConnectionFactory() - */ @Override public ConnectionFactory getDefaultConnectionFactory() { return checkDelegate().getDefaultConnectionFactory(); } - /** - * @see org.eclipse.jetty.server.Connector#getConnectionFactories() - */ @Override public Collection getConnectionFactories() { return checkDelegate().getConnectionFactories(); } - /** - * @see org.eclipse.jetty.server.Connector#getProtocols() - */ @Override public List getProtocols() { return checkDelegate().getProtocols(); } - /** - * @see org.eclipse.jetty.server.Connector#getIdleTimeout() - */ @Override @ManagedAttribute("maximum time a connection can be idle before being closed (in ms)") public long getIdleTimeout() @@ -217,27 +193,18 @@ public class MavenServerConnector extends ContainerLifeCycle implements Connecto return checkDelegate().getIdleTimeout(); } - /** - * @see org.eclipse.jetty.server.Connector#getTransport() - */ @Override public Object getTransport() { return checkDelegate().getTransport(); } - /** - * @see org.eclipse.jetty.server.Connector#getConnectedEndPoints() - */ @Override public Collection getConnectedEndPoints() { return checkDelegate().getConnectedEndPoints(); } - /** - * @see org.eclipse.jetty.server.Connector#getName() - */ @Override public String getName() { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebAppContext.java similarity index 73% rename from jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java rename to jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebAppContext.java index 79c8509ad70..7aae9d0b533 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebAppContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -23,44 +23,40 @@ import java.io.IOException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.util.ArrayList; -import java.util.EventListener; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; -import org.eclipse.jetty.annotations.AnnotationConfiguration; import org.eclipse.jetty.plus.webapp.EnvConfiguration; -import org.eclipse.jetty.plus.webapp.PlusConfiguration; import org.eclipse.jetty.quickstart.QuickStartConfiguration; -import org.eclipse.jetty.quickstart.QuickStartConfiguration.Mode; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletMapping; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; import org.eclipse.jetty.webapp.Configuration; +import org.eclipse.jetty.webapp.Configurations; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * JettyWebAppContext + * MavenWebAppContext * * Extends the WebAppContext to specialize for the maven environment. We pass in * the list of files that should form the classpath for the webapp when * executing in the plugin, and any jetty-env.xml file that may have been * configured. */ -public class JettyWebAppContext extends WebAppContext +public class MavenWebAppContext extends WebAppContext { - private static final Logger LOG = Log.getLogger(JettyWebAppContext.class); + private static final Logger LOG = LoggerFactory.getLogger(MavenWebAppContext.class); private static final String DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN = ".*/javax.servlet-[^/]*\\.jar$|.*/jetty-servlet-api-[^/]*\\.jar$|.*javax.servlet.jsp.jstl-[^/]*\\.jar|.*taglibs-standard-impl-.*\\.jar"; @@ -105,18 +101,11 @@ public class JettyWebAppContext extends WebAppContext */ private boolean _baseAppFirst = true; - private boolean _isGenerateQuickStart; - - public JettyWebAppContext() throws Exception + public MavenWebAppContext() throws Exception { super(); // Turn off copyWebInf option as it is not applicable for plugin. - super.setCopyWebInf(false); - addConfiguration(new MavenWebInfConfiguration()); - addConfiguration(new MavenMetaInfConfiguration()); - addConfiguration(new EnvConfiguration()); - addConfiguration(new PlusConfiguration()); - addConfiguration(new AnnotationConfiguration()); + super.setCopyWebInf(false); } public void setContainerIncludeJarPattern(String pattern) @@ -210,27 +199,6 @@ public class JettyWebAppContext extends WebAppContext return attr == null ? null : attr.toString(); } - /** - * Toggle whether or not the origin attribute will be generated into the - * xml. - * - * @param generateOrigin if true then the origin of each xml element is - * added, otherwise it is omitted. - */ - public void setGenerateOrigin(boolean generateOrigin) - { - setAttribute(QuickStartConfiguration.GENERATE_ORIGIN, generateOrigin); - } - - /** - * @return true if the origin attribute will be generated, false otherwise - */ - public boolean isGenerateOrigin() - { - Object attr = getAttribute(QuickStartConfiguration.GENERATE_ORIGIN); - return attr == null ? false : Boolean.valueOf(attr.toString()); - } - public List getOverlays() { return _overlays; @@ -246,35 +214,6 @@ public class JettyWebAppContext extends WebAppContext return _baseAppFirst; } - /** - * Set the file to use into which to generate the quickstart output. - * - * @param quickStartWebXml the full path to the file to use - */ - public void setQuickStartWebDescriptor(String quickStartWebXml) throws Exception - { - setQuickStartWebDescriptor(Resource.newResource(quickStartWebXml)); - } - - /** - * Set the Resource to use into which to generate the quickstart output. - */ - protected void setQuickStartWebDescriptor(Resource quickStartWebXml) - { - setAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML, quickStartWebXml.toString()); - } - - public Resource getQuickStartWebDescriptor() throws Exception - { - Object o = getAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML); - if (o == null) - return null; - else if (o instanceof Resource) - return (Resource)o; - else - return Resource.newResource((String)o); - } - /** * This method is provided as a convenience for jetty maven plugin * configuration @@ -307,41 +246,9 @@ public class JettyWebAppContext extends WebAppContext return _webInfClasses; } - /** - * If true, a quickstart for the webapp is generated. - * - * @param quickStart if true the quickstart is generated, false otherwise - */ - public void setGenerateQuickStart(boolean quickStart) - { - _isGenerateQuickStart = quickStart; - } - - public boolean isGenerateQuickStart() - { - return _isGenerateQuickStart; - } - @Override public void doStart() throws Exception { - - // choose if this will be a quickstart or normal start - if (!isGenerateQuickStart() && getQuickStartWebDescriptor() != null) - { - MavenQuickStartConfiguration quickStart = new MavenQuickStartConfiguration(); - quickStart.setMode(Mode.QUICKSTART); - quickStart.setQuickStartWebXml(getQuickStartWebDescriptor()); - addConfiguration(quickStart); - } - else if (isGenerateQuickStart()) - { - MavenQuickStartConfiguration quickStart = new MavenQuickStartConfiguration(); - quickStart.setMode(Mode.GENERATE); - quickStart.setQuickStartWebXml(getQuickStartWebDescriptor()); - addConfiguration(quickStart); - } - // Set up the pattern that tells us where the jars are that need // scanning @@ -393,22 +300,27 @@ public class JettyWebAppContext extends WebAppContext } @Override - protected void loadConfigurations() + protected Configurations newConfigurations() { - super.loadConfigurations(); - try + Configurations configurations = super.newConfigurations(); + if (getJettyEnvXml() != null) { - // inject configurations with config from maven plugin - for (Configuration c : getWebAppConfigurations()) + try { - if (c instanceof EnvConfiguration && getJettyEnvXml() != null) - ((EnvConfiguration)c).setJettyEnvResource(new PathResource(new File(getJettyEnvXml()))); + // inject configurations with config from maven plugin + for (Configuration c : configurations) + { + if (c instanceof EnvConfiguration) + ((EnvConfiguration)c).setJettyEnvResource(Resource.newResource(getJettyEnvXml())); + } + } + catch (IOException e) + { + throw new RuntimeException(e); } } - catch (Exception e) - { - throw new RuntimeException(e); - } + + return configurations; } @Override @@ -434,11 +346,9 @@ public class JettyWebAppContext extends WebAppContext super.doStop(); - // remove all listeners, servlets and filters. This is because we will - // re-apply - // any context xml file, which means they would potentially be added - // multiple times. - setEventListeners(new EventListener[0]); + // remove all servlets and filters. This is because we will + // re-appy any context xml file, which means they would potentially be + // added multiple times. getServletHandler().setFilters(new FilterHolder[0]); getServletHandler().setFilterMappings(new FilterMapping[0]); getServletHandler().setServlets(new ServletHolder[0]); @@ -515,7 +425,7 @@ public class JettyWebAppContext extends WebAppContext } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } return resource; @@ -577,7 +487,7 @@ public class JettyWebAppContext extends WebAppContext public void initCDI() { - Class cdiInitializer = null; + Class cdiInitializer = null; try { cdiInitializer = Thread.currentThread().getContextClassLoader().loadClass("org.eclipse.jetty.cdi.servlet.JettyWeldInitializer"); diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebInfConfiguration.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebInfConfiguration.java index d580e4842a6..80901607c94 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebInfConfiguration.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/MavenWebInfConfiguration.java @@ -1,31 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import java.io.File; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebInfConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MavenWebInfConfiguration @@ -35,7 +35,7 @@ import org.eclipse.jetty.webapp.WebInfConfiguration; */ public class MavenWebInfConfiguration extends WebInfConfiguration { - private static final Logger LOG = Log.getLogger(MavenWebInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(MavenWebInfConfiguration.class); public MavenWebInfConfiguration() { @@ -51,13 +51,10 @@ public class MavenWebInfConfiguration extends WebInfConfiguration return WebInfConfiguration.class; } - /** - * @see org.eclipse.jetty.webapp.WebInfConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void configure(WebAppContext context) throws Exception { - JettyWebAppContext jwac = (JettyWebAppContext)context; + MavenWebAppContext jwac = (MavenWebAppContext)context; //put the classes dir and all dependencies into the classpath if (jwac.getClassPathFiles() != null && context.getClassLoader() instanceof WebAppClassLoader) diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Overlay.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Overlay.java index 0378897af24..054dac66443 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Overlay.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Overlay.java @@ -1,27 +1,33 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; +import java.io.File; +import java.io.IOException; + import org.eclipse.jetty.util.resource.Resource; /** * Overlay + * + * An Overlay represents overlay information derived from the + * maven-war-plugin. */ public class Overlay { @@ -68,4 +74,21 @@ public class Overlay } return strbuff.toString(); } + + /** + * Unpack the overlay into the given directory. Only + * unpack if the directory does not exist, or the overlay + * has been modified since the dir was created. + * + * @param dir the directory into which to unpack the overlay + * @throws IOException + */ + public void unpackTo(File dir) throws IOException + { + if (dir == null) + throw new IllegalStateException("No overly unpack directory"); + //only unpack if the overlay is newer + if (!dir.exists() || (getResource().lastModified() > dir.lastModified())) + getResource().copyTo(dir); + } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java index fe7dd6d9af5..f1cede85e15 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -28,6 +28,9 @@ import org.eclipse.jetty.util.StringUtil; /** * OverlayConfig + * + * The configuration of a war overlay in a pom. Used to help determine which resources + * from a project's dependent war should be included. */ public class OverlayConfig { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayManager.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayManager.java new file mode 100644 index 00000000000..8e0ab50a559 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/OverlayManager.java @@ -0,0 +1,161 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceCollection; + +/** + * OverlayManager + * + * Mediates information about overlays configured in a war plugin. + * + */ +public class OverlayManager +{ + private WarPluginInfo warPlugin; + + public OverlayManager(WarPluginInfo warPlugin) + { + this.warPlugin = warPlugin; + } + + public void applyOverlays(MavenWebAppContext webApp) + throws Exception + { + List resourceBases = new ArrayList(); + + for (Overlay o : getOverlays()) + { + //can refer to the current project in list of overlays for ordering purposes + if (o.getConfig() != null && o.getConfig().isCurrentProject() && webApp.getBaseResource().exists()) + { + resourceBases.add(webApp.getBaseResource()); + continue; + } + //add in the selectively unpacked overlay in the correct order to the webapp's resource base + resourceBases.add(unpackOverlay(o)); + } + + if (!resourceBases.contains(webApp.getBaseResource()) && webApp.getBaseResource().exists()) + { + if (webApp.getBaseAppFirst()) + resourceBases.add(0, webApp.getBaseResource()); + else + resourceBases.add(webApp.getBaseResource()); + } + + webApp.setBaseResource(new ResourceCollection(resourceBases.toArray(new Resource[resourceBases.size()]))); + } + + /** + * Generate an ordered list of overlays + */ + protected List getOverlays() + throws Exception + { + Set matchedWarArtifacts = new HashSet(); + List overlays = new ArrayList(); + + //Check all of the overlay configurations + for (OverlayConfig config:warPlugin.getMavenWarOverlayConfigs()) + { + //overlays can be individually skipped + if (config.isSkip()) + continue; + + //an empty overlay refers to the current project - important for ordering + if (config.isCurrentProject()) + { + Overlay overlay = new Overlay(config, null); + overlays.add(overlay); + continue; + } + + //if a war matches an overlay config + Artifact a = warPlugin.getWarArtifact(config.getGroupId(), config.getArtifactId(), config.getClassifier()); + if (a != null) + { + matchedWarArtifacts.add(a); + SelectiveJarResource r = new SelectiveJarResource(new URL("jar:" + Resource.toURL(a.getFile()).toString() + "!/")); + r.setIncludes(config.getIncludes()); + r.setExcludes(config.getExcludes()); + Overlay overlay = new Overlay(config, r); + overlays.add(overlay); + } + } + + //iterate over the left over war artifacts add them + for (Artifact a: warPlugin.getWarArtifacts()) + { + if (!matchedWarArtifacts.contains(a)) + { + Overlay overlay = new Overlay(null, Resource.newResource(new URL("jar:" + Resource.toURL(a.getFile()).toString() + "!/"))); + overlays.add(overlay); + } + } + return overlays; + } + + /** + * Unpack a war overlay. + * + * @param overlay the war overlay to unpack + * @return the location to which it was unpacked + * @throws IOException + */ + protected Resource unpackOverlay(Overlay overlay) + throws IOException + { + if (overlay.getResource() == null) + return null; //nothing to unpack + + //Get the name of the overlayed war and unpack it to a dir of the + //same name in the temporary directory + String name = overlay.getResource().getName(); + if (name.endsWith("!/")) + name = name.substring(0, name.length() - 2); + int i = name.lastIndexOf('/'); + if (i > 0) + name = name.substring(i + 1, name.length()); + name = name.replace('.', '_'); + + File overlaysDir = new File(warPlugin.getProject().getBuild().getDirectory(), "jetty_overlays"); + File dir = new File(overlaysDir, name); + + //if specified targetPath, unpack to that subdir instead + File unpackDir = dir; + if (overlay.getConfig() != null && overlay.getConfig().getTargetPath() != null) + unpackDir = new File(dir, overlay.getConfig().getTargetPath()); + + overlay.unpackTo(unpackDir); + + //use top level of unpacked content + return Resource.newResource(unpackDir.getCanonicalPath()); + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/PluginLog.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/PluginLog.java index 0cd98fe0634..720567ec7fc 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/PluginLog.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/PluginLog.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/QuickStartGenerator.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/QuickStartGenerator.java new file mode 100644 index 00000000000..ff1adc658e4 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/QuickStartGenerator.java @@ -0,0 +1,192 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; + +import org.eclipse.jetty.annotations.AnnotationConfiguration; +import org.eclipse.jetty.quickstart.QuickStartConfiguration; +import org.eclipse.jetty.quickstart.QuickStartConfiguration.Mode; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.thread.QueuedThreadPool; + +/** + * Run enough of jetty in order to generate a quickstart file for a + * webapp. Optionally, some essential elements of the WebAppContext + * configuration can also be converted to properties and saved to + * a file after the quickstart generation. + * + */ +public class QuickStartGenerator +{ + private File quickstartXml; + private MavenWebAppContext webApp; + private File webAppPropsFile; + private String contextXml; + private boolean prepared = false; + private Server server; + private QueuedThreadPool tpool; + + /** + * @param quickstartXml the file to generate quickstart into + * @param webApp the webapp for which to generate quickstart + */ + public QuickStartGenerator(File quickstartXml, MavenWebAppContext webApp) + { + this.quickstartXml = quickstartXml; + this.webApp = webApp; + } + + /** + * @return the webApp + */ + public MavenWebAppContext getWebApp() + { + return webApp; + } + + /** + * @return the quickstartXml + */ + public File getQuickstartXml() + { + return quickstartXml; + } + + /** + * @return the server + */ + public Server getServer() + { + return server; + } + + /** + * @param server the server to use + */ + public void setServer(Server server) + { + this.server = server; + } + + public File getWebAppPropsFile() + { + return webAppPropsFile; + } + + /** + * @param webAppPropsFile properties file describing the webapp + */ + public void setWebAppPropsFile(File webAppPropsFile) + { + this.webAppPropsFile = webAppPropsFile; + } + + public String getContextXml() + { + return contextXml; + } + + /** + * @param contextXml a context xml file to apply to the webapp + */ + public void setContextXml(String contextXml) + { + this.contextXml = contextXml; + } + + /** + * Configure the webapp in preparation for quickstart generation. + * + * @throws Exception + */ + private void prepareWebApp() + throws Exception + { + if (webApp == null) + webApp = new MavenWebAppContext(); + + //set the webapp up to do very little other than generate the quickstart-web.xml + webApp.addConfiguration(new MavenQuickStartConfiguration()); + webApp.setAttribute(QuickStartConfiguration.MODE, Mode.GENERATE); + webApp.setAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML, Resource.newResource(quickstartXml)); + webApp.setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, "o"); + webApp.setCopyWebDir(false); + webApp.setCopyWebInf(false); + } + + /** + * Run enough of jetty to generate a full quickstart xml file for the + * webapp. The tmp directory is persisted. + * + * @throws Exception + */ + public void generate() + throws Exception + { + if (quickstartXml == null) + throw new IllegalStateException("No quickstart xml output file"); + + if (!prepared) + { + prepared = true; + prepareWebApp(); + + if (server == null) + server = new Server(); + + //ensure handler structure enabled + ServerSupport.configureHandlers(server, null, null); + + ServerSupport.configureDefaultConfigurationClasses(server); + + //if our server has a thread pool associated we can do annotation scanning multithreaded, + //otherwise scanning will be single threaded + if (tpool == null) + tpool = server.getBean(QueuedThreadPool.class); + + //add webapp to our fake server instance + ServerSupport.addWebApplication(server, webApp); + + //leave everything unpacked for the forked process to use + webApp.setPersistTempDirectory(true); + } + + try + { + if (tpool != null) + tpool.start(); + else + webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString()); + + webApp.start(); //just enough to generate the quickstart + + //save config of the webapp BEFORE we stop + if (webAppPropsFile != null) + WebAppPropertyConverter.toProperties(webApp, webAppPropsFile, contextXml); + } + finally + { + webApp.stop(); + if (tpool != null) + tpool.stop(); + } + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanPattern.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanPattern.java index 61fb6c166ac..bd1125d9d17 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanPattern.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanPattern.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -24,7 +24,7 @@ import java.util.List; /** * ScanPattern * - * A pattern of includes and excludes. + * Ant-style pattern of includes and excludes. */ public class ScanPattern { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanTargetPattern.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanTargetPattern.java index 567a66113ba..dd8c62dfe34 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanTargetPattern.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ScanTargetPattern.java @@ -1,27 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import java.io.File; +import java.nio.file.Path; +import java.nio.file.PathMatcher; import java.util.Collections; import java.util.List; +import org.eclipse.jetty.util.IncludeExcludeSet; + /** * ScanTargetPattern * @@ -87,4 +91,21 @@ public class ScanTargetPattern { return (_pattern == null ? Collections.emptyList() : _pattern.getExcludes()); } + + public void configureIncludesExcludeSet(IncludeExcludeSet includesExcludes) + { + for (String include:getIncludes()) + { + if (!include.startsWith("glob:")) + include = "glob:" + include; + includesExcludes.include(_directory.toPath().getFileSystem().getPathMatcher(include)); + } + + for (String exclude:getExcludes()) + { + if (!exclude.startsWith("glob:")) + exclude = "glob:" + exclude; + includesExcludes.exclude(_directory.toPath().getFileSystem().getPathMatcher(exclude)); + } + } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SelectiveJarResource.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SelectiveJarResource.java index 5b96ce16f8f..41697a26218 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SelectiveJarResource.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SelectiveJarResource.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -35,9 +35,9 @@ import org.codehaus.plexus.util.SelectorUtils; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SelectiveJarResource @@ -46,11 +46,18 @@ import org.eclipse.jetty.util.resource.JarResource; */ public class SelectiveJarResource extends JarResource { - private static final Logger LOG = Log.getLogger(SelectiveJarResource.class); - public static final List DEFAULT_INCLUDES = Arrays.asList(new String[]{ - "**" - });// No includes supplied, so set it to 'matches all' - public static final List DEFAULT_EXCLUDES = Collections.emptyList(); //No includes, set to no exclusions + private static final Logger LOG = LoggerFactory.getLogger(SelectiveJarResource.class); + + /** + * Default matches every resource. + */ + public static final List DEFAULT_INCLUDES = + Arrays.asList(new String[]{"**"}); + + /** + * Default is to exclude nothing. + */ + public static final List DEFAULT_EXCLUDES = Collections.emptyList(); List _includes = null; List _excludes = null; @@ -105,9 +112,6 @@ public class SelectiveJarResource extends JarResource return false; } - /** - * @see org.eclipse.jetty.util.resource.JarResource#copyTo(java.io.File) - */ @Override public void copyTo(File directory) throws IOException { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerConnectorListener.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerConnectorListener.java index 48e913e3bb4..271dc224348 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerConnectorListener.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerConnectorListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -37,13 +37,9 @@ import org.eclipse.jetty.util.component.LifeCycle; */ public class ServerConnectorListener extends AbstractLifeCycleListener { - private String _fileName; private String _sysPropertyName; - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener#lifeCycleStarted(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStarted(LifeCycle event) { diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java index 0037e4f6cdf..3c5965801d3 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -30,7 +30,6 @@ import org.eclipse.jetty.util.resource.Resource; */ public class ServerListener implements LifeCycle.Listener { - private String _tokenFile; public void setTokenFile(String file) @@ -43,18 +42,11 @@ public class ServerListener implements LifeCycle.Listener return _tokenFile; } - /** - * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStarting(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStarting(LifeCycle event) { - } - /** - * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStarted(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStarted(LifeCycle event) { @@ -72,30 +64,18 @@ public class ServerListener implements LifeCycle.Listener } } - /** - * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleFailure(org.eclipse.jetty.util.component.LifeCycle, java.lang.Throwable) - */ @Override public void lifeCycleFailure(LifeCycle event, Throwable cause) { - } - /** - * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStopping(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStopping(LifeCycle event) { - } - /** - * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStopped(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStopped(LifeCycle event) { - } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java index 48447c19303..b1001c744b4 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; @@ -29,9 +29,11 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.webapp.Configurations; import org.eclipse.jetty.webapp.WebAppContext; @@ -52,22 +54,24 @@ public class ServerSupport /** * Set up the handler structure to receive a webapp. - * Also put in a DefaultHandler so we get a nice page + * Also put in a DefaultHandler so we get a nicer page * than a 404 if we hit the root and the webapp's * context isn't at root. - * - * @param server the server - * @param requestLog the request log - * @throws Exception if unable to configure the handlers + * + * @param server the server to use + * @param contextHandlers the context handlers to include + * @param requestLog a request log to use + * @throws Exception */ - public static void configureHandlers(Server server, RequestLog requestLog) throws Exception + public static void configureHandlers(Server server, List contextHandlers, RequestLog requestLog) throws Exception { if (server == null) throw new IllegalArgumentException("Server is null"); DefaultHandler defaultHandler = new DefaultHandler(); + RequestLogHandler requestLogHandler = new RequestLogHandler(); if (requestLog != null) - server.setRequestLog(requestLog); + requestLogHandler.setRequestLog(requestLog); ContextHandlerCollection contexts = findContextHandlerCollection(server); if (contexts == null) @@ -78,12 +82,20 @@ public class ServerSupport { handlers = new HandlerCollection(); server.setHandler(handlers); - handlers.setHandlers(new Handler[]{contexts, defaultHandler}); + handlers.setHandlers(new Handler[]{contexts, defaultHandler, requestLogHandler}); } else { handlers.addHandler(contexts); } + } + + if (contextHandlers != null) + { + for (ContextHandler context:contextHandlers) + { + contexts.addHandler(context); + } } } @@ -92,8 +104,9 @@ public class ServerSupport * * @param server the server * @param connector the connector + * @param properties jetty properties */ - public static void configureConnectors(Server server, Connector connector) + public static void configureConnectors(Server server, Connector connector, Map properties) { if (server == null) throw new IllegalArgumentException("Server is null"); @@ -111,8 +124,14 @@ public class ServerSupport { //Make a new default connector MavenServerConnector tmp = new MavenServerConnector(); - //use any jetty.http.port settings provided - String port = System.getProperty(MavenServerConnector.PORT_SYSPROPERTY, System.getProperty("jetty.port", MavenServerConnector.DEFAULT_PORT_STR)); + //use any jetty.http.port settings provided, trying system properties before jetty properties + String port = System.getProperty(MavenServerConnector.PORT_SYSPROPERTY); + if (port == null) + port = System.getProperty("jetty.port"); + if (port == null) + port = (properties != null ? properties.get(MavenServerConnector.PORT_SYSPROPERTY) : null); + if (port == null) + port = MavenServerConnector.DEFAULT_PORT_STR; tmp.setPort(Integer.parseInt(port.trim())); tmp.setServer(server); server.setConnectors(new Connector[]{tmp}); @@ -125,7 +144,7 @@ public class ServerSupport * @param server the server * @param loginServices the login services */ - public static void configureLoginServices(Server server, LoginService[] loginServices) + public static void configureLoginServices(Server server, List loginServices) { if (server == null) throw new IllegalArgumentException("Server is null"); @@ -140,6 +159,12 @@ public class ServerSupport } } + /** + * Add a WebAppContext to a Server + * @param server the server to use + * @param webapp the webapp to add + * @throws Exception + */ public static void addWebApplication(Server server, WebAppContext webapp) throws Exception { if (server == null) @@ -150,6 +175,12 @@ public class ServerSupport contexts.addHandler(webapp); } + /** + * Locate a ContextHandlerCollection for a Server. + * + * @param server the Server to check. + * @return The ContextHandlerCollection or null if not found. + */ public static ContextHandlerCollection findContextHandlerCollection(Server server) { if (server == null) @@ -173,7 +204,7 @@ public class ServerSupport if (files == null || files.isEmpty()) return server; - Map lastMap = new HashMap<>(); + Map lastMap = new HashMap(); if (server != null) lastMap.put("Server", server); @@ -218,7 +249,7 @@ public class ServerSupport * @param server the Server instance to configure * @param files the xml configs to apply * @return the Server after application of configs - * @throws Exception if unable to apply the xml configuration + * @throws Exception */ public static Server applyXmlConfigurations(Server server, List files) throws Exception diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java deleted file mode 100644 index 7d76d8124a5..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java +++ /dev/null @@ -1,253 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ShutdownMonitor; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.resource.Resource; - -/** - * Starter Class which is exec'ed to create a new jetty process. Used by the JettyRunForked mojo. - */ -public class Starter -{ - private static final Logger LOG = Log.getLogger(Starter.class); - - private List jettyXmls; // list of jetty.xml config files to apply - private Server server; - private JettyWebAppContext webApp; - private Map jettyProperties; //optional list of jetty properties to set - - private int stopPort = 0; - private String stopKey = null; - private File propsFile; - private String token; - - public void configureJetty() throws Exception - { - LOG.debug("Starting Jetty Server ..."); - Resource.setDefaultUseCaches(false); - - //apply any configs from jetty.xml files first - applyJettyXml(); - - //ensure there's a connector - ServerSupport.configureConnectors(server, null); - - //check if contexts already configured, create if not - ServerSupport.configureHandlers(server, null); - - //Set up list of default Configurations to apply to a webapp - ServerSupport.configureDefaultConfigurationClasses(server); - - webApp = new JettyWebAppContext(); - - //configure webapp from properties file describing unassembled webapp - configureWebApp(); - - //make it a quickstart if the quickstart-web.xml file exists - if (webApp.getTempDirectory() != null) - { - File qs = new File(webApp.getTempDirectory(), "quickstart-web.xml"); - if (qs.exists() && qs.isFile()) - webApp.setQuickStartWebDescriptor(Resource.newResource(qs)); - } - - ServerSupport.addWebApplication(server, webApp); - - if (stopPort > 0 && stopKey != null) - { - ShutdownMonitor monitor = ShutdownMonitor.getInstance(); - monitor.setPort(stopPort); - monitor.setKey(stopKey); - monitor.setExitVm(true); - } - } - - public void configureWebApp() - throws Exception - { - if (propsFile == null) - return; - - //apply a properties file that defines the things that we configure in the jetty:run plugin - WebAppPropertyConverter.fromProperties(webApp, propsFile, server, jettyProperties); - } - - public void getConfiguration(String[] args) - throws Exception - { - for (int i = 0; i < args.length; i++) - { - //--stop-port - if ("--stop-port".equals(args[i])) - { - stopPort = Integer.parseInt(args[++i]); - continue; - } - - //--stop-key - if ("--stop-key".equals(args[i])) - { - stopKey = args[++i]; - continue; - } - - //--jettyXml - if ("--jetty-xml".equals(args[i])) - { - jettyXmls = new ArrayList(); - String[] names = StringUtil.csvSplit(args[++i]); - for (int j = 0; names != null && j < names.length; j++) - { - jettyXmls.add(new File(names[j].trim())); - } - continue; - } - - //--props - if ("--props".equals(args[i])) - { - propsFile = new File(args[++i].trim()); - continue; - } - - //--token - if ("--token".equals(args[i])) - { - token = args[++i].trim(); - continue; - } - - //assume everything else is a jetty property to be passed in - if (jettyProperties == null) - jettyProperties = new HashMap<>(); - - String[] tmp = args[i].trim().split("="); - if (tmp.length == 2) - jettyProperties.put(tmp[0], tmp[1]); - } - } - - public void run() throws Exception - { - LOG.info("Started Jetty Server"); - server.start(); - } - - public void join() throws Exception - { - server.join(); - } - - public void communicateStartupResult() - { - if (token != null) - { - try - { - Resource r = Resource.newResource(token); - r.getFile().createNewFile(); - } - catch (Exception x) - { - throw new IllegalStateException(x); - } - } - } - - /** - * Apply any jetty xml files given - * - * @throws Exception if unable to apply the xml - */ - public void applyJettyXml() throws Exception - { - Server tmp = ServerSupport.applyXmlConfigurations(server, jettyXmls, jettyProperties); - if (server == null) - server = tmp; - - if (server == null) - server = new Server(); - } - - protected void prependHandler(Handler handler, HandlerCollection handlers) - { - if (handler == null || handlers == null) - return; - - Handler[] existing = handlers.getChildHandlers(); - Handler[] children = new Handler[existing.length + 1]; - children[0] = handler; - System.arraycopy(existing, 0, children, 1, existing.length); - handlers.setHandlers(children); - } - - /** - * - */ - private List fromCSV(String csv) - { - if (csv == null || "".equals(csv.trim())) - return null; - String[] atoms = StringUtil.csvSplit(csv); - List list = new ArrayList(); - for (String a : atoms) - { - list.add(a.trim()); - } - return list; - } - - /** - * @param args Starter arguments - */ - public static final void main(String[] args) - { - if (args == null) - System.exit(1); - - Starter starter = null; - try - { - starter = new Starter(); - starter.getConfiguration(args); - starter.configureJetty(); - starter.run(); - starter.communicateStartupResult(); - starter.join(); - } - catch (Exception e) - { - e.printStackTrace(); - System.exit(1); - } - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SystemProperties.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SystemProperties.java deleted file mode 100644 index ada9c59824b..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SystemProperties.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * SystemProperties - * - * Map of name to SystemProperty. - * - * When a SystemProperty instance is added, if it has not - * been already set (eg via the command line java system property) - * then it will be set. - */ -public class SystemProperties -{ - private final Map properties; - private boolean force; - - public SystemProperties() - { - properties = new HashMap<>(); - } - - public void setForce(boolean force) - { - this.force = force; - } - - public boolean getForce() - { - return this.force; - } - - public void setSystemProperty(SystemProperty prop) - { - properties.put(prop.getName(), prop); - if (!force) - prop.setIfNotSetAlready(); - else - prop.setAnyway(); - } - - public SystemProperty getSystemProperty(String name) - { - return properties.get(name); - } - - public boolean containsSystemProperty(String name) - { - return properties.containsKey(name); - } - - public List getSystemProperties() - { - return new ArrayList<>(properties.values()); - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SystemProperty.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SystemProperty.java deleted file mode 100644 index 73e83a67af6..00000000000 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/SystemProperty.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -/** - * SystemProperty - * - * Provides the ability to set System properties - * for the mojo execution. A value will only - * be set if it is not set already. That is, if - * it was set on the command line or by the system, - * it won't be overridden by settings in the - * plugin's configuration. - */ -public class SystemProperty -{ - - private String name; - private String value; - private boolean isSet; - - /** - * @return Returns the name. - */ - public String getName() - { - return this.name; - } - - /** - * @param name The name to set. - */ - public void setName(String name) - { - this.name = name; - } - - public String getKey() - { - return this.name; - } - - public void setKey(String name) - { - this.name = name; - } - - /** - * @return Returns the value. - */ - public String getValue() - { - return this.value; - } - - /** - * @param value The value to set. - */ - public void setValue(String value) - { - this.value = value; - } - - public boolean isSet() - { - return isSet; - } - - /** - * Set a System.property with this value - * if it is not already set. - */ - void setIfNotSetAlready() - { - if (System.getProperty(getName()) == null) - { - System.setProperty(getName(), (getValue() == null ? "" : getValue())); - isSet = true; - } - } - - void setAnyway() - { - System.setProperty(getName(), (getValue() == null ? "" : getValue())); - isSet = true; - } -} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java index 24026f87692..c9354ed8361 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WarPluginInfo.java @@ -1,28 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -30,7 +33,7 @@ import org.eclipse.jetty.util.StringUtil; /** * WarPluginInfo - *

      + * * Information about the maven-war-plugin contained in the pom */ public class WarPluginInfo @@ -40,10 +43,50 @@ public class WarPluginInfo private List _dependentMavenWarIncludes; private List _dependentMavenWarExcludes; private List _overlayConfigs; + private Set _warArtifacts; public WarPluginInfo(MavenProject project) { _project = project; + if (_project.getArtifacts() != null) + { + _warArtifacts = _project.getArtifacts() + .stream() + .filter(a -> "war".equals(a.getType()) || "zip".equals(a.getType())).collect(Collectors.toSet()); + } + else + _warArtifacts = Collections.emptySet(); + } + + /** + * @return the project + */ + public MavenProject getProject() + { + return _project; + } + + /** + * Get all dependent artifacts that are wars. + * @return all artifacts of type "war" or "zip" + */ + public Set getWarArtifacts() + { + return _warArtifacts; + } + + /** + * Get an artifact of type war that matches the given coordinates. + * @param groupId the groupId to match + * @param artifactId the artifactId to match + * @param classifier the classified to match + * @return the matching Artifact or null if no match + */ + public Artifact getWarArtifact(String groupId, String artifactId, String classifier) + { + Optional o = _warArtifacts.stream() + .filter(a -> match(a, groupId, artifactId, classifier)).findFirst(); + return o.orElse(null); } /** @@ -51,20 +94,21 @@ public class WarPluginInfo * * @return the plugin */ - public Plugin getPlugin() + public Plugin getWarPlugin() { if (_plugin == null) { - List plugins = _project.getBuildPlugins(); + List plugins = _project.getBuildPlugins(); if (plugins == null) return null; - Iterator itor = plugins.iterator(); - while (itor.hasNext() && _plugin == null) + for (Plugin p : plugins) { - Plugin plugin = (Plugin)itor.next(); - if ("maven-war-plugin".equals(plugin.getArtifactId())) - _plugin = plugin; + if ("maven-war-plugin".equals(p.getArtifactId())) + { + _plugin = p; + break; + } } } return _plugin; @@ -79,7 +123,7 @@ public class WarPluginInfo { if (_dependentMavenWarIncludes == null) { - getPlugin(); + getWarPlugin(); if (_plugin == null) return null; @@ -106,7 +150,7 @@ public class WarPluginInfo { if (_dependentMavenWarExcludes == null) { - getPlugin(); + getWarPlugin(); if (_plugin == null) return null; @@ -133,7 +177,7 @@ public class WarPluginInfo { if (_overlayConfigs == null) { - getPlugin(); + getWarPlugin(); if (_plugin == null) return Collections.emptyList(); @@ -163,20 +207,37 @@ public class WarPluginInfo return _overlayConfigs; } + + public boolean match(Artifact a, String gid, String aid, String cls) + { + if (a == null) + return (gid == null && aid == null && cls == null); + + if (((a.getGroupId() == null && gid == null) || (a.getGroupId() != null && a.getGroupId().equals(gid))) && + ((a.getArtifactId() == null && aid == null) || (a.getArtifactId() != null && a.getArtifactId().equals(aid))) && + ((a.getClassifier() == null) || (a.getClassifier().equals(cls)))) + return true; + + return false; + } /** - * @return the xml as a string + * Check if the given artifact matches the group and artifact coordinates. + * + * @param a the artifact to check + * @param gid the group id + * @param aid the artifact id + * @return true if matched false otherwise */ - public String getMavenWarOverlayConfigAsString() + public boolean match(Artifact a, String gid, String aid) { - getPlugin(); + if (a == null) + return (gid == null && aid == null); + + if (((a.getGroupId() == null && gid == null) || (a.getGroupId() != null && a.getGroupId().equals(gid))) && + ((a.getArtifactId() == null && aid == null) || (a.getArtifactId() != null && a.getArtifactId().equals(aid)))) + return true; - if (_plugin == null) - return ""; - - Xpp3Dom node = (Xpp3Dom)_plugin.getConfiguration(); - if (node == null) - return ""; - return node.toString(); + return false; } } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java index d5ca0c745e6..d588cefd1bf 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin; import java.io.BufferedWriter; import java.io.File; +import java.io.FileInputStream; import java.io.InputStream; import java.nio.file.Files; import java.util.ArrayList; @@ -27,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import org.eclipse.jetty.quickstart.QuickStartConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; @@ -41,7 +43,22 @@ import org.eclipse.jetty.xml.XmlConfiguration; */ public class WebAppPropertyConverter { - + public static String WEB_XML = "web.xml"; + public static String QUICKSTART_WEB_XML = "quickstart.web.xml"; + public static String CONTEXT_XML = "context.xml"; + public static String CONTEXT_PATH = "context.path"; + public static String TMP_DIR = "tmp.dir"; + public static String TMP_DIR_PERSIST = "tmp.dir.persist"; + public static String BASE_DIRS = "base.dirs"; + public static String WAR_FILE = "war.file"; + public static String CLASSES_DIR = "classes.dir"; + public static String TEST_CLASSES_DIR = "testClasses.dir"; + public static String LIB_JARS = "lib.jars"; + public static String DEFAULTS_DESCRIPTOR = "web.default.xml"; + public static String OVERRIDE_DESCRIPTORS = "web.overrides.xml"; + + //TODO :Support defaults descriptor! + /** * Convert a webapp to properties stored in a file. * @@ -50,7 +67,7 @@ public class WebAppPropertyConverter * @param contextXml the optional context xml file related to the webApp * @throws Exception if any I/O exception occurs */ - public static void toProperties(JettyWebAppContext webApp, File propsFile, String contextXml) + public static void toProperties(MavenWebAppContext webApp, File propsFile, String contextXml) throws Exception { if (webApp == null) @@ -68,41 +85,46 @@ public class WebAppPropertyConverter //web.xml if (webApp.getDescriptor() != null) { - props.put("web.xml", webApp.getDescriptor()); + props.put(WEB_XML, webApp.getDescriptor()); } - if (webApp.getQuickStartWebDescriptor() != null) + Object tmp = webApp.getAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML); + if (tmp != null) { - props.put("quickstart.web.xml", webApp.getQuickStartWebDescriptor().getFile().getAbsolutePath()); + props.put(QUICKSTART_WEB_XML, tmp.toString()); } //sort out the context path if (webApp.getContextPath() != null) { - props.put("context.path", webApp.getContextPath()); + props.put(CONTEXT_PATH, webApp.getContextPath()); } //tmp dir - props.put("tmp.dir", webApp.getTempDirectory().getAbsolutePath()); + props.put(TMP_DIR, webApp.getTempDirectory().getAbsolutePath()); //props.put("tmp.dir.persist", Boolean.toString(originalPersistTemp)); - props.put("tmp.dir.persist", Boolean.toString(webApp.isPersistTempDirectory())); + props.put(TMP_DIR_PERSIST, Boolean.toString(webApp.isPersistTempDirectory())); //send over the calculated resource bases that includes unpacked overlays Resource baseResource = webApp.getBaseResource(); if (baseResource instanceof ResourceCollection) - props.put("base.dirs", toCSV(((ResourceCollection)webApp.getBaseResource()).getResources())); - else - props.put("base.dirs", webApp.getBaseResource().toString()); + props.put(BASE_DIRS, toCSV(((ResourceCollection)webApp.getBaseResource()).getResources())); + else if (baseResource instanceof Resource) + props.put(BASE_DIRS, webApp.getBaseResource().toString()); + + //if there is a war file, use that + if (webApp.getWar() != null) + props.put(WAR_FILE, webApp.getWar()); //web-inf classes if (webApp.getClasses() != null) { - props.put("classes.dir", webApp.getClasses().getAbsolutePath()); + props.put(CLASSES_DIR, webApp.getClasses().getAbsolutePath()); } if (webApp.getTestClasses() != null) { - props.put("testClasses.dir", webApp.getTestClasses().getAbsolutePath()); + props.put(TEST_CLASSES_DIR, webApp.getTestClasses().getAbsolutePath()); } //web-inf lib @@ -118,15 +140,23 @@ public class WebAppPropertyConverter strbuff.append(","); } } - props.put("lib.jars", strbuff.toString()); + props.put(LIB_JARS, strbuff.toString()); //context xml to apply if (contextXml != null) - props.put("context.xml", contextXml); + props.put(CONTEXT_XML, contextXml); + + if (webApp.getDefaultsDescriptor() != null) + props.put(DEFAULTS_DESCRIPTOR, webApp.getDefaultsDescriptor()); + + if (webApp.getOverrideDescriptors() != null) + { + props.put(OVERRIDE_DESCRIPTORS, String.join(",", webApp.getOverrideDescriptors())); + } try (BufferedWriter out = Files.newBufferedWriter(propsFile.toPath())) { - props.store(out, "properties for forked webapp"); + props.store(out, "properties for webapp"); } } @@ -137,9 +167,9 @@ public class WebAppPropertyConverter * @param resource the properties file to apply * @param server the Server instance to use * @param jettyProperties jetty properties to use if there is a context xml file to apply - * @throws Exception if any I/O exception occurs + * @throws Exception */ - public static void fromProperties(JettyWebAppContext webApp, String resource, Server server, Map jettyProperties) + public static void fromProperties(MavenWebAppContext webApp, String resource, Server server, Map jettyProperties) throws Exception { if (resource == null) @@ -149,58 +179,51 @@ public class WebAppPropertyConverter } /** - * Configure a webapp from a properties file - * + * Configure a webapp from properties. + * * @param webApp the webapp to configure - * @param propsFile the properties to apply - * @param server the Server instance to use if there is a context xml file to apply - * @param jettyProperties jetty properties to use if there is a context xml file to apply - * @throws Exception if any I/O exception occurs + * @param webAppProperties properties that describe the configuration of the webapp + * @param server the jetty Server instance + * @param jettyProperties jetty properties + * + * @throws Exception */ - public static void fromProperties(JettyWebAppContext webApp, File propsFile, Server server, Map jettyProperties) + public static void fromProperties(MavenWebAppContext webApp, Properties webAppProperties, Server server, Map jettyProperties) throws Exception { if (webApp == null) throw new IllegalArgumentException("No webapp"); - if (propsFile == null) - throw new IllegalArgumentException("No properties file"); + + if (webAppProperties == null) + return; - if (!propsFile.exists()) - throw new IllegalArgumentException(propsFile.getCanonicalPath() + " does not exist"); - - Properties props = new Properties(); - try (InputStream in = Files.newInputStream(propsFile.toPath())) - { - props.load(in); - } - - String str = props.getProperty("context.path"); + String str = webAppProperties.getProperty(CONTEXT_PATH); if (!StringUtil.isBlank(str)) webApp.setContextPath(str); // - web.xml - str = props.getProperty("web.xml"); + str = webAppProperties.getProperty(WEB_XML); if (!StringUtil.isBlank(str)) webApp.setDescriptor(str); - //TODO the WebAppStarter class doesn't set up the QUICKSTART_CONFIGURATION_CLASSES, but the Starter class does!!! - str = props.getProperty("quickstart.web.xml"); + //if there is a pregenerated quickstart file + str = webAppProperties.getProperty(QUICKSTART_WEB_XML); if (!StringUtil.isBlank(str)) { - webApp.setQuickStartWebDescriptor(Resource.newResource(new File(str))); + webApp.setAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML, Resource.newResource(str)); } // - the tmp directory - str = props.getProperty("tmp.dir"); + str = webAppProperties.getProperty(TMP_DIR); if (!StringUtil.isBlank(str)) webApp.setTempDirectory(new File(str.trim())); - str = props.getProperty("tmp.dir.persist"); + str = webAppProperties.getProperty(TMP_DIR_PERSIST); if (!StringUtil.isBlank(str)) webApp.setPersistTempDirectory(Boolean.valueOf(str)); //Get the calculated base dirs which includes the overlays - str = props.getProperty("base.dirs"); + str = webAppProperties.getProperty(BASE_DIRS); if (!StringUtil.isBlank(str)) { ResourceCollection bases = new ResourceCollection(StringUtil.csvSplit(str)); @@ -208,21 +231,27 @@ public class WebAppPropertyConverter webApp.setBaseResource(bases); } + str = webAppProperties.getProperty(WAR_FILE); + if (!StringUtil.isBlank(str)) + { + webApp.setWar(str); + } + // - the equivalent of web-inf classes - str = props.getProperty("classes.dir"); + str = webAppProperties.getProperty(CLASSES_DIR); if (!StringUtil.isBlank(str)) { webApp.setClasses(new File(str)); } - str = props.getProperty("testClasses.dir"); + str = webAppProperties.getProperty(TEST_CLASSES_DIR); if (!StringUtil.isBlank(str)) { webApp.setTestClasses(new File(str)); } // - the equivalent of web-inf lib - str = props.getProperty("lib.jars"); + str = webAppProperties.getProperty(LIB_JARS); if (!StringUtil.isBlank(str)) { List jars = new ArrayList(); @@ -234,13 +263,31 @@ public class WebAppPropertyConverter webApp.setWebInfLib(jars); } + //any defaults descriptor + str = (String)webAppProperties.getProperty(DEFAULTS_DESCRIPTOR); + if (!StringUtil.isBlank(str)) + { + webApp.setDefaultsDescriptor(str); + } + + //any override descriptors + str = (String)webAppProperties.getProperty(OVERRIDE_DESCRIPTORS); + if (!StringUtil.isBlank(str)) + { + String[] names = StringUtil.csvSplit(str); + for (int j = 0; names != null && j < names.length; j++) + { + webApp.addOverrideDescriptor(names[j]); + } + } + //set up the webapp from the context xml file provided //NOTE: just like jetty:run mojo this means that the context file can //potentially override settings made in the pom. Ideally, we'd like //the pom to override the context xml file, but as the other mojos all //configure a WebAppContext in the pom (the element), it is //already configured by the time the context xml file is applied. - str = props.getProperty("context.xml"); + str = (String)webAppProperties.getProperty(CONTEXT_XML); if (!StringUtil.isBlank(str)) { XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(str)); @@ -256,6 +303,33 @@ public class WebAppPropertyConverter xmlConfiguration.configure(webApp); } } + + /** + * Configure a webapp from a properties file + * @param webApp the webapp to configure + * @param propsFile the properties to apply + * @param server the Server instance to use if there is a context xml file to apply + * @param jettyProperties jetty properties to use if there is a context xml file to apply + * @throws Exception + */ + public static void fromProperties(MavenWebAppContext webApp, File propsFile, Server server, Map jettyProperties) + throws Exception + { + + if (propsFile == null) + throw new IllegalArgumentException("No properties file"); + + if (!propsFile.exists()) + throw new IllegalArgumentException(propsFile.getCanonicalPath() + " does not exist"); + + Properties props = new Properties(); + try (InputStream in = new FileInputStream(propsFile)) + { + props.load(in); + } + + fromProperties(webApp, props, server, jettyProperties); + } /** * Convert an array of Resources to csv file names diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/package-info.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/package-info.java index 8bd40d96c9c..c04b872296e 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/package-info.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/utils/MavenProjectHelper.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/utils/MavenProjectHelper.java index b705500278d..56e026d519b 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/utils/MavenProjectHelper.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/utils/MavenProjectHelper.java @@ -1,73 +1,132 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin.utils; +import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; +import org.eclipse.jetty.maven.plugin.OverlayManager; +import org.eclipse.jetty.maven.plugin.WarPluginInfo; +/** + * MavenProjectHelper + * + * A class to facilitate interacting with the build time maven environment. + * + */ public class MavenProjectHelper { - - private final Map artifactToLocalProjectMap; - - public MavenProjectHelper(MavenProject project) + private MavenProject project; + private ArtifactResolver artifactResolver; + private List remoteRepositories; + private MavenSession session; + private final Map artifactToReactorProjectMap; + /** + * maven-war-plugin reference + */ + private WarPluginInfo warPluginInfo; + + /** + * Helper for wrangling war overlays + */ + private OverlayManager overlayManager; + + /** + * @param project the project being built + * @param artifactResolver a resolve for artifacts + * @param remoteRepositories repositories from which to resolve artifacts + * @param session the current maven build session + */ + public MavenProjectHelper(MavenProject project, ArtifactResolver artifactResolver, List remoteRepositories, MavenSession session) { - Set mavenProjects = resolveProjectDependencies(project, new HashSet<>()); - artifactToLocalProjectMap = mavenProjects.stream() + this.project = project; + this.artifactResolver = artifactResolver; + this.remoteRepositories = remoteRepositories; + this.session = session; + //work out which dependent projects are in the reactor + Set mavenProjects = findDependenciesInReactor(project, new HashSet<>()); + artifactToReactorProjectMap = mavenProjects.stream() .collect(Collectors.toMap(MavenProject::getId, Function.identity())); - artifactToLocalProjectMap.put(project.getArtifact().getId(), project); + artifactToReactorProjectMap.put(project.getArtifact().getId(), project); + warPluginInfo = new WarPluginInfo(project); + overlayManager = new OverlayManager(warPluginInfo); + } + + public MavenProject getProject() + { + return this.project; + } + + public WarPluginInfo getWarPluginInfo() + { + return warPluginInfo; } + public OverlayManager getOverlayManager() + { + return overlayManager; + } + /** - * Gets maven project if referenced in reactor + * Gets the maven project represented by the artifact iff it is in + * the reactor. * - * @param artifact - maven artifact + * @param artifact the artifact of the project to get * @return {@link MavenProject} if artifact is referenced in reactor, otherwise null */ - public MavenProject getMavenProject(Artifact artifact) + public MavenProject getMavenProjectFor(Artifact artifact) { - return artifactToLocalProjectMap.get(artifact.getId()); + return artifactToReactorProjectMap.get(artifact.getId()); } /** * Gets path to artifact. - * If artifact is referenced in reactor, returns path to ${project.build.outputDirectory}. + * If the artifact is referenced in the reactor, returns path to ${project.build.outputDirectory}. * Otherwise, returns path to location in local m2 repo. * - * Cannot return null - maven will complain about unsatisfied dependency during project built. + * Cannot return null - maven will complain about unsatisfied dependency during project build. * - * @param artifact maven artifact + * @param artifact maven artifact to check * @return path to artifact */ - public Path getArtifactPath(Artifact artifact) + public Path getPathFor(Artifact artifact) { Path path = artifact.getFile().toPath(); - MavenProject mavenProject = getMavenProject(artifact); + MavenProject mavenProject = getMavenProjectFor(artifact); if (mavenProject != null) { if ("test-jar".equals(artifact.getType())) @@ -81,18 +140,57 @@ public class MavenProjectHelper } return path; } + + /** + * Given the coordinates for an artifact, resolve the artifact from the + * remote repositories. + * + * @param groupId the groupId of the artifact to resolve + * @param artifactId the artifactId of the artifact to resolve + * @param version the version of the artifact to resolve + * @param type the type of the artifact to resolve + * @return a File representing the location of the artifact or null if not resolved + * @throws ArtifactResolverException + */ + public File resolveArtifact(String groupId, String artifactId, String version, String type) + throws ArtifactResolverException + { + DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); + coordinate.setGroupId(groupId); + coordinate.setArtifactId(artifactId); + coordinate.setVersion(version); + coordinate.setExtension(type); - private static Set resolveProjectDependencies(MavenProject project, Set visitedProjects) + ProjectBuildingRequest buildingRequest = + new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); + + buildingRequest.setRemoteRepositories(remoteRepositories); + + Artifact a = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); + + if (a != null) + return a.getFile(); + return null; + } + + /** + * Recursively find projects in the reactor for all dependencies of the given project. + * + * @param project the project for which to find dependencies that are in the reactor + * @param visitedProjects the set of projects already seen + * @return unified set of all related projects in the reactor + */ + private static Set findDependenciesInReactor(MavenProject project, Set visitedProjects) { if (visitedProjects.contains(project)) - { return Collections.emptySet(); - } + visitedProjects.add(project); - Set availableProjects = new HashSet<>(project.getProjectReferences().values()); - for (MavenProject ref : project.getProjectReferences().values()) + Collection refs = project.getProjectReferences().values(); + Set availableProjects = new HashSet<>(refs); + for (MavenProject ref : refs) { - availableProjects.addAll(resolveProjectDependencies(ref, visitedProjects)); + availableProjects.addAll(findDependenciesInReactor(ref, visitedProjects)); } return availableProjects; } diff --git a/jetty-maven-plugin/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration b/jetty-maven-plugin/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration index e61fe50a422..b762a0f739d 100644 --- a/jetty-maven-plugin/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration +++ b/jetty-maven-plugin/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration @@ -1,2 +1,4 @@ org.eclipse.jetty.maven.plugin.MavenWebInfConfiguration -org.eclipse.jetty.maven.plugin.MavenMetaInfConfiguration \ No newline at end of file +org.eclipse.jetty.maven.plugin.MavenMetaInfConfiguration +#Do not list this because Quickstart is not present for distro +#org.eclipse.jetty.maven.plugin.MavenQuickStartConfiguration diff --git a/jetty-maven-plugin/src/main/resources/jetty-maven.xml b/jetty-maven-plugin/src/main/resources/jetty-maven.xml index 8ee79fbec55..47d10a84d4f 100644 --- a/jetty-maven-plugin/src/main/resources/jetty-maven.xml +++ b/jetty-maven-plugin/src/main/resources/jetty-maven.xml @@ -2,7 +2,7 @@ - + diff --git a/jetty-maven-plugin/src/main/resources/maven.xml b/jetty-maven-plugin/src/main/resources/maven.xml index b477d77edee..36dec030c94 100644 --- a/jetty-maven-plugin/src/main/resources/maven.xml +++ b/jetty-maven-plugin/src/main/resources/maven.xml @@ -1,12 +1,16 @@ - + - + + + /etc/maven.props - + + + diff --git a/jetty-maven-plugin/src/site/markdown/index.md b/jetty-maven-plugin/src/site/markdown/index.md new file mode 100644 index 00000000000..9cddd436d39 --- /dev/null +++ b/jetty-maven-plugin/src/site/markdown/index.md @@ -0,0 +1,10 @@ +Eclipse Jetty Maven Plugin +======================== + +The Jetty Maven plugin is useful for rapid development and testing. + +You can add it to any webapp project that is structured according to the Maven defaults. + +The plugin can then periodically scan your project for changes and automatically redeploy the webapp if any are found. + +This makes the development cycle more productive by eliminating the build and deploy steps: you use your IDE to make changes to the project, and the running web container automatically picks them up, allowing you to test them straight away. diff --git a/jetty-maven-plugin/src/site/site.xml b/jetty-maven-plugin/src/site/site.xml new file mode 100644 index 00000000000..d37c6e5f9dc --- /dev/null +++ b/jetty-maven-plugin/src/site/site.xml @@ -0,0 +1,44 @@ + + + + + + ${project.name} + https://www.eclipse.org/jetty/images/jetty-logo-80x22.png + https://eclipse.org/jetty/ + + + https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-426x100.png + + + + org.apache.maven.skins + maven-fluido-skin + 1.7 + + + + + true + true + + ${project.url} + + + eclipse/jetty.project + right + gray + + + + + +

      + + + + + + diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestForkedChild.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestForkedChild.java new file mode 100644 index 00000000000..8696223f210 --- /dev/null +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestForkedChild.java @@ -0,0 +1,183 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.Socket; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Random; + +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.resource.Resource; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Test the JettyForkedChild class, which + * is the main that is executed by jetty:run/start in mode FORKED. + */ +public class TestForkedChild +{ + File testDir; + File baseDir; + File tmpDir; + File tokenFile; + File webappPropsFile; + int stopPort; + String stopKey = "FERMATI"; + String jettyPortString; + int jettyPort; + String token; + JettyForkedChild child; + Thread starter; + JettyRunner runner = new JettyRunner(); + + public class JettyRunner implements Runnable + { + @Override + public void run() + { + try + { + List cmd = new ArrayList(); + cmd.add("--stop-port"); + cmd.add(String.valueOf(stopPort)); + cmd.add("--stop-key"); + cmd.add(stopKey); + cmd.add("--webprops"); + cmd.add(webappPropsFile.getAbsolutePath()); + cmd.add("--token"); + cmd.add(tokenFile.getAbsolutePath()); + + MavenWebAppContext webapp = new MavenWebAppContext(); + webapp.setContextPath("/foo"); + webapp.setTempDirectory(tmpDir); + webapp.setBaseResource(Resource.newResource(baseDir)); + WebAppPropertyConverter.toProperties(webapp, webappPropsFile, null); + child = new JettyForkedChild(cmd.toArray(new String[cmd.size()])); + child.jetty.setExitVm(false); //ensure jetty doesn't stop vm for testing + child.start(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + } + + @BeforeEach + public void setUp() + { + baseDir = MavenTestingUtils.getTestResourceDir("root"); + testDir = MavenTestingUtils.getTargetTestingDir("forkedChild"); + if (testDir.exists()) + FS.delete(testDir); + testDir.mkdirs(); + tmpDir = new File(testDir, "tmp"); + webappPropsFile = new File(testDir, "webapp.props"); + + String stopPortString = System.getProperty("stop.port"); + assertNotNull(stopPortString, "stop.port System property"); + stopPort = Integer.valueOf(stopPortString); + jettyPortString = System.getProperty("jetty.port"); + assertNotNull(jettyPortString, "jetty.port System property"); + jettyPort = Integer.valueOf(jettyPortString); + + Random random = new Random(); + token = Long.toString(random.nextLong() ^ System.currentTimeMillis(), 36).toUpperCase(Locale.ENGLISH); + tokenFile = testDir.toPath().resolve(token + ".txt").toFile(); + } + + @AfterEach + public void tearDown() throws Exception + { + String command = "forcestop"; + + try (Socket s = new Socket(InetAddress.getByName("127.0.0.1"), stopPort);) + { + OutputStream out = s.getOutputStream(); + out.write((stopKey + "\r\n" + command + "\r\n").getBytes()); + out.flush(); + + s.setSoTimeout(1000); + s.getInputStream(); + + LineNumberReader lin = new LineNumberReader(new InputStreamReader(s.getInputStream())); + String response; + boolean stopped = false; + while (!stopped && ((response = lin.readLine()) != null)) + { + if ("Stopped".equals(response)) + { + stopped = true; + } + } + } + } + + @Test + public void test() throws Exception + { + starter = new Thread(runner, "JettyForkedChild"); + starter.start(); + + //wait for the token file to be created + int attempts = 20; + while (!tokenFile.exists() && attempts > 0) + { + Thread.currentThread().sleep(500); + --attempts; + } + assertThat(attempts, Matchers.greaterThan(0)); + + URL url = new URL("http://localhost:" + jettyPortString + "/foo/"); + HttpURLConnection connection = null; + + try + { + connection = (HttpURLConnection)url.openConnection(); + connection.connect(); + assertThat(connection.getResponseCode(), Matchers.is(200)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + IO.copy(connection.getInputStream(), baos); + assertThat(baos.toString(), Matchers.containsString("ROOT")); + } + finally + { + if (connection != null) + connection.disconnect(); + } + } +} diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyEmbedder.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyEmbedder.java new file mode 100644 index 00000000000..0f220b1cf3e --- /dev/null +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyEmbedder.java @@ -0,0 +1,120 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.Resource; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestJettyEmbedder +{ + + @Test + public void testJettyEmbedderFromDefaults() throws Exception + { + MavenWebAppContext webApp = new MavenWebAppContext(); + MavenServerConnector connector = new MavenServerConnector(); + connector.setPort(0); + + JettyEmbedder jetty = new JettyEmbedder(); + jetty.setHttpConnector(connector); + jetty.setExitVm(false); + jetty.setServer(null); + jetty.setContextHandlers(null); + jetty.setRequestLog(null); + jetty.setJettyXmlFiles(null); + jetty.setJettyProperties(null); + jetty.setLoginServices(null); + jetty.setContextXml(MavenTestingUtils.getTestResourceFile("embedder-context.xml").getAbsolutePath()); + jetty.setWebApp(webApp); + + try + { + jetty.start(); + assertEquals("/embedder", webApp.getContextPath()); + assertTrue(webApp.isStarted()); + assertNotNull(jetty.getServer()); + assertTrue(jetty.getServer().isStarted()); + assertNotNull(jetty.getServer().getConnectors()); + assertNotNull(ServerSupport.findContextHandlerCollection(jetty.getServer())); + } + finally + { + jetty.stop(); + } + } + + @Test + public void testJettyEmbedder() + throws Exception + { + MavenWebAppContext webApp = new MavenWebAppContext(); + Server server = new Server(); + Map jettyProperties = new HashMap<>(); + jettyProperties.put("jetty.server.dumpAfterStart", "false"); + + ContextHandler otherHandler = new ContextHandler(); + otherHandler.setContextPath("/other"); + otherHandler.setBaseResource(Resource.newResource(MavenTestingUtils.getTestResourceDir("root"))); + + MavenServerConnector connector = new MavenServerConnector(); + connector.setPort(0); + + JettyEmbedder jetty = new JettyEmbedder(); + jetty.setHttpConnector(connector); + jetty.setExitVm(false); + jetty.setServer(server); + jetty.setContextHandlers(Arrays.asList(otherHandler)); + jetty.setRequestLog(null); + jetty.setJettyXmlFiles(Arrays.asList(MavenTestingUtils.getTestResourceFile("embedder-jetty.xml"))); + jetty.setJettyProperties(jettyProperties); + jetty.setLoginServices(null); + jetty.setContextXml(MavenTestingUtils.getTestResourceFile("embedder-context.xml").getAbsolutePath()); + jetty.setWebApp(webApp); + + try + { + jetty.start(); + assertEquals("/embedder", webApp.getContextPath()); + assertTrue(webApp.isStarted()); + assertNotNull(jetty.getServer()); + assertTrue(jetty.getServer().isStarted()); + assertNotNull(jetty.getServer().getConnectors()); + ContextHandlerCollection contexts = ServerSupport.findContextHandlerCollection(jetty.getServer()); + assertNotNull(contexts); + assertTrue(contexts.contains(otherHandler)); + assertTrue(contexts.contains(webApp)); + } + finally + { + jetty.stop(); + } + } +} diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestQuickStartGenerator.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestQuickStartGenerator.java new file mode 100644 index 00000000000..5321d2dfb07 --- /dev/null +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestQuickStartGenerator.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.Resource; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * + * + */ +public class TestQuickStartGenerator +{ + @Test + public void testGenerator() throws Exception + { + MavenWebAppContext webApp = new MavenWebAppContext(); + webApp.setContextPath("/shouldbeoverridden"); + webApp.setBaseResource(Resource.newResource(MavenTestingUtils.getTestResourceDir("root"))); + File quickstartFile = new File(MavenTestingUtils.getTargetTestingDir(), "quickstart-web.xml"); + QuickStartGenerator generator = new QuickStartGenerator(quickstartFile, webApp); + generator.setContextXml(MavenTestingUtils.getTestResourceFile("embedder-context.xml").getAbsolutePath()); + generator.setServer(new Server()); + MavenTestingUtils.getTargetTestingDir().mkdirs(); + File propsFile = new File(MavenTestingUtils.getTargetTestingDir(), "webapp.props"); + propsFile.createNewFile(); + generator.setWebAppPropsFile(propsFile); + generator.generate(); + assertTrue(propsFile.exists()); + assertTrue(propsFile.length() > 0); + assertTrue(quickstartFile.exists()); + assertTrue(quickstartFile.length() > 0); + } +} diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestSelectiveJarResource.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestSelectiveJarResource.java new file mode 100644 index 00000000000..ce7fdfa61bb --- /dev/null +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestSelectiveJarResource.java @@ -0,0 +1,130 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.net.URL; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.Resource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * + * + */ +public class TestSelectiveJarResource +{ + File unpackParent; + + @BeforeEach + public void setUp() throws Exception + { + unpackParent = MavenTestingUtils.getTargetTestingDir("selective-jar-resource"); + unpackParent.mkdirs(); + } + + @Test + public void testIncludesNoExcludes() throws Exception + { + File unpackDir = File.createTempFile("inc", "exc", unpackParent); + unpackDir.delete(); + unpackDir.mkdirs(); + + File testJar = MavenTestingUtils.getTestResourceFile("selective-jar-test.jar"); + try (SelectiveJarResource sjr = new SelectiveJarResource(new URL("jar:" + Resource.toURL(testJar).toString() + "!/"));) + { + sjr.setCaseSensitive(false); + List includes = new ArrayList<>(); + includes.add("**/*.html"); + sjr.setIncludes(includes); + sjr.copyTo(unpackDir); + assertTrue(Files.exists(unpackDir.toPath().resolve("top.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("aa/a1.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("aa/a2.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("aa/deep/a3.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("bb/b1.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("bb/b2.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("cc/c1.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("cc/c2.html"))); + } + } + + @Test + public void testExcludesNoIncludes() throws Exception + { + File unpackDir = File.createTempFile("exc", "inc", unpackParent); + unpackDir.delete(); + unpackDir.mkdirs(); + File testJar = MavenTestingUtils.getTestResourceFile("selective-jar-test.jar"); + + try (SelectiveJarResource sjr = new SelectiveJarResource(new URL("jar:" + Resource.toURL(testJar).toString() + "!/"));) + { + sjr.setCaseSensitive(false); + List excludes = new ArrayList<>(); + excludes.add("**/*"); + sjr.setExcludes(excludes); + sjr.copyTo(unpackDir); + assertFalse(Files.exists(unpackDir.toPath().resolve("top.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("aa/a1.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("aa/a2.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("aa/deep/a3.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("bb/b1.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("bb/b2.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("cc/c1.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("cc/c2.html"))); + } + } + + @Test + public void testIncludesExcludes() throws Exception + { + File unpackDir = File.createTempFile("exc", "andinc", unpackParent); + unpackDir.delete(); + unpackDir.mkdirs(); + File testJar = MavenTestingUtils.getTestResourceFile("selective-jar-test.jar"); + + try (SelectiveJarResource sjr = new SelectiveJarResource(new URL("jar:" + Resource.toURL(testJar).toString() + "!/"));) + { + sjr.setCaseSensitive(false); + List excludes = new ArrayList<>(); + excludes.add("**/deep/*"); + sjr.setExcludes(excludes); + List includes = new ArrayList<>(); + includes.add("bb/*"); + sjr.setIncludes(includes); + sjr.copyTo(unpackDir); + assertFalse(Files.exists(unpackDir.toPath().resolve("top.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("aa/a1.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("aa/a2.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("aa/deep/a3.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("bb/b1.html"))); + assertTrue(Files.exists(unpackDir.toPath().resolve("bb/b2.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("cc/c1.html"))); + assertFalse(Files.exists(unpackDir.toPath().resolve("cc/c2.html"))); + } + } +} diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestWebAppPropertyConverter.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestWebAppPropertyConverter.java new file mode 100644 index 00000000000..9b238d2647f --- /dev/null +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestWebAppPropertyConverter.java @@ -0,0 +1,160 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.maven.plugin; + +import java.io.File; +import java.io.FileInputStream; +import java.util.Arrays; +import java.util.Properties; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceCollection; +import org.eclipse.jetty.webapp.WebAppContext; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestWebAppPropertyConverter +{ + static File testDir; + static String contextXml; + static File tmpDir; + static File classesDir; + static File testClassesDir; + static File jar1; + static File jar2; + static File war; + static File override1; + static File override2; + static File webXml; + + @BeforeAll + public static void setUp() throws Exception + { + testDir = MavenTestingUtils.getTargetTestingDir("TestWebApPropertyConverter"); + testDir.mkdirs(); + contextXml = MavenTestingUtils.getTestResourceFile("embedder-context.xml").getAbsolutePath(); + tmpDir = new File(testDir, "testToProperties"); + tmpDir.mkdirs(); + classesDir = new File(testDir, "imaginaryClasses"); + classesDir.mkdirs(); + testClassesDir = new File(testDir, "imaginaryTestClasses"); + testClassesDir.mkdirs(); + jar1 = new File(testDir, "imaginary1.jar"); + jar1.createNewFile(); + jar2 = new File(testDir, "imaginary2.jar"); + jar2.createNewFile(); + war = new File(testDir, "imaginary.war"); + war.createNewFile(); + override1 = new File(testDir, "override-web1.xml"); + override1.createNewFile(); + override2 = new File(testDir, "override-web2.xml"); + override2.createNewFile(); + webXml = new File(testDir, "web.xml"); + webXml.createNewFile(); + } + + @AfterAll + public static void tearDown() throws Exception + { + IO.delete(testDir); + } + + @Test + public void testToProperties() throws Exception + { + File propsFile = new File(testDir, "webapp.props"); + if (propsFile.exists()) + propsFile.delete(); + propsFile.createNewFile(); + + MavenWebAppContext webApp = new MavenWebAppContext(); + webApp.setContextPath("/foo"); + webApp.setBaseResource(Resource.newResource(MavenTestingUtils.getTestResourceDir("root"))); + webApp.setTempDirectory(tmpDir); + webApp.setPersistTempDirectory(false); + webApp.setClasses(classesDir); + webApp.setTestClasses(testClassesDir); + webApp.setWebInfLib(Arrays.asList(jar1, jar2)); + webApp.setWar(war.getAbsolutePath()); + webApp.addOverrideDescriptor(override1.getAbsolutePath()); + webApp.addOverrideDescriptor(override2.getAbsolutePath()); + WebAppPropertyConverter.toProperties(webApp, propsFile, contextXml); + + assertTrue(propsFile.exists()); + Properties props = new Properties(); + props.load(new FileInputStream(propsFile)); + assertEquals("/foo", props.get(WebAppPropertyConverter.CONTEXT_PATH)); + assertEquals(contextXml, props.get(WebAppPropertyConverter.CONTEXT_XML)); + assertEquals(tmpDir.getAbsolutePath(), props.get(WebAppPropertyConverter.TMP_DIR)); + assertEquals("false", props.get(WebAppPropertyConverter.TMP_DIR_PERSIST)); + assertEquals(classesDir.getAbsolutePath(), props.get(WebAppPropertyConverter.CLASSES_DIR)); + assertEquals(testClassesDir.getAbsolutePath(), props.get(WebAppPropertyConverter.TEST_CLASSES_DIR)); + assertEquals(String.join(",", jar1.getAbsolutePath(),jar2.getAbsolutePath()), props.get(WebAppPropertyConverter.LIB_JARS)); + assertEquals(war.getAbsolutePath(), props.get(WebAppPropertyConverter.WAR_FILE)); + assertEquals(WebAppContext.WEB_DEFAULTS_XML, props.get(WebAppPropertyConverter.DEFAULTS_DESCRIPTOR)); + assertEquals(String.join(",", override1.getAbsolutePath(), override2.getAbsolutePath()), props.get(WebAppPropertyConverter.OVERRIDE_DESCRIPTORS)); + } + + @Test + public void testFromProperties() throws Exception + { + File base1 = new File(testDir, "base1"); + base1.mkdirs(); + File base2 = new File(testDir, "base2"); + base2.mkdirs(); + MavenWebAppContext webApp = new MavenWebAppContext(); + Properties props = new Properties(); + props.setProperty(WebAppPropertyConverter.BASE_DIRS, String.join(",", base1.getAbsolutePath(), base2.getAbsolutePath())); + props.setProperty(WebAppPropertyConverter.CLASSES_DIR, classesDir.getAbsolutePath()); + props.setProperty(WebAppPropertyConverter.CONTEXT_PATH, "/foo"); + props.setProperty(WebAppPropertyConverter.CONTEXT_XML, contextXml); + props.setProperty(WebAppPropertyConverter.LIB_JARS, String.join(",", jar1.getAbsolutePath(),jar2.getAbsolutePath())); + props.setProperty(WebAppPropertyConverter.OVERRIDE_DESCRIPTORS, String.join(",", override1.getAbsolutePath(), override2.getAbsolutePath())); + //props.setProperty(WebAppPropertyConverter.QUICKSTART_WEB_XML, value); + props.setProperty(WebAppPropertyConverter.TEST_CLASSES_DIR, testClassesDir.getAbsolutePath()); + props.setProperty(WebAppPropertyConverter.TMP_DIR, tmpDir.getAbsolutePath()); + props.setProperty(WebAppPropertyConverter.TMP_DIR_PERSIST, "true"); + props.setProperty(WebAppPropertyConverter.WAR_FILE, war.getAbsolutePath()); + props.setProperty(WebAppPropertyConverter.WEB_XML, webXml.getAbsolutePath()); + WebAppPropertyConverter.fromProperties(webApp, props, new Server(), null); + + assertEquals("/embedder", webApp.getContextPath()); //the embedder-context file changes the context path + assertEquals(classesDir, webApp.getClasses()); + assertEquals(testClassesDir, webApp.getTestClasses()); + assertThat(webApp.getWebInfLib(), Matchers.contains(jar1, jar2)); + assertThat(webApp.getOverrideDescriptors(), Matchers.contains(override1.getAbsolutePath(), override2.getAbsolutePath())); + assertEquals(tmpDir, webApp.getTempDirectory()); + assertEquals(true, webApp.isPersistTempDirectory()); + assertEquals(war.getAbsolutePath(), webApp.getWar()); + assertEquals(webXml.getAbsolutePath(), webApp.getDescriptor()); + assertThat(webApp.getBaseResource(), instanceOf(ResourceCollection.class)); + assertThat(webApp.getBaseResource().toString(), Matchers.containsString(Resource.newResource(base1).toString())); + assertThat(webApp.getBaseResource().toString(), Matchers.containsString(Resource.newResource(base2).toString())); + } +} diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/IntegrationTestGetContent.java similarity index 65% rename from jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java rename to jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/IntegrationTestGetContent.java index 2a09f98bc73..7ee511214ed 100644 --- a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/IntegrationTestGetContent.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.maven.plugin.it; @@ -32,17 +32,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -/** - * - */ -public class TestGetContent +public class IntegrationTestGetContent { @Test - public void get_content_response() + public void getContentResponse() throws Exception { int port = getPort(); assertTrue(port > 0); + String contextPath = getContextPath(); + if (contextPath.endsWith("/")) + contextPath = contextPath.substring(0, contextPath.lastIndexOf('/')); + HttpClient httpClient = new HttpClient(); try { @@ -50,16 +51,16 @@ public class TestGetContent if (Boolean.getBoolean("helloServlet")) { - String response = httpClient.GET("http://localhost:" + port + "/hello?name=beer").getContentAsString(); + String response = httpClient.GET("http://localhost:" + port + contextPath + "/hello?name=beer").getContentAsString(); assertEquals("Hello beer", response.trim(), "it test " + System.getProperty("maven.it.name")); - response = httpClient.GET("http://localhost:" + port + "/hello?name=foo").getContentAsString(); + response = httpClient.GET("http://localhost:" + port + contextPath + "/hello?name=foo").getContentAsString(); assertEquals("Hello foo", response.trim(), "it test " + System.getProperty("maven.it.name")); System.out.println("helloServlet"); } if (Boolean.getBoolean("pingServlet")) { System.out.println("pingServlet"); - String response = httpClient.GET("http://localhost:" + port + "/ping?name=beer").getContentAsString(); + String response = httpClient.GET("http://localhost:" + port + contextPath + "/ping?name=beer").getContentAsString(); assertEquals("pong beer", response.trim(), "it test " + System.getProperty("maven.it.name")); System.out.println("pingServlet ok"); } @@ -67,21 +68,21 @@ public class TestGetContent String pathToCheck = System.getProperty("pathToCheck"); if (StringUtils.isNotBlank(contentCheck)) { - String url = "http://localhost:" + port; + String url = "http://localhost:" + port + contextPath; if (pathToCheck != null) { url += pathToCheck; } String response = httpClient.GET(url).getContentAsString(); - assertTrue(response.contains(contentCheck), "it test " + System.getProperty("maven.it.name") - + ", response not contentCheck: " + contentCheck + ", response:" + response); + assertTrue(response.contains(contentCheck), "it test " + System.getProperty("maven.it.name") + + ", response not contentCheck: " + contentCheck + ", response:" + response); System.out.println("contentCheck"); } if (Boolean.getBoolean("helloTestServlet")) { - String response = httpClient.GET("http://localhost:" + port + "/testhello?name=beer").getContentAsString(); + String response = httpClient.GET("http://localhost:" + port + contextPath + "/testhello?name=beer").getContentAsString(); assertEquals("Hello from test beer", response.trim(), "it test " + System.getProperty("maven.it.name")); - response = httpClient.GET("http://localhost:" + port + "/testhello?name=foo").getContentAsString(); + response = httpClient.GET("http://localhost:" + port + contextPath + "/testhello?name=foo").getContentAsString(); assertEquals("Hello from test foo", response.trim(), "it test " + System.getProperty("maven.it.name")); System.out.println("helloServlet"); } @@ -92,14 +93,20 @@ public class TestGetContent } } + public static String getContextPath() + { + return System.getProperty("context.path", "/"); + } + public static int getPort() throws Exception { int attempts = 70; int port = -1; String s = System.getProperty("jetty.port.file"); - assertNotNull(s); + assertNotNull(s, "jetty.port.file System property"); Path p = Paths.get(s); + System.err.println("Looking for port file: " + p); while (true) { if (Files.exists(p)) @@ -121,8 +128,9 @@ public class TestGetContent } else { - Thread.currentThread().sleep(1000); + Thread.sleep(1000); } + System.err.printf(" attempts left: #%d%n", attempts); } } return port; diff --git a/jetty-maven-plugin/src/test/resources/embedder-context.xml b/jetty-maven-plugin/src/test/resources/embedder-context.xml new file mode 100644 index 00000000000..c13affca5e7 --- /dev/null +++ b/jetty-maven-plugin/src/test/resources/embedder-context.xml @@ -0,0 +1,6 @@ + + + + + /embedder + diff --git a/jetty-maven-plugin/src/test/resources/embedder-jetty.xml b/jetty-maven-plugin/src/test/resources/embedder-jetty.xml new file mode 100644 index 00000000000..85ae556bdda --- /dev/null +++ b/jetty-maven-plugin/src/test/resources/embedder-jetty.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-maven-plugin/src/test/resources/root/index.html b/jetty-maven-plugin/src/test/resources/root/index.html new file mode 100644 index 00000000000..e8d4c65dd0d --- /dev/null +++ b/jetty-maven-plugin/src/test/resources/root/index.html @@ -0,0 +1 @@ +

      ROOT

      \ No newline at end of file diff --git a/jetty-maven-plugin/src/test/resources/selective-jar-test.jar b/jetty-maven-plugin/src/test/resources/selective-jar-test.jar new file mode 100644 index 00000000000..dc7dc4b596c Binary files /dev/null and b/jetty-maven-plugin/src/test/resources/selective-jar-test.jar differ diff --git a/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod b/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod index 77a21ea759f..017c004f4b9 100644 --- a/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod +++ b/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod @@ -8,7 +8,7 @@ session [depends] session-store -slf4j-api +logging/slf4j [files] maven://com.googlecode.xmemcached/xmemcached/2.4.5|lib/xmemcached/xmemcached-2.4.5.jar diff --git a/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java b/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java index 2198a822934..1c7900462f3 100644 --- a/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java +++ b/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.memcached.session; diff --git a/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMapFactory.java b/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMapFactory.java index c1714bd7e87..e04ca05a327 100644 --- a/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMapFactory.java +++ b/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMapFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.memcached.session; @@ -83,9 +83,6 @@ public class MemcachedSessionDataMapFactory implements SessionDataMapFactory _heartbeats = heartbeats; } - /** - * @see org.eclipse.jetty.server.session.SessionDataMapFactory#getSessionDataMap() - */ @Override public SessionDataMap getSessionDataMap() { diff --git a/jetty-memcached/jetty-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/session/TestMemcachedSessions.java b/jetty-memcached/jetty-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/session/TestMemcachedSessions.java index ffc3d8d68f8..9debffeb235 100644 --- a/jetty-memcached/jetty-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/session/TestMemcachedSessions.java +++ b/jetty-memcached/jetty-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/session/TestMemcachedSessions.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.memcached.session; @@ -31,12 +31,9 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.session.AbstractSessionCache; import org.eclipse.jetty.server.session.CachingSessionDataStore; +import org.eclipse.jetty.server.session.NullSessionCache; import org.eclipse.jetty.server.session.NullSessionDataStore; -import org.eclipse.jetty.server.session.Session; -import org.eclipse.jetty.server.session.SessionData; -import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.junit.jupiter.api.Test; @@ -88,56 +85,6 @@ public class TestMemcachedSessions } } - public static class NullSessionCache extends AbstractSessionCache - { - - public NullSessionCache(SessionHandler handler) - { - super(handler); - } - - @Override - public void shutdown() - { - } - - @Override - public Session newSession(SessionData data) - { - return new Session(_handler, data); - } - - @Override - public Session newSession(HttpServletRequest request, SessionData data) - { - return new Session(_handler, request, data); - } - - @Override - public Session doGet(String id) - { - return null; - } - - @Override - public Session doPutIfAbsent(String id, Session session) - { - return null; - } - - @Override - public boolean doReplace(String id, Session oldValue, Session newValue) - { - return true; - } - - @Override - public Session doDelete(String id) - { - return null; - } - } - @Test public void testMemcached() throws Exception { diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 1d3f099c606..af03a0f479c 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -21,11 +21,6 @@ jetty-server ${project.version} - - org.eclipse.jetty.toolchain - jetty-test-helper - test - org.eclipse.jetty jetty-jmx @@ -39,6 +34,20 @@ jar compile + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + org.eclipse.jetty.tests test-sessions-common diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java index e9536d4fd28..b8c20b0145f 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql; diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java index a097fc68c57..b72d7fbca7f 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; @@ -43,8 +43,8 @@ import org.eclipse.jetty.util.ClassLoadingObjectInputStream; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MongoSessionDataStore @@ -97,7 +97,7 @@ import org.eclipse.jetty.util.log.Logger; public class MongoSessionDataStore extends NoSqlSessionDataStore { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(MongoSessionDataStore.class); /** * Special attribute for a session that is context-specific diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreFactory.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreFactory.java index c0c8696301b..5423b8129fe 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreFactory.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java index 94de6c5785c..fb29105e870 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/package-info.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/package-info.java index 69443e75abe..b29477faf96 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/package-info.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/package-info.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/package-info.java index d92cfa5d36d..bc3914d3b83 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/package-info.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-openid/pom.xml b/jetty-openid/pom.xml new file mode 100644 index 00000000000..14106194db4 --- /dev/null +++ b/jetty-openid/pom.xml @@ -0,0 +1,90 @@ + + + org.eclipse.jetty + jetty-project + 10.0.0-SNAPSHOT + + + 4.0.0 + jetty-openid + Jetty :: OpenID + Jetty OpenID Connect infrastructure + http://www.eclipse.org/jetty + + + ${project.groupId}.openid + + + + + + org.codehaus.mojo + findbugs-maven-plugin + + org.eclipse.jetty.security.openid.* + + + + org.apache.felix + maven-bundle-plugin + true + + + + manifest + + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory + + + + + + + + + + + org.eclipse.jetty + jetty-server + ${project.version} + + + org.eclipse.jetty + jetty-client + ${project.version} + + + org.eclipse.jetty + jetty-security + ${project.version} + + + org.eclipse.jetty + jetty-util-ajax + ${project.version} + + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + org.eclipse.jetty + jetty-servlet + ${project.version} + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + diff --git a/jetty-openid/src/main/config/etc/jetty-openid.xml b/jetty-openid/src/main/config/etc/jetty-openid.xml new file mode 100644 index 00000000000..5072c160495 --- /dev/null +++ b/jetty-openid/src/main/config/etc/jetty-openid.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jetty-openid/src/main/config/modules/openid.mod b/jetty-openid/src/main/config/modules/openid.mod new file mode 100644 index 00000000000..77ea5c35e6e --- /dev/null +++ b/jetty-openid/src/main/config/modules/openid.mod @@ -0,0 +1,44 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Adds OpenId Connect authentication. + +[depend] +security +client + +[lib] +lib/jetty-openid-${jetty.version}.jar +lib/jetty-util-ajax-${jetty.version}.jar + +[files] +basehome:modules/openid/openid-baseloginservice.xml|etc/openid-baseloginservice.xml + +[xml] +etc/openid-baseloginservice.xml +etc/jetty-openid.xml + +[ini-template] +## The OpenID Identity Provider's issuer ID (the entire URL *before* ".well-known/openid-configuration") +# jetty.openid.provider=https://id.example.com/~ + +## The OpenID Identity Provider's authorization endpoint (optional if the metadata of the OP is accessible) +# jetty.openid.provider.authorizationEndpoint=https://id.example.com/authorization + +## The OpenID Identity Provider's token endpoint (optional if the metadata of the OP is accessible) +# jetty.openid.provider.tokenEndpoint=https://id.example.com/token + +## The Client Identifier +# jetty.openid.clientId=test1234 + +## The Client Secret +# jetty.openid.clientSecret=XT_Mafv_aUCGheuCaKY8P + +## Additional Scopes to Request +# jetty.openid.scopes=email,profile + +## Whether to Authenticate users not found by base LoginService +# jetty.openid.authenticateNewUsers=false + +## True if all certificates should be trusted by the default SslContextFactory +# jetty.openid.sslContextFactory.trustAll=false \ No newline at end of file diff --git a/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml b/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml new file mode 100644 index 00000000000..1773ebd46db --- /dev/null +++ b/jetty-openid/src/main/config/modules/openid/openid-baseloginservice.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/JwtDecoder.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/JwtDecoder.java new file mode 100644 index 00000000000..2ce4ababc8c --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/JwtDecoder.java @@ -0,0 +1,106 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; +import java.util.Map; + +import org.eclipse.jetty.util.ajax.JSON; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Used to decode the ID Token from the base64 encrypted JSON Web Token (JWT). + */ +public class JwtDecoder +{ + private static final Logger LOG = LoggerFactory.getLogger(JwtDecoder.class); + + /** + * Decodes a JSON Web Token (JWT) into a Map of claims. + * + * @param jwt the JWT to decode. + * @return the map of claims encoded in the JWT. + */ + public static Map decode(String jwt) + { + if (LOG.isDebugEnabled()) + LOG.debug("decode {}", jwt); + + String[] sections = jwt.split("\\."); + if (sections.length != 3) + throw new IllegalArgumentException("JWT does not contain 3 sections"); + + Base64.Decoder decoder = Base64.getUrlDecoder(); + String jwtHeaderString = new String(decoder.decode(padJWTSection(sections[0])), StandardCharsets.UTF_8); + String jwtClaimString = new String(decoder.decode(padJWTSection(sections[1])), StandardCharsets.UTF_8); + String jwtSignature = sections[2]; + + JSON json = new JSON(); + + Object parsedJwtHeader = json.fromJSON(jwtHeaderString); + if (!(parsedJwtHeader instanceof Map)) + throw new IllegalStateException("Invalid JWT header"); + @SuppressWarnings("unchecked") + Map jwtHeader = (Map)parsedJwtHeader; + if (LOG.isDebugEnabled()) + LOG.debug("JWT Header: {}", jwtHeader); + + /* If the ID Token is received via direct communication between the Client + and the Token Endpoint (which it is in this flow), the TLS server validation + MAY be used to validate the issuer in place of checking the token signature. */ + if (LOG.isDebugEnabled()) + LOG.debug("JWT signature not validated {}", jwtSignature); + + Object parsedClaims = json.fromJSON(jwtClaimString); + if (!(parsedClaims instanceof Map)) + throw new IllegalStateException("Could not decode JSON for JWT claims."); + return (Map)parsedClaims; + } + + static byte[] padJWTSection(String unpaddedEncodedJwtSection) + { + // If already padded just use what we are given. + if (unpaddedEncodedJwtSection.endsWith("=")) + return unpaddedEncodedJwtSection.getBytes(); + + int length = unpaddedEncodedJwtSection.length(); + int remainder = length % 4; + + // A valid base-64-encoded string will have a remainder of 0, 2 or 3. Never 1! + if (remainder == 1) + throw new IllegalArgumentException("Not a valid Base64-encoded string"); + + byte[] paddedEncodedJwtSection; + if (remainder > 0) + { + int paddingNeeded = (4 - remainder) % 4; + paddedEncodedJwtSection = Arrays.copyOf(unpaddedEncodedJwtSection.getBytes(), length + paddingNeeded); + Arrays.fill(paddedEncodedJwtSection, length, paddedEncodedJwtSection.length, (byte)'='); + } + else + { + paddedEncodedJwtSection = unpaddedEncodedJwtSection.getBytes(); + } + + return paddedEncodedJwtSection; + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java new file mode 100644 index 00000000000..94703d1d1e1 --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java @@ -0,0 +1,503 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.security.authentication.SessionAuthentication; +import org.eclipse.jetty.server.Authentication; +import org.eclipse.jetty.server.Authentication.User; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.UserIdentity; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.UrlEncoded; +import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

      Implements authentication using OpenId Connect on top of OAuth 2.0. + * + *

      The OpenIdAuthenticator redirects unauthenticated requests to the OpenID Connect Provider. The End-User is + * eventually redirected back with an Authorization Code to the /j_security_check URI within the context. + * The Authorization Code is then used to authenticate the user through the {@link OpenIdCredentials} and {@link OpenIdLoginService}. + *

      + *

      + * Once a user is authenticated the OpenID Claims can be retrieved through an attribute on the session with the key {@link #CLAIMS}. + * The full response containing the OAuth 2.0 Access Token can be obtained with the session attribute {@link #RESPONSE}. + *

      + *

      {@link SessionAuthentication} is then used to wrap Authentication results so that they are associated with the session.

      + */ +public class OpenIdAuthenticator extends LoginAuthenticator +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdAuthenticator.class); + + public static final String CLAIMS = "org.eclipse.jetty.security.openid.claims"; + public static final String RESPONSE = "org.eclipse.jetty.security.openid.response"; + public static final String ERROR_PAGE = "org.eclipse.jetty.security.openid.error_page"; + public static final String J_URI = "org.eclipse.jetty.security.openid.URI"; + public static final String J_POST = "org.eclipse.jetty.security.openid.POST"; + public static final String J_METHOD = "org.eclipse.jetty.security.openid.METHOD"; + public static final String CSRF_TOKEN = "org.eclipse.jetty.security.openid.csrf_token"; + public static final String J_SECURITY_CHECK = "/j_security_check"; + + private OpenIdConfiguration _configuration; + private String _errorPage; + private String _errorPath; + private boolean _alwaysSaveUri; + + public OpenIdAuthenticator() + { + } + + public OpenIdAuthenticator(OpenIdConfiguration configuration, String errorPage) + { + this._configuration = configuration; + if (errorPage != null) + setErrorPage(errorPage); + } + + @Override + public void setConfiguration(AuthConfiguration configuration) + { + super.setConfiguration(configuration); + + String error = configuration.getInitParameter(ERROR_PAGE); + if (error != null) + setErrorPage(error); + + if (_configuration != null) + return; + + LoginService loginService = configuration.getLoginService(); + if (!(loginService instanceof OpenIdLoginService)) + throw new IllegalArgumentException("invalid LoginService"); + this._configuration = ((OpenIdLoginService)loginService).getConfiguration(); + } + + @Override + public String getAuthMethod() + { + return Constraint.__OPENID_AUTH; + } + + /** + * If true, uris that cause a redirect to a login page will always + * be remembered. If false, only the first uri that leads to a login + * page redirect is remembered. + * + * @param alwaysSave true to always save the uri + */ + public void setAlwaysSaveUri(boolean alwaysSave) + { + _alwaysSaveUri = alwaysSave; + } + + public boolean isAlwaysSaveUri() + { + return _alwaysSaveUri; + } + + private void setErrorPage(String path) + { + if (path == null || path.trim().length() == 0) + { + _errorPath = null; + _errorPage = null; + } + else + { + if (!path.startsWith("/")) + { + LOG.warn("error-page must start with /"); + path = "/" + path; + } + _errorPage = path; + _errorPath = path; + + if (_errorPath.indexOf('?') > 0) + _errorPath = _errorPath.substring(0, _errorPath.indexOf('?')); + } + } + + @Override + public UserIdentity login(String username, Object credentials, ServletRequest request) + { + if (LOG.isDebugEnabled()) + LOG.debug("login {} {} {}", username, credentials, request); + + UserIdentity user = super.login(username, credentials, request); + if (user != null) + { + HttpSession session = ((HttpServletRequest)request).getSession(); + Authentication cached = new SessionAuthentication(getAuthMethod(), user, credentials); + session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, cached); + session.setAttribute(CLAIMS, ((OpenIdCredentials)credentials).getClaims()); + session.setAttribute(RESPONSE, ((OpenIdCredentials)credentials).getResponse()); + } + return user; + } + + @Override + public void logout(ServletRequest request) + { + super.logout(request); + HttpServletRequest httpRequest = (HttpServletRequest)request; + HttpSession session = httpRequest.getSession(false); + + if (session == null) + return; + + //clean up session + session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); + session.removeAttribute(CLAIMS); + session.removeAttribute(RESPONSE); + } + + @Override + public void prepareRequest(ServletRequest request) + { + //if this is a request resulting from a redirect after auth is complete + //(ie its from a redirect to the original request uri) then due to + //browser handling of 302 redirects, the method may not be the same as + //that of the original request. Replace the method and original post + //params (if it was a post). + // + //See Servlet Spec 3.1 sec 13.6.3 + HttpServletRequest httpRequest = (HttpServletRequest)request; + HttpSession session = httpRequest.getSession(false); + if (session == null || session.getAttribute(SessionAuthentication.__J_AUTHENTICATED) == null) + return; //not authenticated yet + + String juri = (String)session.getAttribute(J_URI); + if (juri == null || juri.length() == 0) + return; //no original uri saved + + String method = (String)session.getAttribute(J_METHOD); + if (method == null || method.length() == 0) + return; //didn't save original request method + + StringBuffer buf = httpRequest.getRequestURL(); + if (httpRequest.getQueryString() != null) + buf.append("?").append(httpRequest.getQueryString()); + + if (!juri.equals(buf.toString())) + return; //this request is not for the same url as the original + + //restore the original request's method on this request + if (LOG.isDebugEnabled()) + LOG.debug("Restoring original method {} for {} with method {}", method, juri, httpRequest.getMethod()); + Request baseRequest = Request.getBaseRequest(request); + baseRequest.setMethod(method); + } + + @Override + public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException + { + final HttpServletRequest request = (HttpServletRequest)req; + final HttpServletResponse response = (HttpServletResponse)res; + final Request baseRequest = Request.getBaseRequest(request); + final Response baseResponse = baseRequest.getResponse(); + + String uri = request.getRequestURI(); + if (uri == null) + uri = URIUtil.SLASH; + + mandatory |= isJSecurityCheck(uri); + if (!mandatory) + return new DeferredAuthentication(this); + + if (isErrorPage(URIUtil.addPaths(request.getServletPath(), request.getPathInfo())) && !DeferredAuthentication.isDeferred(response)) + return new DeferredAuthentication(this); + + try + { + if (request.isRequestedSessionIdFromURL()) + { + if (LOG.isDebugEnabled()) + LOG.debug("Session ID should be cookie for OpenID authentication to work"); + + baseResponse.sendRedirect(getRedirectCode(baseRequest.getHttpVersion()), URIUtil.addPaths(request.getContextPath(), _errorPage)); + return Authentication.SEND_FAILURE; + } + + // Handle a request for authentication. + if (isJSecurityCheck(uri)) + { + String authCode = request.getParameter("code"); + if (authCode != null) + { + // Verify anti-forgery state token + String state = request.getParameter("state"); + String antiForgeryToken = (String)request.getSession().getAttribute(CSRF_TOKEN); + if (antiForgeryToken == null || !antiForgeryToken.equals(state)) + { + LOG.warn("auth failed 403: invalid state parameter"); + if (response != null) + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return Authentication.SEND_FAILURE; + } + + // Attempt to login with the provided authCode + OpenIdCredentials credentials = new OpenIdCredentials(authCode, getRedirectUri(request), _configuration); + UserIdentity user = login(null, credentials, request); + HttpSession session = request.getSession(false); + if (user != null) + { + // Redirect to original request + String nuri; + synchronized (session) + { + nuri = (String)session.getAttribute(J_URI); + + if (nuri == null || nuri.length() == 0) + { + nuri = request.getContextPath(); + if (nuri.length() == 0) + nuri = URIUtil.SLASH; + } + } + OpenIdAuthentication openIdAuth = new OpenIdAuthentication(getAuthMethod(), user); + if (LOG.isDebugEnabled()) + LOG.debug("authenticated {}->{}", openIdAuth, nuri); + + response.setContentLength(0); + baseResponse.sendRedirect(getRedirectCode(baseRequest.getHttpVersion()), nuri); + return openIdAuth; + } + } + + // not authenticated + if (LOG.isDebugEnabled()) + LOG.debug("OpenId authentication FAILED"); + if (_errorPage == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth failed 403"); + if (response != null) + response.sendError(HttpServletResponse.SC_FORBIDDEN); + } + else + { + if (LOG.isDebugEnabled()) + LOG.debug("auth failed {}", _errorPage); + baseResponse.sendRedirect(getRedirectCode(baseRequest.getHttpVersion()), URIUtil.addPaths(request.getContextPath(), _errorPage)); + } + + return Authentication.SEND_FAILURE; + } + + // Look for cached authentication + HttpSession session = request.getSession(false); + Authentication authentication = session == null ? null : (Authentication)session.getAttribute(SessionAuthentication.__J_AUTHENTICATED); + if (authentication != null) + { + // Has authentication been revoked? + if (authentication instanceof Authentication.User && _loginService != null && + !_loginService.validate(((Authentication.User)authentication).getUserIdentity())) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth revoked {}", authentication); + session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); + } + else + { + synchronized (session) + { + String jUri = (String)session.getAttribute(J_URI); + if (jUri != null) + { + //check if the request is for the same url as the original and restore + //params if it was a post + if (LOG.isDebugEnabled()) + LOG.debug("auth retry {}->{}", authentication, jUri); + StringBuffer buf = request.getRequestURL(); + if (request.getQueryString() != null) + buf.append("?").append(request.getQueryString()); + + if (jUri.equals(buf.toString())) + { + @SuppressWarnings("unchecked") + MultiMap jPost = (MultiMap)session.getAttribute(J_POST); + if (jPost != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth rePOST {}->{}", authentication, jUri); + baseRequest.setContentParameters(jPost); + } + session.removeAttribute(J_URI); + session.removeAttribute(J_METHOD); + session.removeAttribute(J_POST); + } + } + } + if (LOG.isDebugEnabled()) + LOG.debug("auth {}", authentication); + return authentication; + } + } + + // if we can't send challenge + if (DeferredAuthentication.isDeferred(response)) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth deferred {}", session == null ? null : session.getId()); + return Authentication.UNAUTHENTICATED; + } + + // remember the current URI + session = (session != null ? session : request.getSession(true)); + synchronized (session) + { + // But only if it is not set already, or we save every uri that leads to a login redirect + if (session.getAttribute(J_URI) == null || isAlwaysSaveUri()) + { + StringBuffer buf = request.getRequestURL(); + if (request.getQueryString() != null) + buf.append("?").append(request.getQueryString()); + session.setAttribute(J_URI, buf.toString()); + session.setAttribute(J_METHOD, request.getMethod()); + + if (MimeTypes.Type.FORM_ENCODED.is(req.getContentType()) && HttpMethod.POST.is(request.getMethod())) + { + MultiMap formParameters = new MultiMap<>(); + baseRequest.extractFormParameters(formParameters); + session.setAttribute(J_POST, formParameters); + } + } + } + + // send the the challenge + String challengeUri = getChallengeUri(request); + if (LOG.isDebugEnabled()) + LOG.debug("challenge {}->{}", session.getId(), challengeUri); + baseResponse.sendRedirect(getRedirectCode(baseRequest.getHttpVersion()), challengeUri); + + return Authentication.SEND_CONTINUE; + } + catch (IOException e) + { + throw new ServerAuthException(e); + } + } + + public boolean isJSecurityCheck(String uri) + { + int jsc = uri.indexOf(J_SECURITY_CHECK); + + if (jsc < 0) + return false; + int e = jsc + J_SECURITY_CHECK.length(); + if (e == uri.length()) + return true; + char c = uri.charAt(e); + return c == ';' || c == '#' || c == '/' || c == '?'; + } + + public boolean isErrorPage(String pathInContext) + { + return pathInContext != null && (pathInContext.equals(_errorPath)); + } + + private static int getRedirectCode(HttpVersion httpVersion) + { + return (httpVersion.getVersion() < HttpVersion.HTTP_1_1.getVersion() + ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); + } + + private String getRedirectUri(HttpServletRequest request) + { + final StringBuffer redirectUri = new StringBuffer(128); + URIUtil.appendSchemeHostPort(redirectUri, request.getScheme(), + request.getServerName(), request.getServerPort()); + redirectUri.append(request.getContextPath()); + redirectUri.append(J_SECURITY_CHECK); + return redirectUri.toString(); + } + + protected String getChallengeUri(HttpServletRequest request) + { + HttpSession session = request.getSession(); + String antiForgeryToken; + synchronized (session) + { + antiForgeryToken = (session.getAttribute(CSRF_TOKEN) == null) + ? new BigInteger(130, new SecureRandom()).toString(32) + : (String)session.getAttribute(CSRF_TOKEN); + session.setAttribute(CSRF_TOKEN, antiForgeryToken); + } + + // any custom scopes requested from configuration + StringBuilder scopes = new StringBuilder(); + for (String s : _configuration.getScopes()) + { + scopes.append(" ").append(s); + } + + return _configuration.getAuthEndpoint() + + "?client_id=" + UrlEncoded.encodeString(_configuration.getClientId(), StandardCharsets.UTF_8) + + "&redirect_uri=" + UrlEncoded.encodeString(getRedirectUri(request), StandardCharsets.UTF_8) + + "&scope=openid" + UrlEncoded.encodeString(scopes.toString(), StandardCharsets.UTF_8) + + "&state=" + antiForgeryToken + + "&response_type=code"; + } + + @Override + public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) + { + return true; + } + + /** + * This Authentication represents a just completed OpenId Connect authentication. + * Subsequent requests from the same user are authenticated by the presents + * of a {@link SessionAuthentication} instance in their session. + */ + public static class OpenIdAuthentication extends UserAuthentication implements Authentication.ResponseSent + { + public OpenIdAuthentication(String method, UserIdentity userIdentity) + { + super(method, userIdentity); + } + + @Override + public String toString() + { + return "OpenId" + super.toString(); + } + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java new file mode 100644 index 00000000000..3318884490e --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import javax.servlet.ServletContext; + +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.security.Constraint; + +public class OpenIdAuthenticatorFactory implements Authenticator.Factory +{ + @Override + public Authenticator getAuthenticator(Server server, ServletContext context, Authenticator.AuthConfiguration configuration, IdentityService identityService, LoginService loginService) + { + String auth = configuration.getAuthMethod(); + if (Constraint.__OPENID_AUTH.equalsIgnoreCase(auth)) + return new OpenIdAuthenticator(); + return null; + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java new file mode 100644 index 00000000000..73f2269ac0a --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java @@ -0,0 +1,195 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.util.ajax.JSON; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Holds the configuration for an OpenID Connect service. + * + * This uses the OpenID Provider URL with the path {@link #CONFIG_PATH} to discover + * the required information about the OIDC service. + */ +public class OpenIdConfiguration extends ContainerLifeCycle +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdConfiguration.class); + private static final String CONFIG_PATH = "/.well-known/openid-configuration"; + + private final HttpClient httpClient; + private final String issuer; + private final String clientId; + private final String clientSecret; + private final List scopes = new ArrayList<>(); + private String authEndpoint; + private String tokenEndpoint; + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param provider The URL of the OpenID provider. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + */ + public OpenIdConfiguration(String provider, String clientId, String clientSecret) + { + this(provider, null, null, clientId, clientSecret, null); + } + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param issuer The URL of the OpenID provider. + * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. + * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + * @param httpClient The {@link HttpClient} instance to use. + */ + public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint, + String clientId, String clientSecret, HttpClient httpClient) + { + this.issuer = issuer; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.authEndpoint = authorizationEndpoint; + this.tokenEndpoint = tokenEndpoint; + this.httpClient = httpClient != null ? httpClient : newHttpClient(); + + if (this.issuer == null) + throw new IllegalArgumentException("Issuer was not configured"); + + addBean(this.httpClient); + } + + @Override + protected void doStart() throws Exception + { + super.doStart(); + + if (authEndpoint == null || tokenEndpoint == null) + { + Map discoveryDocument = fetchOpenIdConnectMetadata(issuer, httpClient); + + authEndpoint = (String)discoveryDocument.get("authorization_endpoint"); + if (authEndpoint == null) + throw new IllegalArgumentException("authorization_endpoint"); + + tokenEndpoint = (String)discoveryDocument.get("token_endpoint"); + if (tokenEndpoint == null) + throw new IllegalArgumentException("token_endpoint"); + + if (!Objects.equals(discoveryDocument.get("issuer"), issuer)) + LOG.warn("The issuer in the metadata is not correct."); + } + } + + private static HttpClient newHttpClient() + { + ClientConnector connector = new ClientConnector(); + connector.setSslContextFactory(new SslContextFactory.Client(false)); + return new HttpClient(new HttpClientTransportOverHTTP(connector)); + } + + private static Map fetchOpenIdConnectMetadata(String provider, HttpClient httpClient) + { + try + { + if (provider.endsWith("/")) + provider = provider.substring(0, provider.length() - 1); + + Map result; + String responseBody = httpClient.GET(provider + CONFIG_PATH) + .getContentAsString(); + Object parsedResult = new JSON().fromJSON(responseBody); + + if (parsedResult instanceof Map) + { + Map rawResult = (Map)parsedResult; + result = rawResult.entrySet().stream() + .collect(Collectors.toMap(it -> it.getKey().toString(), Map.Entry::getValue)); + } + else + { + LOG.warn("OpenID provider did not return a proper JSON object response. Result was '{}'", responseBody); + throw new IllegalStateException("Could not parse OpenID provider's malformed response"); + } + + LOG.debug("discovery document {}", result); + + return result; + } + catch (Exception e) + { + throw new IllegalArgumentException("invalid identity provider", e); + } + } + + public HttpClient getHttpClient() + { + return httpClient; + } + + public String getAuthEndpoint() + { + return authEndpoint; + } + + public String getClientId() + { + return clientId; + } + + public String getClientSecret() + { + return clientSecret; + } + + public String getIssuer() + { + return issuer; + } + + public String getTokenEndpoint() + { + return tokenEndpoint; + } + + public void addScopes(String... scopes) + { + if (scopes != null) + Collections.addAll(this.scopes, scopes); + } + + public List getScopes() + { + return scopes; + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java new file mode 100644 index 00000000000..07c6f6fc22d --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java @@ -0,0 +1,193 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.util.FormContentProvider; +import org.eclipse.jetty.util.Fields; +import org.eclipse.jetty.util.ajax.JSON; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

      The credentials of an user to be authenticated with OpenID Connect. This will contain + * the OpenID ID Token and the OAuth 2.0 Access Token.

      + * + *

      + * This is constructed with an authorization code from the authentication request. This authorization code + * is then exchanged using {@link #redeemAuthCode(HttpClient)} for a response containing the ID Token and Access Token. + * The response is then validated against the {@link OpenIdConfiguration}. + *

      + */ +public class OpenIdCredentials implements Serializable +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdCredentials.class); + private static final long serialVersionUID = 4766053233370044796L; + + private final String redirectUri; + private final OpenIdConfiguration configuration; + private String authCode; + private Map response; + private Map claims; + + public OpenIdCredentials(String authCode, String redirectUri, OpenIdConfiguration configuration) + { + this.authCode = authCode; + this.redirectUri = redirectUri; + this.configuration = configuration; + } + + public String getUserId() + { + return (String)claims.get("sub"); + } + + public Map getClaims() + { + return claims; + } + + public Map getResponse() + { + return response; + } + + public void redeemAuthCode(HttpClient httpClient) throws Exception + { + if (LOG.isDebugEnabled()) + LOG.debug("redeemAuthCode() {}", this); + + if (authCode != null) + { + try + { + response = claimAuthCode(httpClient, authCode); + if (LOG.isDebugEnabled()) + LOG.debug("response: {}", response); + + String idToken = (String)response.get("id_token"); + if (idToken == null) + throw new IllegalArgumentException("no id_token"); + + String accessToken = (String)response.get("access_token"); + if (accessToken == null) + throw new IllegalArgumentException("no access_token"); + + String tokenType = (String)response.get("token_type"); + if (!"Bearer".equalsIgnoreCase(tokenType)) + throw new IllegalArgumentException("invalid token_type"); + + claims = JwtDecoder.decode(idToken); + if (LOG.isDebugEnabled()) + LOG.debug("claims {}", claims); + validateClaims(); + } + finally + { + // reset authCode as it can only be used once + authCode = null; + } + } + } + + private void validateClaims() + { + // Issuer Identifier for the OpenID Provider MUST exactly match the value of the iss (issuer) Claim. + if (!configuration.getIssuer().equals(claims.get("iss"))) + throw new IllegalArgumentException("Issuer Identifier MUST exactly match the iss Claim"); + + // The aud (audience) Claim MUST contain the client_id value. + validateAudience(); + + // If an azp (authorized party) Claim is present, verify that its client_id is the Claim Value. + Object azp = claims.get("azp"); + if (azp != null && !configuration.getClientId().equals(azp)) + throw new IllegalArgumentException("Authorized party claim value should be the client_id"); + } + + private void validateAudience() + { + Object aud = claims.get("aud"); + String clientId = configuration.getClientId(); + boolean isString = aud instanceof String; + boolean isList = aud instanceof Object[]; + boolean isValidType = isString || isList; + + if (isString && !clientId.equals(aud)) + throw new IllegalArgumentException("Audience Claim MUST contain the client_id value"); + else if (isList) + { + if (!Arrays.asList((Object[])aud).contains(clientId)) + throw new IllegalArgumentException("Audience Claim MUST contain the client_id value"); + + if (claims.get("azp") == null) + throw new IllegalArgumentException("A multi-audience ID token needs to contain an azp claim"); + } + else if (!isValidType) + throw new IllegalArgumentException("Audience claim was not valid"); + } + + public boolean isExpired() + { + if (authCode != null || claims == null) + return true; + + // Check expiry + long expiry = (Long)claims.get("exp"); + long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F); + if (currentTimeSeconds > expiry) + { + if (LOG.isDebugEnabled()) + LOG.debug("OpenId Credentials expired {}", this); + return true; + } + + return false; + } + + private Map claimAuthCode(HttpClient httpClient, String authCode) throws Exception + { + Fields fields = new Fields(); + fields.add("code", authCode); + fields.add("client_id", configuration.getClientId()); + fields.add("client_secret", configuration.getClientSecret()); + fields.add("redirect_uri", redirectUri); + fields.add("grant_type", "authorization_code"); + FormContentProvider formContentProvider = new FormContentProvider(fields); + Request request = httpClient.POST(configuration.getTokenEndpoint()) + .content(formContentProvider) + .timeout(10, TimeUnit.SECONDS); + ContentResponse response = request.send(); + String responseBody = response.getContentAsString(); + if (LOG.isDebugEnabled()) + LOG.debug("Authentication response: {}", responseBody); + + Object parsedResponse = new JSON().fromJSON(responseBody); + if (!(parsedResponse instanceof Map)) + throw new IllegalStateException("Malformed response from OpenID Provider"); + return (Map)parsedResponse; + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java new file mode 100644 index 00000000000..bfded720934 --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java @@ -0,0 +1,174 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.security.Principal; +import javax.security.auth.Subject; +import javax.servlet.ServletRequest; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.server.UserIdentity; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The implementation of {@link LoginService} required to use OpenID Connect. + * + *

      + * Can contain an optional wrapped {@link LoginService} which is used to store role information about users. + *

      + */ +public class OpenIdLoginService extends ContainerLifeCycle implements LoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdLoginService.class); + + private final OpenIdConfiguration configuration; + private final LoginService loginService; + private final HttpClient httpClient; + private IdentityService identityService; + private boolean authenticateNewUsers; + + public OpenIdLoginService(OpenIdConfiguration configuration) + { + this(configuration, null); + } + + /** + * Use a wrapped {@link LoginService} to store information about user roles. + * Users in the wrapped loginService must be stored with their username as + * the value of the sub (subject) Claim, and a credentials value of the empty string. + * @param configuration the OpenID configuration to use. + * @param loginService the wrapped LoginService to defer to for user roles. + */ + public OpenIdLoginService(OpenIdConfiguration configuration, LoginService loginService) + { + this.configuration = configuration; + this.loginService = loginService; + this.httpClient = configuration.getHttpClient(); + addBean(this.configuration); + addBean(this.loginService); + } + + @Override + public String getName() + { + return configuration.getIssuer(); + } + + public OpenIdConfiguration getConfiguration() + { + return configuration; + } + + @Override + public UserIdentity login(String identifier, Object credentials, ServletRequest req) + { + if (LOG.isDebugEnabled()) + LOG.debug("login({}, {}, {})", identifier, credentials, req); + + OpenIdCredentials openIdCredentials = (OpenIdCredentials)credentials; + try + { + openIdCredentials.redeemAuthCode(httpClient); + if (openIdCredentials.isExpired()) + return null; + } + catch (Throwable e) + { + LOG.warn("Unable to redeem auth code", e); + return null; + } + + OpenIdUserPrincipal userPrincipal = new OpenIdUserPrincipal(openIdCredentials); + Subject subject = new Subject(); + subject.getPrincipals().add(userPrincipal); + subject.getPrivateCredentials().add(credentials); + subject.setReadOnly(); + + if (loginService != null) + { + UserIdentity userIdentity = loginService.login(openIdCredentials.getUserId(), "", req); + if (userIdentity == null) + { + if (isAuthenticateNewUsers()) + return getIdentityService().newUserIdentity(subject, userPrincipal, new String[0]); + return null; + } + return new OpenIdUserIdentity(subject, userPrincipal, userIdentity); + } + + return identityService.newUserIdentity(subject, userPrincipal, new String[0]); + } + + public boolean isAuthenticateNewUsers() + { + return authenticateNewUsers; + } + + /** + * This setting is only meaningful if a wrapped {@link LoginService} has been set. + *

      + * If set to true, any users not found by the wrapped {@link LoginService} will still + * be authenticated but with no roles, if set to false users will not be + * authenticated unless they are discovered by the wrapped {@link LoginService}. + *

      + * @param authenticateNewUsers whether to authenticate users not found by a wrapping LoginService + */ + public void setAuthenticateNewUsers(boolean authenticateNewUsers) + { + this.authenticateNewUsers = authenticateNewUsers; + } + + @Override + public boolean validate(UserIdentity user) + { + Principal userPrincipal = user.getUserPrincipal(); + if (!(userPrincipal instanceof OpenIdUserPrincipal)) + return false; + + OpenIdCredentials credentials = ((OpenIdUserPrincipal)userPrincipal).getCredentials(); + return !credentials.isExpired(); + } + + @Override + public IdentityService getIdentityService() + { + return loginService == null ? identityService : loginService.getIdentityService(); + } + + @Override + public void setIdentityService(IdentityService service) + { + if (isRunning()) + throw new IllegalStateException("Running"); + + if (loginService != null) + loginService.setIdentityService(service); + else + identityService = service; + } + + @Override + public void logout(UserIdentity user) + { + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserIdentity.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserIdentity.java new file mode 100644 index 00000000000..4fb962560e6 --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserIdentity.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.security.Principal; +import javax.security.auth.Subject; + +import org.eclipse.jetty.server.UserIdentity; + +public class OpenIdUserIdentity implements UserIdentity +{ + private final Subject subject; + private final Principal userPrincipal; + private final UserIdentity userIdentity; + + public OpenIdUserIdentity(Subject subject, Principal userPrincipal, UserIdentity userIdentity) + { + this.subject = subject; + this.userPrincipal = userPrincipal; + this.userIdentity = userIdentity; + } + + @Override + public Subject getSubject() + { + return subject; + } + + @Override + public Principal getUserPrincipal() + { + return userPrincipal; + } + + @Override + public boolean isUserInRole(String role, Scope scope) + { + return userIdentity != null && userIdentity.isUserInRole(role, scope); + } +} diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserPrincipal.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserPrincipal.java new file mode 100644 index 00000000000..b2ce7b752c8 --- /dev/null +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserPrincipal.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.io.Serializable; +import java.security.Principal; + +public class OpenIdUserPrincipal implements Principal, Serializable +{ + private static final long serialVersionUID = 1521094652756670469L; + private final OpenIdCredentials _credentials; + + public OpenIdUserPrincipal(OpenIdCredentials credentials) + { + _credentials = credentials; + } + + public OpenIdCredentials getCredentials() + { + return _credentials; + } + + @Override + public String getName() + { + return _credentials.getUserId(); + } + + @Override + public String toString() + { + return _credentials.getUserId(); + } +} diff --git a/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory b/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory new file mode 100644 index 00000000000..cc53212a57b --- /dev/null +++ b/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory @@ -0,0 +1 @@ +org.eclipse.jetty.security.openid.OpenIdAuthenticatorFactory \ No newline at end of file diff --git a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtDecoderTest.java b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtDecoderTest.java new file mode 100644 index 00000000000..614b9ce7d00 --- /dev/null +++ b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtDecoderTest.java @@ -0,0 +1,122 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class JwtDecoderTest +{ + public static Stream paddingExamples() + { + return Stream.of( + Arguments.of("XXXX", "XXXX"), + Arguments.of("XXX", "XXX="), + Arguments.of("XX", "XX=="), + Arguments.of("XXX=", "XXX="), + Arguments.of("X-X", "X-X="), + Arguments.of("@#", "@#=="), + Arguments.of("X=", "X="), + Arguments.of("XX=", "XX="), + Arguments.of("XX==", "XX=="), + Arguments.of("XXX=", "XXX="), + Arguments.of("", "") + ); + } + + public static Stream badPaddingExamples() + { + return Stream.of( + Arguments.of("X"), + Arguments.of("XXXXX") + ); + } + + @ParameterizedTest + @MethodSource("paddingExamples") + public void testPaddingBase64(String input, String expected) + { + byte[] actual = JwtDecoder.padJWTSection(input); + assertThat(actual, is(expected.getBytes())); + } + + @ParameterizedTest + @MethodSource("badPaddingExamples") + public void testPaddingInvalidBase64(String input) + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> JwtDecoder.padJWTSection(input)); + + assertThat(error.getMessage(), is("Not a valid Base64-encoded string")); + } + + @Test + public void testEncodeDecode() + { + String issuer = "example.com"; + String subject = "1234"; + String clientId = "1234.client.id"; + String name = "Bob"; + long expiry = 123; + + // Create a fake ID Token. + String claims = JwtEncoder.createIdToken(issuer, clientId, subject, name, expiry); + String idToken = JwtEncoder.encode(claims); + + // Decode the ID Token and verify the claims are the same. + Map decodedClaims = JwtDecoder.decode(idToken); + assertThat(decodedClaims.get("iss"), is(issuer)); + assertThat(decodedClaims.get("sub"), is(subject)); + assertThat(decodedClaims.get("aud"), is(clientId)); + assertThat(decodedClaims.get("name"), is(name)); + assertThat(decodedClaims.get("exp"), is(expiry)); + } + + @Test + public void testDecodeMissingPadding() + { + // Example given in Issue #4128 which requires the re-adding the B64 padding to decode. + String jwt = "eyJraWQiOiIxNTU1OTM0ODQ3IiwieDV0IjoiOWdCOW9zRldSRHRSMkhtNGNmVnJnWTBGcmZRIiwiYWxnIjoiUlMyNTYifQ" + + ".eyJhdF9oYXNoIjoiQTA0NUoxcE5YRk1nYzlXN2wxSk1fUSIsImRlbGVnYXRpb25faWQiOiJjZTBhNjRlNS0xYWY3LTQ2MzEtOGUz" + + "NC1mNDE5N2JkYzVjZTAiLCJhY3IiOiJ1cm46c2U6Y3VyaXR5OmF1dGhlbnRpY2F0aW9uOmh0bWwtZm9ybTpodG1sLXByaW1hcnkiL" + + "CJzX2hhc2giOiIwc1FtRG9YY3FwcnM4NWUzdy0wbHdBIiwiYXpwIjoiNzZiZTc5Y2ItM2E1Ni00ZTE3LTg3NzYtNDI1Nzc5MjRjYz" + + "c2IiwiYXV0aF90aW1lIjoxNTY5NjU4MDk1LCJleHAiOjE1Njk2NjE5OTUsIm5iZiI6MTU2OTY1ODM5NSwianRpIjoiZjJkNWI2YzE" + + "tNTIxYi00Y2Y5LThlNWEtOTg5NGJhNmE0MzkyIiwiaXNzIjoiaHR0cHM6Ly9ub3JkaWNhcGlzLmN1cml0eS5pby9-IiwiYXVkIjoi" + + "NzZiZTc5Y2ItM2E1Ni00ZTE3LTg3NzYtNDI1Nzc5MjRjYzc2Iiwic3ViIjoibmlrb3MiLCJpYXQiOjE1Njk2NTgzOTUsInB1cnBvc" + + "2UiOiJpZCJ9.Wd458zNmXggpkDN6vbS3-aiajh4-VbkmcStLYUqahYJUp9p-AUI_RZttWvwh3UDMG9rWww_ya8KFK_SkPfKooEaSN" + + "OjOhw0ox4d-9lgti3J49eRyO20RViXvRHyLVtcjv5IaqvMXgwW60Thubv19OION7DstyArffcxNNSpiqDq6wjd0T2DJ3gSXXlJHLT" + + "Wrry3svqu1j_GCbHc04XYGicxsusKgc3n22dh4I6p4trdo0Gu5Un0bZ8Yov7IzWItqTgm9X5r9gZlAOLcAuK1WTwkzAwZJ24HgvxK" + + "muYfV_4ZCg_VPN2Op8YPuRAQOgUERpeTv1RDFTOG9GKZIMBVR0A"; + + // Decode the ID Token and verify the claims are the correct. + Map decodedClaims = JwtDecoder.decode(jwt); + assertThat(decodedClaims.get("sub"), is("nikos")); + assertThat(decodedClaims.get("aud"), is("76be79cb-3a56-4e17-8776-42577924cc76")); + assertThat(decodedClaims.get("exp"), is(1569661995L)); + } +} diff --git a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtEncoder.java b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtEncoder.java new file mode 100644 index 00000000000..42fda2a53a6 --- /dev/null +++ b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtEncoder.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.util.Base64; + +/** + * A basic JWT encoder for testing purposes. + */ +public class JwtEncoder +{ + private static final Base64.Encoder ENCODER = Base64.getUrlEncoder(); + private static final String DEFAULT_HEADER = "{\"INFO\": \"this is not used or checked in our implementation\"}"; + private static final String DEFAULT_SIGNATURE = "we do not validate signature as we use the authorization code flow"; + + public static String encode(String idToken) + { + return stripPadding(ENCODER.encodeToString(DEFAULT_HEADER.getBytes())) + "." + + stripPadding(ENCODER.encodeToString(idToken.getBytes())) + "." + + stripPadding(ENCODER.encodeToString(DEFAULT_SIGNATURE.getBytes())); + } + + private static String stripPadding(String paddedBase64) + { + return paddedBase64.split("=")[0]; + } + + /** + * Create a basic JWT for testing using argument supplied attributes. + */ + public static String createIdToken(String provider, String clientId, String subject, String name, long expiry) + { + return "{" + + "\"iss\": \"" + provider + "\"," + + "\"sub\": \"" + subject + "\"," + + "\"aud\": \"" + clientId + "\"," + + "\"exp\": " + expiry + "," + + "\"name\": \"" + name + "\"," + + "\"email\": \"" + name + "@example.com" + "\"" + + "}"; + } +} diff --git a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java new file mode 100644 index 00000000000..d321f36db23 --- /dev/null +++ b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java @@ -0,0 +1,226 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.io.IOException; +import java.security.Principal; +import java.util.Map; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.security.Constraint; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class OpenIdAuthenticationTest +{ + public static final String CLIENT_ID = "testClient101"; + public static final String CLIENT_SECRET = "secret37989798"; + + private OpenIdProvider openIdProvider; + private Server server; + private ServerConnector connector; + private HttpClient client; + + @BeforeEach + public void setup() throws Exception + { + openIdProvider = new OpenIdProvider(CLIENT_ID, CLIENT_SECRET); + openIdProvider.start(); + + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); + + // Add servlets + context.addServlet(LoginPage.class, "/login"); + context.addServlet(LogoutPage.class, "/logout"); + context.addServlet(HomePage.class, "/*"); + context.addServlet(ErrorPage.class, "/error"); + + // configure security constraints + Constraint constraint = new Constraint(); + constraint.setName(Constraint.__OPENID_AUTH); + constraint.setRoles(new String[]{"**"}); + constraint.setAuthenticate(true); + + Constraint adminConstraint = new Constraint(); + adminConstraint.setName(Constraint.__OPENID_AUTH); + adminConstraint.setRoles(new String[]{"admin"}); + adminConstraint.setAuthenticate(true); + + // constraint mappings + ConstraintMapping profileMapping = new ConstraintMapping(); + profileMapping.setConstraint(constraint); + profileMapping.setPathSpec("/profile"); + ConstraintMapping loginMapping = new ConstraintMapping(); + loginMapping.setConstraint(constraint); + loginMapping.setPathSpec("/login"); + ConstraintMapping adminMapping = new ConstraintMapping(); + adminMapping.setConstraint(adminConstraint); + adminMapping.setPathSpec("/admin"); + + // security handler + ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); + securityHandler.setRealmName("OpenID Connect Authentication"); + securityHandler.addConstraintMapping(profileMapping); + securityHandler.addConstraintMapping(loginMapping); + securityHandler.addConstraintMapping(adminMapping); + + // Authentication using local OIDC Provider + OpenIdConfiguration configuration = new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET); + + // Configure OpenIdLoginService optionally providing a base LoginService to provide user roles + OpenIdLoginService loginService = new OpenIdLoginService(configuration);//, hashLoginService); + securityHandler.setLoginService(loginService); + + Authenticator authenticator = new OpenIdAuthenticator(configuration, "/error"); + securityHandler.setAuthenticator(authenticator); + context.setSecurityHandler(securityHandler); + + server.start(); + String redirectUri = "http://localhost:" + connector.getLocalPort() + "/j_security_check"; + openIdProvider.addRedirectUri(redirectUri); + + client = new HttpClient(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + openIdProvider.stop(); + server.stop(); + } + + @Test + public void testLoginLogout() throws Exception + { + String appUriString = "http://localhost:" + connector.getLocalPort(); + + // Initially not authenticated + ContentResponse response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + String[] content = response.getContentAsString().split("[\r\n]+"); + assertThat(content.length, is(1)); + assertThat(content[0], is("not authenticated")); + + // Request to login is success + response = client.GET(appUriString + "/login"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString().split("[\r\n]+"); + assertThat(content.length, is(1)); + assertThat(content[0], is("success")); + + // Now authenticated we can get info + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString().split("[\r\n]+"); + assertThat(content.length, is(3)); + assertThat(content[0], is("userId: 123456789")); + assertThat(content[1], is("name: Alice")); + assertThat(content[2], is("email: Alice@example.com")); + + // Request to admin page gives 403 as we do not have admin role + response = client.GET(appUriString + "/admin"); + assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403)); + + // We are no longer authenticated after logging out + response = client.GET(appUriString + "/logout"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString().split("[\r\n]+"); + assertThat(content.length, is(1)); + assertThat(content[0], is("not authenticated")); + } + + public static class LoginPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.getWriter().println("success"); + } + } + + public static class LogoutPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + request.getSession().invalidate(); + response.sendRedirect("/"); + } + } + + public static class AdminPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); + response.getWriter().println(userInfo.get("sub") + ": success"); + } + } + + public static class HomePage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/plain"); + Principal userPrincipal = request.getUserPrincipal(); + if (userPrincipal != null) + { + Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); + response.getWriter().println("userId: " + userInfo.get("sub")); + response.getWriter().println("name: " + userInfo.get("name")); + response.getWriter().println("email: " + userInfo.get("email")); + } + else + { + response.getWriter().println("not authenticated"); + } + } + } + + public static class ErrorPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/plain"); + response.getWriter().println("not authorized"); + } + } +} diff --git a/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java new file mode 100644 index 00000000000..9b1f99fe1cc --- /dev/null +++ b/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java @@ -0,0 +1,231 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security.openid; + +import java.io.IOException; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.UUID; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.component.ContainerLifeCycle; + +public class OpenIdProvider extends ContainerLifeCycle +{ + private static final String CONFIG_PATH = "/.well-known/openid-configuration"; + private static final String AUTH_PATH = "/auth"; + private static final String TOKEN_PATH = "/token"; + private final Map issuedAuthCodes = new HashMap<>(); + + protected final String clientId; + protected final String clientSecret; + protected final List redirectUris = new ArrayList<>(); + + private String provider; + private Server server; + private ServerConnector connector; + + public OpenIdProvider(String clientId, String clientSecret) + { + this.clientId = clientId; + this.clientSecret = clientSecret; + + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(); + contextHandler.setContextPath("/"); + contextHandler.addServlet(new ServletHolder(new OpenIdConfigServlet()), CONFIG_PATH); + contextHandler.addServlet(new ServletHolder(new OpenIdAuthEndpoint()), AUTH_PATH); + contextHandler.addServlet(new ServletHolder(new OpenIdTokenEndpoint()), TOKEN_PATH); + server.setHandler(contextHandler); + + addBean(server); + } + + @Override + protected void doStart() throws Exception + { + super.doStart(); + provider = "http://localhost:" + connector.getLocalPort(); + } + + public String getProvider() + { + if (!isStarted()) + throw new IllegalStateException(); + return provider; + } + + public void addRedirectUri(String uri) + { + redirectUris.add(uri); + } + + public class OpenIdAuthEndpoint extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + if (!clientId.equals(req.getParameter("client_id"))) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid client_id"); + return; + } + + String redirectUri = req.getParameter("redirect_uri"); + if (!redirectUris.contains(redirectUri)) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); + return; + } + + String scopeString = req.getParameter("scope"); + List scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(StringUtil.csvSplit(scopeString)); + if (!scopes.contains("openid")) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no openid scope"); + return; + } + + if (!"code".equals(req.getParameter("response_type"))) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "response_type must be code"); + return; + } + + String state = req.getParameter("state"); + if (state == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param"); + return; + } + + String authCode = UUID.randomUUID().toString().replace("-", ""); + User user = new User(123456789, "Alice"); + issuedAuthCodes.put(authCode, user); + + final Request baseRequest = Request.getBaseRequest(req); + final Response baseResponse = baseRequest.getResponse(); + redirectUri += "?code=" + authCode + "&state=" + state; + int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() + ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); + baseResponse.sendRedirect(redirectCode, resp.encodeRedirectURL(redirectUri)); + } + } + + public class OpenIdTokenEndpoint extends HttpServlet + { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + String code = req.getParameter("code"); + + if (!clientId.equals(req.getParameter("client_id")) || + !clientSecret.equals(req.getParameter("client_secret")) || + !redirectUris.contains(req.getParameter("redirect_uri")) || + !"authorization_code".equals(req.getParameter("grant_type")) || + code == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "bad auth request"); + return; + } + + User user = issuedAuthCodes.remove(code); + if (user == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid auth code"); + return; + } + + String accessToken = "ABCDEFG"; + long expiry = System.currentTimeMillis() + Duration.ofMinutes(10).toMillis(); + String response = "{" + + "\"access_token\": \"" + accessToken + "\"," + + "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken()) + "\"," + + "\"expires_in\": " + expiry + "," + + "\"token_type\": \"Bearer\"" + + "}"; + + resp.setContentType("text/plain"); + resp.getWriter().print(response); + } + } + + public class OpenIdConfigServlet extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + String discoveryDocument = "{" + + "\"issuer\": \"" + provider + "\"," + + "\"authorization_endpoint\": \"" + provider + AUTH_PATH + "\"," + + "\"token_endpoint\": \"" + provider + TOKEN_PATH + "\"," + + "}"; + + resp.getWriter().write(discoveryDocument); + } + } + + public class User + { + private long subject; + private String name; + + public User(String name) + { + this(new Random().nextLong(), name); + } + + public User(long subject, String name) + { + this.subject = subject; + this.name = name; + } + + public String getName() + { + return name; + } + + public String getIdToken() + { + long expiry = System.currentTimeMillis() + Duration.ofMinutes(1).toMillis(); + return JwtEncoder.createIdToken(provider, clientId, Long.toString(subject), name, expiry); + } + } +} diff --git a/jetty-openid/src/test/resources/jetty-logging.properties b/jetty-openid/src/test/resources/jetty-logging.properties new file mode 100755 index 00000000000..6f21b764f54 --- /dev/null +++ b/jetty-openid/src/test/resources/jetty-logging.properties @@ -0,0 +1,3 @@ +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG +# org.eclipse.jetty.security.openid.LEVEL=DEBUG \ No newline at end of file diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java index 89173c4c081..c5a50ee839b 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.jasper; @@ -33,10 +33,10 @@ import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.OSGiMetaInfConfiguration; import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ContainerTldBundleDiscoverer @@ -66,7 +66,7 @@ import org.osgi.framework.FrameworkUtil; public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer { - private static final Logger LOG = Log.getLogger(ContainerTldBundleDiscoverer.class); + private static final Logger LOG = LoggerFactory.getLogger(ContainerTldBundleDiscoverer.class); private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl"; /** diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java index b702de34a53..c85aaa42d6a 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.jasper; @@ -29,10 +29,10 @@ import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JSTLBundleDiscoverer @@ -47,7 +47,7 @@ import org.osgi.framework.FrameworkUtil; */ public class JSTLBundleDiscoverer implements TldBundleDiscoverer { - private static final Logger LOG = Log.getLogger(JSTLBundleDiscoverer.class); + private static final Logger LOG = LoggerFactory.getLogger(JSTLBundleDiscoverer.class); /** * Default name of a class that belongs to the jstl bundle. From that class diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java index 5649086f424..ad4e59614f2 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.jsp; diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlActivator.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlActivator.java index 9383ca9f60a..2d554ca51ac 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlActivator.java +++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlActivator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.warurl; diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java index 5bc33d7678b..2a2171f47ce 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java +++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/WarUrlStreamHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.warurl; diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarBundleManifestGenerator.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarBundleManifestGenerator.java index 6bf48be72d0..d1538944fc1 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarBundleManifestGenerator.java +++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarBundleManifestGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.warurl.internal; diff --git a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java index f9502a4251e..d54bbcfbf16 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java +++ b/jetty-osgi/jetty-osgi-boot-warurl/src/main/java/org/eclipse/jetty/osgi/boot/warurl/internal/WarURLConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.warurl.internal; diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-http.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-http.xml index c5925ef6b77..303ada127b6 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-http.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-http.xml @@ -3,13 +3,13 @@ - + - + diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml index 17f38f2776d..d4bac27248f 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml @@ -49,7 +49,7 @@ 8192 true false - 4096 + 1024 --> @@ -61,7 +61,7 @@ - + @@ -96,7 +96,7 @@ org.eclipse.jetty.webapp.JmxConfiguration org.eclipse.jetty.osgi.annotations.AnnotationConfiguration org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.javax.server.JavaxWebSocketConfiguration + org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketConfiguration org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration org.eclipse.jetty.osgi.boot.OSGiMetaInfConfiguration diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationConfiguration.java index c70a9e7008f..8db88e052e8 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.annotations; @@ -28,13 +28,13 @@ import org.eclipse.jetty.annotations.AnnotationParser.Handler; import org.eclipse.jetty.osgi.boot.OSGiMetaInfConfiguration; import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Extend the AnnotationConfiguration to support OSGi: @@ -43,7 +43,7 @@ import org.osgi.framework.Constants; */ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.AnnotationConfiguration { - private static final Logger LOG = Log.getLogger(org.eclipse.jetty.annotations.AnnotationConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(org.eclipse.jetty.annotations.AnnotationConfiguration.class); public class BundleParserTask extends ParserTask { @@ -126,9 +126,9 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot continue; Resource bundleRes = oparser.indexBundle(bundle); - if (!context.getMetaData().getWebInfJars().contains(bundleRes)) + if (!context.getMetaData().getWebInfResources(false).contains(bundleRes)) { - context.getMetaData().addWebInfJar(bundleRes); + context.getMetaData().addWebInfResource(bundleRes); } if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null) @@ -194,9 +194,6 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot parseBundle(context, parser, webbundle, webbundle); } - /** - * @see org.eclipse.jetty.annotations.AnnotationConfiguration#parseWebInfClasses(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.annotations.AnnotationParser) - */ @Override public void parseWebInfClasses(WebAppContext context, org.eclipse.jetty.annotations.AnnotationParser parser) throws Exception diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java index c457149301c..a28bef28592 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.annotations; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java index d52f5ff4a47..4c7d6b3e8b8 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -30,12 +30,12 @@ import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; import org.osgi.framework.Bundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractContextProvider @@ -45,7 +45,7 @@ import org.osgi.framework.Bundle; */ public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider { - private static final Logger LOG = Log.getLogger(AbstractContextProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); private DeploymentManager _deploymentManager; @@ -208,9 +208,6 @@ public abstract class AbstractContextProvider extends AbstractLifeCycle implemen return _serverWrapper; } - /** - * @see org.eclipse.jetty.deploy.AppProvider#createContextHandler(org.eclipse.jetty.deploy.App) - */ @Override public ContextHandler createContextHandler(App app) throws Exception { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java index 1db95bb2df3..ee52bf382a2 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -27,12 +27,12 @@ import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractOSGiApp @@ -41,7 +41,7 @@ import org.osgi.framework.ServiceRegistration; */ public abstract class AbstractOSGiApp extends App { - private static final Logger LOG = Log.getLogger(AbstractOSGiApp.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractOSGiApp.class); protected Bundle _bundle; protected Dictionary _properties; @@ -175,7 +175,7 @@ public abstract class AbstractOSGiApp extends App } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to find relative override location: {}", bundleOverrideLocation, e); } } if (res != null) diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java index e1b556510c9..cd34e0d677e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -33,8 +33,6 @@ import org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader; import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppClassLoader; @@ -44,6 +42,8 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.PackageAdmin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractWebAppProvider @@ -53,7 +53,7 @@ import org.osgi.service.packageadmin.PackageAdmin; */ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider { - private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); private boolean _parentLoaderPriority; @@ -530,9 +530,6 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement return _deploymentManager; } - /** - * @see org.eclipse.jetty.deploy.AppProvider#setDeploymentManager(org.eclipse.jetty.deploy.DeploymentManager) - */ @Override public void setDeploymentManager(DeploymentManager deploymentManager) { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java index a5873d23dcf..a7a0e60d622 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -28,14 +28,14 @@ import java.util.Map; import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.BundleTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * BundleContextProvider @@ -44,7 +44,7 @@ import org.osgi.util.tracker.BundleTracker; */ public class BundleContextProvider extends AbstractContextProvider implements BundleProvider { - private static final Logger LOG = Log.getLogger(AbstractContextProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); private Map _appMap = new HashMap(); @@ -64,9 +64,6 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu _managedServerName = managedServerName; } - /** - * @see org.osgi.util.tracker.BundleTracker#addingBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent) - */ @Override public Object addingBundle(Bundle bundle, BundleEvent event) { @@ -82,14 +79,11 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to add bundle {}", bundle, e); } return null; } - /** - * @see org.osgi.util.tracker.BundleTracker#removedBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent, java.lang.Object) - */ @Override public void removedBundle(Bundle bundle, BundleEvent event, Object object) { @@ -99,7 +93,7 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to remove bundle {}", bundle, e); } } } @@ -137,7 +131,7 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to unregister {}", _serviceRegForBundles, e); } } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java index 33b36b85186..5fd12fad435 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java index 353f9396a01..ba6d78fd28e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleWebAppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -27,14 +27,14 @@ import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.BundleTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * BundleWebAppProvider @@ -43,7 +43,7 @@ import org.osgi.util.tracker.BundleTracker; */ public class BundleWebAppProvider extends AbstractWebAppProvider implements BundleProvider { - private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); /** * Map of Bundle to App. Used when a Bundle contains a webapp. @@ -64,9 +64,6 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund _managedServerName = managedServerName; } - /** - * @see org.osgi.util.tracker.BundleTracker#addingBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent) - */ @Override public Object addingBundle(Bundle bundle, BundleEvent event) { @@ -82,14 +79,11 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to add bundle {}", bundle, e); } return null; } - /** - * @see org.osgi.util.tracker.BundleTracker#removedBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent, java.lang.Object) - */ @Override public void removedBundle(Bundle bundle, BundleEvent event, Object object) { @@ -99,7 +93,7 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to remove bundle {}", bundle, e); } } } @@ -109,9 +103,6 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund super(wrapper); } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -124,9 +115,6 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund super.doStart(); } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -141,7 +129,7 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to unregister {}", _serviceRegForBundles, e); } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java index 63140b189b3..cb994215815 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -22,13 +22,13 @@ import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHom import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JettyBootstrapActivator @@ -41,7 +41,7 @@ import org.osgi.util.tracker.ServiceTracker; */ public class JettyBootstrapActivator implements BundleActivator { - private static final Logger LOG = Log.getLogger(JettyBootstrapActivator.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyBootstrapActivator.class); private static JettyBootstrapActivator INSTANCE = null; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java index ac6161d7302..40af01b2276 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java index 8af1f54ce92..6386b3a3a87 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -35,8 +35,6 @@ import java.util.regex.Pattern; import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; import org.eclipse.jetty.webapp.Configuration; @@ -45,6 +43,8 @@ import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebInfConfiguration; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * OSGiWebInfConfiguration @@ -53,7 +53,7 @@ import org.osgi.framework.FrameworkUtil; */ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { - private static final Logger LOG = Log.getLogger(WebInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(WebInfConfiguration.class); /** * Comma separated list of symbolic names of bundles that contain tlds that should be considered diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java index 3795396fd8a..69f99200f1e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java index 90fc0daf06a..4877fb6518b 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java index b4a4dc9758d..9eb8b233d4e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java index 35581168bbc..2f75af0de75 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java index f7a2aa7c1a0..a3787f7c7e3 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -29,8 +29,6 @@ import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -39,6 +37,8 @@ import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ServiceContextProvider @@ -47,7 +47,7 @@ import org.osgi.util.tracker.ServiceTracker; */ public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider { - private static final Logger LOG = Log.getLogger(AbstractContextProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); private Map _serviceMap = new HashMap<>(); @@ -66,9 +66,6 @@ public class ServiceContextProvider extends AbstractContextProvider implements S super(bundleContext, filter, null); } - /** - * @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference) - */ @Override public Object addingService(ServiceReference reference) { @@ -77,9 +74,6 @@ public class ServiceContextProvider extends AbstractContextProvider implements S return h; } - /** - * @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object) - */ @Override public void modifiedService(ServiceReference reference, Object service) { @@ -87,9 +81,6 @@ public class ServiceContextProvider extends AbstractContextProvider implements S addingService(reference); } - /** - * @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object) - */ @Override public void removedService(ServiceReference reference, Object service) { @@ -230,7 +221,7 @@ public class ServiceContextProvider extends AbstractContextProvider implements S } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to unregister {}", _serviceRegForServices, e); } } super.doStop(); diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java index 916f3b17a5b..c12e40a4ba0 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java index d5409d479c1..7f0ce92d89e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot; @@ -29,8 +29,6 @@ import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -39,6 +37,8 @@ import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ServiceWebAppProvider @@ -47,7 +47,7 @@ import org.osgi.util.tracker.ServiceTracker; */ public class ServiceWebAppProvider extends AbstractWebAppProvider implements ServiceProvider { - private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); /** * Map of ServiceRef to App. Used when it is an osgi service that is a WebAppContext. @@ -72,9 +72,6 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser super(bundleContext, filter, null); } - /** - * @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference) - */ @Override public Object addingService(ServiceReference reference) { @@ -83,9 +80,6 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser return wac; } - /** - * @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object) - */ @Override public void modifiedService(ServiceReference reference, Object service) { @@ -93,9 +87,6 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser addingService(reference); } - /** - * @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object) - */ @Override public void removedService(ServiceReference reference, Object service) { @@ -229,9 +220,6 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser return false; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -251,9 +239,6 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser super.doStart(); } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -268,7 +253,7 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to unregister {}", _serviceRegForServices, e); } } super.doStop(); diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java index 95f27927ffb..59bcd04a251 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.internal.serverfactory; @@ -26,6 +26,7 @@ import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.StringTokenizer; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; @@ -34,12 +35,12 @@ import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader; import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DefaultJettyAtJettyHomeHelper @@ -53,7 +54,7 @@ import org.osgi.framework.BundleContext; */ public class DefaultJettyAtJettyHomeHelper { - private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class); + private static final Logger LOG = LoggerFactory.getLogger(DefaultJettyAtJettyHomeHelper.class); /** * contains a comma separated list of paths to the etc/jetty-*.xml files @@ -148,9 +149,8 @@ public class DefaultJettyAtJettyHomeHelper LOG.warn("No default jetty created."); return null; } - - //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to - //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing + + //resolve the jetty xml config files List configURLs = jettyHomeDir != null ? getJettyConfigurationURLs(jettyHomeDir) : getJettyConfigurationURLs(jettyHomeBundle, properties); LOG.info("Configuring the default jetty server with {}", configURLs); @@ -174,14 +174,36 @@ public class DefaultJettyAtJettyHomeHelper } Thread.currentThread().setContextClassLoader(cl); - // these properties usually are the ones passed to this type of - // configuration. + //the default server name properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); - Util.setProperty(properties, OSGiServerConstants.JETTY_HOST, System.getProperty(OSGiServerConstants.JETTY_HOST, System.getProperty("jetty.host"))); - Util.setProperty(properties, OSGiServerConstants.JETTY_PORT, System.getProperty(OSGiServerConstants.JETTY_PORT, System.getProperty("jetty.port"))); - Util.setProperty(properties, OSGiServerConstants.JETTY_PORT_SSL, System.getProperty(OSGiServerConstants.JETTY_PORT_SSL, System.getProperty("ssl.port"))); + + //Always set home and base Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, home); Util.setProperty(properties, OSGiServerConstants.JETTY_BASE, base); + + // copy all system properties starting with "jetty." to service properties for the jetty server service. + // these will be used as xml configuration properties. + for (Map.Entry prop : System.getProperties().entrySet()) + { + if (prop.getKey() instanceof String) + { + String skey = (String)prop.getKey(); + //never copy the jetty xml config files into the properties as we pass them explicitly into + //the call to configure, also we set home and base explicitly + if (OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS.equals(skey) || + OSGiServerConstants.JETTY_HOME.equals(skey) || + OSGiServerConstants.JETTY_BASE.equals(skey)) + continue; + + if (skey.startsWith("jetty.")) + { + Util.setProperty(properties, skey, prop.getValue()); + } + } + } + + //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to + //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing Server server = ServerInstanceWrapper.configure(null, configURLs, properties); //Register the default Server instance as an OSGi service. @@ -192,7 +214,7 @@ public class DefaultJettyAtJettyHomeHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to start Jetty at Jetty Home", e); throw e; } finally diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java index 03daafe65b9..3e082f89ead 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.internal.serverfactory; @@ -23,11 +23,11 @@ import java.util.Hashtable; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JettyServerServiceTracker @@ -37,11 +37,8 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer; */ public class JettyServerServiceTracker implements ServiceTrackerCustomizer { - private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName()); + private static Logger LOG = LoggerFactory.getLogger(JettyServerServiceTracker.class.getName()); - /** - * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference) - */ @Override public Object addingService(ServiceReference sr) { @@ -68,14 +65,11 @@ public class JettyServerServiceTracker implements ServiceTrackerCustomizer } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to start server {}", name, e); return sr.getBundle().getBundleContext().getService(sr); } } - /** - * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object) - */ @Override public void modifiedService(ServiceReference reference, Object service) { @@ -83,23 +77,20 @@ public class JettyServerServiceTracker implements ServiceTrackerCustomizer addingService(reference); } - /** - * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object) - */ @Override public void removedService(ServiceReference reference, Object service) { if (service instanceof ServerInstanceWrapper) { + ServerInstanceWrapper wrapper = (ServerInstanceWrapper)service; try { - ServerInstanceWrapper wrapper = (ServerInstanceWrapper)service; wrapper.stop(); LOG.info("Stopped Server {}", wrapper.getManagedServerName()); } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to stop server {}", wrapper.getManagedServerName(), e); } } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java index bd20b079fba..e8b2bcb3db2 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.internal.serverfactory; @@ -51,10 +51,10 @@ import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ServerInstanceWrapper @@ -73,7 +73,7 @@ public class ServerInstanceWrapper private static Collection __containerTldBundleDiscoverers = new ArrayList<>(); - private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName()); + private static final Logger LOG = LoggerFactory.getLogger(ServerInstanceWrapper.class.getName()); private final String _managedServerName; @@ -278,7 +278,7 @@ public class ServerInstanceWrapper } catch (Exception x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } throw e; @@ -300,7 +300,7 @@ public class ServerInstanceWrapper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to stop server", e); } } @@ -356,7 +356,7 @@ public class ServerInstanceWrapper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to add BundleAppProvider to DeploymentManager", e); } } @@ -370,7 +370,7 @@ public class ServerInstanceWrapper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to add ServiceWebAppProvider to DeploymentManager", e); } } @@ -383,7 +383,7 @@ public class ServerInstanceWrapper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to add BundleContextProvider to DeploymentManager", e); } } @@ -396,7 +396,7 @@ public class ServerInstanceWrapper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to add ServiceContextProvider to DeploymentManager", e); } } } @@ -438,7 +438,7 @@ public class ServerInstanceWrapper } catch (Throwable mfe) { - LOG.warn(mfe); + LOG.warn("Unable to process legacy lib folder {}", tok, mfe); } } return libURLs; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java index 46c026ff5f1..7a30d6d19d1 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.internal.webapp; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java index 9cfdc747513..6d68c9a4de6 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.internal.webapp; @@ -34,13 +34,13 @@ import javax.servlet.http.HttpServlet; import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelperFactory; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; import org.osgi.framework.BundleReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * OSGiWebappClassLoader @@ -51,7 +51,7 @@ import org.osgi.framework.BundleReference; public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleReference { - private static final Logger __logger = Log.getLogger(OSGiWebappClassLoader.class.getName()); + private static final Logger LOG = LoggerFactory.getLogger(OSGiWebappClassLoader.class.getName()); /** * when a logging framework is setup in the osgi classloaders, it can access @@ -214,7 +214,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe } else { - __logger.info("Did not add " + path + " to the classloader of the webapp " + getContext()); + LOG.info("Did not add " + path + " to the classloader of the webapp " + getContext()); } } } @@ -266,7 +266,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe catch (IOException e) { // nevermind. just trying our best - __logger.ignore(e); + LOG.trace("IGNORED", e); } return true; } @@ -300,7 +300,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe catch (Throwable t) { // humf that will hurt if it does not work. - __logger.warn("Unable to set webappcontext", t); + LOG.warn("Unable to set webappcontext", t); } } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java index d69fca5c306..5db8946f857 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java index d52375109e1..8a9e2c41da9 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleClassLoaderHelperFactory.java @@ -1,25 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * BundleClassLoaderHelperFactory @@ -28,7 +28,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class BundleClassLoaderHelperFactory { - private static final Logger LOG = Log.getLogger(BundleClassLoaderHelperFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(BundleClassLoaderHelperFactory.class); private static BundleClassLoaderHelperFactory _instance = new BundleClassLoaderHelperFactory(); @@ -53,7 +53,7 @@ public class BundleClassLoaderHelperFactory } catch (Throwable t) { - LOG.ignore(t); + LOG.trace("IGNORED", t); } return helper; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java index 81ea9475503..d7a77c2bd11 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java index a9335f1eebc..479a200a78a 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java @@ -1,25 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * BundleFileLocatorHelperFactory @@ -28,7 +28,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class BundleFileLocatorHelperFactory { - private static final Logger LOG = Log.getLogger(BundleFileLocatorHelperFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(BundleFileLocatorHelperFactory.class); private static BundleFileLocatorHelperFactory _instance = new BundleFileLocatorHelperFactory(); @@ -52,7 +52,7 @@ public class BundleFileLocatorHelperFactory } catch (Throwable t) { - LOG.ignore(t); + LOG.trace("IGNORED", t); } return helper; } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java index ed6798e3a94..0f952c9a62d 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/EventSender.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java index f755f85bbbb..1c0938848f4 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/FakeURLClassLoader.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; @@ -52,9 +52,6 @@ public class FakeURLClassLoader extends URLClassLoader return _jars; } - /** - * @see java.lang.Object#toString() - */ @Override public String toString() { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java index 6c7a44d804f..256e4e5aa4f 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; @@ -26,9 +26,9 @@ import java.util.Collections; import java.util.Enumeration; import java.util.List; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * OSGiClassLoader @@ -38,7 +38,7 @@ import org.osgi.framework.Bundle; */ public class OSGiClassLoader extends URLClassLoader { - private static final Logger LOG = Log.getLogger(OSGiClassLoader.class); + private static final Logger LOG = LoggerFactory.getLogger(OSGiClassLoader.class); private Bundle _bundle; private ClassLoader _osgiBundleClassLoader; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/ServerConnectorListener.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/ServerConnectorListener.java index 3e2a3538082..2edfc3bbeeb 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/ServerConnectorListener.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/ServerConnectorListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; @@ -38,9 +38,6 @@ public class ServerConnectorListener extends AbstractLifeCycleListener private Path _filePath; private String _sysPropertyName; - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener#lifeCycleStarted(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStarted(LifeCycle event) { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java index efd3d6321a0..58137bf1a6e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/TldBundleDiscoverer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java index 1938e439389..b5e5b370945 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java index bbc7af2242e..ced85389b5e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils.internal; @@ -23,9 +23,9 @@ import java.lang.reflect.Method; import java.util.List; import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DefaultBundleClassLoaderHelper @@ -35,7 +35,7 @@ import org.osgi.framework.Bundle; */ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper { - private static final Logger LOG = Log.getLogger(BundleClassLoaderHelper.class); + private static final Logger LOG = LoggerFactory.getLogger(BundleClassLoaderHelper.class); private static enum OSGiContainerType { @@ -80,7 +80,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (ClassNotFoundException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } try @@ -91,7 +91,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (ClassNotFoundException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } try @@ -112,7 +112,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (ClassNotFoundException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } try @@ -123,7 +123,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (ClassNotFoundException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } LOG.warn("Unknown OSGi container type"); @@ -153,7 +153,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (ClassNotFoundException e) { - LOG.warn(e); + LOG.warn("Unable to load bundle activator {}", bundleActivator, e); } } @@ -207,6 +207,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper { if (osgiContainer == OSGiContainerType.EquinoxOld) { + String bundleLoaderName = "org.eclipse.osgi.internal.loader.BundleLoader"; try { if (Equinox_BundleHost_getBundleLoader_method == null) @@ -219,19 +220,14 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null) { Equinox_BundleLoader_createClassLoader_method = - bundleLoader.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader", new Class[]{}); + bundleLoader.getClass().getClassLoader().loadClass(bundleLoaderName).getDeclaredMethod("createClassLoader", new Class[]{}); Equinox_BundleLoader_createClassLoader_method.setAccessible(true); } return (ClassLoader)Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[]{}); } - catch (ClassNotFoundException t) - { - LOG.warn(t); - return null; - } catch (Throwable t) { - LOG.warn(t); + LOG.warn("Unable to get equinox bundle classloader", t); return null; } } @@ -252,7 +248,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get equinox luna bundle classloader", e); return null; } } @@ -288,7 +284,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get felix bundle classloader", e); return null; } } @@ -320,21 +316,23 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get field {}", Felix_BundleImpl_m_Modules_Field, e); return null; } } if (Felix_ModuleImpl_m_ClassLoader_Field == null && currentModuleImpl != null) { + String felixFrameworkModuleImplClassName = "org.apache.felix.framework.ModuleImpl"; + String felixFrameworkModuleImplClassLoaderField = "m_classLoader"; try { - Felix_ModuleImpl_m_ClassLoader_Field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField("m_classLoader"); + Felix_ModuleImpl_m_ClassLoader_Field = bundle.getClass().getClassLoader().loadClass(felixFrameworkModuleImplClassName).getDeclaredField(felixFrameworkModuleImplClassLoaderField); Felix_ModuleImpl_m_ClassLoader_Field.setAccessible(true); } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to find field {}.{}", felixFrameworkModuleImplClassName, felixFrameworkModuleImplClassLoaderField, e); return null; } } @@ -351,7 +349,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get field {}", Felix_ModuleImpl_m_ClassLoader_Field, e); return null; } @@ -367,13 +365,13 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get field {}", Felix_ModuleImpl_m_ClassLoader_Field, e); return null; } } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to load old felix container", e); return null; } } @@ -424,7 +422,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to load Concierge platform", e); return null; } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java index 4692074d055..a209767c7a3 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils.internal; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java index fb1415985f9..c7301870d71 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.boot.utils.internal; diff --git a/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorHandlerHelper.java b/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorHandlerHelper.java index e14208c6212..676934b71ab 100644 --- a/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorHandlerHelper.java +++ b/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorHandlerHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.httpservice; diff --git a/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorPageErrorHandler.java b/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorPageErrorHandler.java index 85e22fb065c..aeff8b90a47 100644 --- a/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorPageErrorHandler.java +++ b/jetty-osgi/jetty-osgi-httpservice/src/main/java/org/eclipse/jetty/osgi/httpservice/HttpServiceErrorPageErrorHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.httpservice; @@ -49,7 +49,7 @@ public class HttpServiceErrorPageErrorHandler extends ErrorPageErrorHandler @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) - throws IOException + throws IOException, ServletException { if (HttpServiceErrorHandlerHelper.getCustomErrorHandler() != null) { diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 9deafe864a6..49ce22029ee 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -39,7 +39,18 @@ src/main/context - + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + + + org.apache.maven.plugins diff --git a/jetty-osgi/test-jetty-osgi-context/src/main/java/com/acme/osgi/Activator.java b/jetty-osgi/test-jetty-osgi-context/src/main/java/com/acme/osgi/Activator.java index 63a1ee99048..44109522807 100644 --- a/jetty-osgi/test-jetty-osgi-context/src/main/java/com/acme/osgi/Activator.java +++ b/jetty-osgi/test-jetty-osgi-context/src/main/java/com/acme/osgi/Activator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.osgi; diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index e43a76e22a4..e3b7af48eef 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -19,7 +19,18 @@ src/main/resources - + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + + + org.apache.maven.plugins diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index a213793c34f..ccf17f5a981 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -31,6 +31,18 @@ + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + + + org.apache.maven.plugins diff --git a/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java b/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java index 0c688fe393c..ab85f2b9de1 100644 --- a/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java +++ b/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.osgi; @@ -46,12 +46,9 @@ public class Activator implements BundleActivator { //For test purposes, use a random port Server server = new Server(0); - server.getConnectors()[0].addLifeCycleListener(new AbstractLifeCycleListener() + server.getConnectors()[0].addEventListener(new AbstractLifeCycleListener() { - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener#lifeCycleStarted(org.eclipse.jetty.util.component.LifeCycle) - */ @Override public void lifeCycleStarted(LifeCycle event) { diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index cb9ff9bc9a6..757dd7f09e9 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -36,7 +36,18 @@ src/main/resources - + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + + + org.apache.maven.plugins diff --git a/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java b/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java index 4bfb84e3990..0184d027048 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java +++ b/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.osgi; @@ -45,9 +45,6 @@ public class Activator implements BundleActivator public static class TestServlet extends HttpServlet { - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 4dd970f92dd..d82c7e2dde9 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -94,7 +94,7 @@ org.eclipse.platform org.eclipse.osgi - 3.13.100 + 3.15.100 test @@ -280,25 +280,25 @@ org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api ${project.version} runtime org.eclipse.jetty.websocket - jetty-websocket-common + websocket-jetty-common ${project.version} runtime org.eclipse.jetty.websocket - jetty-websocket-client + websocket-jetty-client ${project.version} runtime org.eclipse.jetty.websocket - javax-websocket-client + websocket-javax-client ${project.version} runtime @@ -310,7 +310,7 @@
      org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} runtime @@ -321,7 +321,7 @@ org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} runtime @@ -409,6 +409,12 @@ jetty-test-helper test + + org.slf4j + slf4j-api + ${slf4j.version} + test + org.slf4j slf4j-log4j12 @@ -471,6 +477,14 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + maven-surefire-plugin diff --git a/jetty-osgi/test-jetty-osgi/src/main/resources/jetty-logging.properties b/jetty-osgi/test-jetty-osgi/src/main/resources/jetty-logging.properties index 147cf004df8..c2be11c689a 100644 --- a/jetty-osgi/test-jetty-osgi/src/main/resources/jetty-logging.properties +++ b/jetty-osgi/test-jetty-osgi/src/main/resources/jetty-logging.properties @@ -1 +1 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +org.eclipse.jetty.LEVEL=INFO \ No newline at end of file diff --git a/jetty-osgi/test-jetty-osgi/src/main/resources/keystore.jks b/jetty-osgi/test-jetty-osgi/src/main/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-osgi/test-jetty-osgi/src/main/resources/keystore.jks and /dev/null differ diff --git a/jetty-osgi/test-jetty-osgi/src/main/resources/truststore.jks b/jetty-osgi/test-jetty-osgi/src/main/resources/truststore.jks deleted file mode 100644 index 839cb8c3515..00000000000 Binary files a/jetty-osgi/test-jetty-osgi/src/main/resources/truststore.jks and /dev/null differ diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml index cd907934b86..5333433aab7 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + boot.context.service.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml index df4f9a29512..b90533d0b60 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + boot.webapp.service.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml index fafa0ecdd18..271f12e042c 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + boot.annotations.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml index 80335e9184a..6cb5d15395a 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml @@ -31,7 +31,7 @@ - + boot.bundle.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml index 856a577d329..4ff583996c4 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-javax-websocket.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + boot.javax.websocket.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml index aeda97879e8..9edaf7b56c0 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + boot.jsp.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml index 3c45c45a368..e1b37e7c70f 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + boot.websocket.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml index 6384118ee3b..6b883c59a0e 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http.xml @@ -3,13 +3,13 @@ - + - + @@ -31,7 +31,7 @@ - + foo.foo diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml index 16984b9bbdf..ad51713fd9c 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2-jdk9.xml @@ -2,7 +2,7 @@ - + diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml index a48b216e4ff..2bf9d1051b1 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http2.xml @@ -2,7 +2,7 @@ - + diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml index 7b408b6dc4d..941216afee1 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml @@ -2,7 +2,7 @@ - + @@ -16,7 +16,7 @@ - + boot.https.port diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml index 077cc7f66cd..178ae88fa36 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml @@ -9,7 +9,7 @@ - + @@ -31,9 +31,9 @@ - / + / - / + / diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-with-custom-class.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-with-custom-class.xml index 9cc5f6f72e7..6c2b9d68082 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-with-custom-class.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-with-custom-class.xml @@ -82,7 +82,7 @@ org.eclipse.jetty.plus.webapp.EnvConfiguration org.eclipse.jetty.webapp.JmxConfiguration org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.javax.server.JavaxWebSocketConfiguration + org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketConfiguration org.eclipse.jetty.osgi.annotations.AnnotationConfiguration org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration org.eclipse.jetty.osgi.boot.OSGiMetaInfConfiguration diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml index 291fccd1873..25f831c57c5 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml @@ -42,8 +42,8 @@ - - + + @@ -70,7 +70,7 @@ - + org.eclipse.jetty.webapp.FragmentConfiguration org.eclipse.jetty.webapp.JettyWebXmlConfiguration @@ -85,7 +85,7 @@ org.eclipse.jetty.webapp.JmxConfiguration org.eclipse.jetty.osgi.annotations.AnnotationConfiguration org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.javax.server.JavaxWebSocketConfiguration + org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketConfiguration org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration org.eclipse.jetty.osgi.boot.OSGiMetaInfConfiguration diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/keystore b/jetty-osgi/test-jetty-osgi/src/test/config/etc/keystore deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-osgi/test-jetty-osgi/src/test/config/etc/keystore and /dev/null differ diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/keystore.p12 b/jetty-osgi/test-jetty-osgi/src/test/config/etc/keystore.p12 new file mode 100644 index 00000000000..7196dcdadc0 Binary files /dev/null and b/jetty-osgi/test-jetty-osgi/src/test/config/etc/keystore.p12 differ diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleEchoSocket.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleEchoSocket.java index 97318efe639..9391c197630 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleEchoSocket.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleEchoSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleJavaxWebSocket.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleJavaxWebSocket.java index 4dd450d77b7..3406dc7aff3 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleJavaxWebSocket.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SimpleJavaxWebSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SomeCustomBean.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SomeCustomBean.java index 3723141a7a8..4000a82e26f 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SomeCustomBean.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/SomeCustomBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootContextAsService.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootContextAsService.java index a0ca1da0667..3e34573a5bc 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootContextAsService.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootContextAsService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java index 26f78507a7d..20aceef34c2 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; @@ -135,14 +135,12 @@ public class TestJettyOSGiBootHTTP2Conscrypt assertNotNull(port); Path path = Paths.get("src", "test", "config"); - File keys = path.resolve("etc").resolve("keystore").toFile(); + File keys = path.resolve("etc").resolve("keystore.p12").toFile(); ClientConnector clientConnector = new ClientConnector(); SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); - sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - sslContextFactory.setTrustStorePath(keys.getAbsolutePath()); sslContextFactory.setKeyStorePath(keys.getAbsolutePath()); - sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setProvider("Conscrypt"); sslContextFactory.setEndpointIdentificationAlgorithm(null); if (JavaVersion.VERSION.getPlatform() < 9) diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java index f124c887b53..37592a392be 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; @@ -129,14 +129,12 @@ public class TestJettyOSGiBootHTTP2JDK9 assertNotNull(port); Path path = Paths.get("src", "test", "config"); - File keys = path.resolve("etc").resolve("keystore").toFile(); + File keys = path.resolve("etc").resolve("keystore.p12").toFile(); ClientConnector clientConnector = new ClientConnector(); SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); - sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - sslContextFactory.setTrustStorePath(keys.getAbsolutePath()); sslContextFactory.setKeyStorePath(keys.getAbsolutePath()); - sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setEndpointIdentificationAlgorithm(null); clientConnector.setSslContextFactory(sslContextFactory); http2Client = new HTTP2Client(clientConnector); diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java index 7efb7dce321..ead1178d1a8 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java index 3912879af14..7ca4598dcac 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; @@ -25,6 +25,8 @@ import javax.inject.Inject; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.util.MultiPartContentProvider; +import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpStatus; import org.junit.Test; import org.junit.runner.RunWith; @@ -131,6 +133,11 @@ public class TestJettyOSGiBootWithAnnotations assertEquals("Response status code", HttpStatus.OK_200, response.getStatus()); content = response.getContentAsString(); TestOSGiUtil.assertContains("Response contents", content, "

      FRAGMENT

      "); + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart("field", new StringContentProvider("foo"), null); + response = client.newRequest("http://127.0.0.1:" + port + "/multi").method("POST") + .content(multiPart).send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); } finally { diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithBundle.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithBundle.java index d0d50b79489..cf367c2b129 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithBundle.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithBundle.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJavaxWebSocket.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJavaxWebSocket.java index 07741e557e7..ddff23f9f30 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJavaxWebSocket.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJavaxWebSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; @@ -107,9 +107,9 @@ public class TestJettyOSGiBootWithJavaxWebSocket @Test public void testWebsocket() throws Exception { - startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.common"); - startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.client"); - startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.server"); + startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.common"); + startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.client"); + startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.server"); startBundle(bundleContext, "org.eclipse.jetty.tests.webapp"); if (Boolean.getBoolean(TestOSGiUtil.BUNDLE_DEBUG)) diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJsp.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJsp.java index 1835982def9..ff1be6e0736 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJsp.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithJsp.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithWebSocket.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithWebSocket.java index 2a438ccecfd..d62a0be2e20 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithWebSocket.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithWebSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java index 5c6339b9021..a5b0022a065 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.osgi.test; @@ -37,7 +37,6 @@ import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.ops4j.pax.exam.CoreOptions; import org.ops4j.pax.exam.Option; @@ -116,15 +115,14 @@ public class TestOSGiUtil if (!StringUtil.isBlank(mavenRepoPath)) { res.add(systemProperty("org.ops4j.pax.url.mvn.localRepository").value(mavenRepoPath)); - res.add( systemProperty( "org.ops4j.pax.url.mvn.localRepository" ).value( mavenRepoPath ) ); - res.add( systemProperty( "org.ops4j.pax.url.mvn.defaultRepositories" ).value( "file://" + mavenRepoPath + "@id=local.repo") ); - res.add( systemProperty( "org.ops4j.pax.url.mvn.useFallbackRepositories").value( Boolean.FALSE.toString() ) ); - res.add( systemProperty( "org.ops4j.pax.url.mvn.repositories").value( "+https://repo1.maven.org/maven2@id=maven.central.repo" ) ); + res.add(systemProperty("org.ops4j.pax.url.mvn.defaultRepositories").value("file://" + mavenRepoPath + "@id=local.repo")); + res.add(systemProperty("org.ops4j.pax.url.mvn.useFallbackRepositories").value(Boolean.FALSE.toString())); + res.add(systemProperty("org.ops4j.pax.url.mvn.repositories").value("+https://repo1.maven.org/maven2@id=maven.central.repo")); } String settingsFilePath = System.getProperty("settingsFilePath"); if (!StringUtil.isBlank(settingsFilePath)) { - res.add( systemProperty( "org.ops4j.pax.url.mvn.settings" ).value( System.getProperty( "settingsFilePath" ) ) ); + res.add(systemProperty("org.ops4j.pax.url.mvn.settings").value(System.getProperty("settingsFilePath"))); } res.add(mavenBundle().groupId("org.eclipse.jetty.toolchain").artifactId("jetty-servlet-api").versionAsInProject().start()); res.add(mavenBundle().groupId("org.ow2.asm").artifactId("asm").versionAsInProject().start()); @@ -133,6 +131,8 @@ public class TestOSGiUtil res.add(mavenBundle().groupId("org.apache.aries.spifly").artifactId("org.apache.aries.spifly.dynamic.bundle").versionAsInProject().start()); res.add(mavenBundle().groupId("jakarta.annotation").artifactId("jakarta.annotation-api").versionAsInProject().start()); res.add(mavenBundle().groupId("org.apache.geronimo.specs").artifactId("geronimo-jta_1.1_spec").version("1.1.1").start()); + res.add(mavenBundle().groupId("org.slf4j").artifactId("slf4j-api").versionAsInProject().noStart()); + res.add(mavenBundle().groupId("org.slf4j").artifactId("slf4j-log4j12").versionAsInProject().noStart()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-util").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-deploy").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-server").versionAsInProject().start()); @@ -148,16 +148,17 @@ public class TestOSGiUtil res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-plus").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-annotations").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-core").versionAsInProject().start()); - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("jetty-websocket-api").versionAsInProject().start()); - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("jetty-websocket-common").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-servlet").versionAsInProject().start()); - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("jetty-websocket-server").versionAsInProject().start()); - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("jetty-websocket-client").versionAsInProject().start()); - - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("javax-websocket-common").versionAsInProject().noStart()); - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("javax-websocket-client").versionAsInProject().noStart()); - res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("javax-websocket-server").versionAsInProject().noStart()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util").versionAsInProject().start()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-api").versionAsInProject().start()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-server").versionAsInProject().start()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-client").versionAsInProject().start()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-common").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.toolchain").artifactId("jetty-javax-websocket-api").versionAsInProject().noStart()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-javax-server").versionAsInProject().noStart()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-javax-client").versionAsInProject().noStart()); + res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-javax-common").versionAsInProject().noStart()); + res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("jetty-osgi-boot").versionAsInProject().start()); return res; } @@ -195,18 +196,18 @@ public class TestOSGiUtil protected static Bundle getBundle(BundleContext bundleContext, String symbolicName) { - Map _bundles = new HashMap<>(); + Map bundles = new HashMap<>(); for (Bundle b : bundleContext.getBundles()) { - Bundle prevBundle = _bundles.put(b.getSymbolicName(), b); - String err = prevBundle != null ? "2 versions of the bundle " + b.getSymbolicName() - + " " - + b.getHeaders().get("Bundle-Version") - + " and " - + prevBundle.getHeaders().get("Bundle-Version") : ""; + Bundle prevBundle = bundles.put(b.getSymbolicName(), b); + String err = prevBundle != null ? "2 versions of the bundle " + b.getSymbolicName() + + " " + + b.getHeaders().get("Bundle-Version") + + " and " + + prevBundle.getHeaders().get("Bundle-Version") : ""; assertNull(err, prevBundle); } - return _bundles.get(symbolicName); + return bundles.get(symbolicName); } protected static void assertActiveBundle(BundleContext bundleContext, String symbolicName) throws Exception @@ -234,16 +235,16 @@ public class TestOSGiUtil { diagnoseNonActiveOrNonResolvedBundle(b); } - assertTrue("Bundle: " + b - + " (state should be " - + "ACTIVE[" - + Bundle.ACTIVE - + "] or RESOLVED[" - + Bundle.RESOLVED - + "]" - + ", but was [" - + b.getState() - + "])", (b.getState() == Bundle.ACTIVE) || (b.getState() == Bundle.RESOLVED)); + assertTrue("Bundle: " + b + + " (state should be " + + "ACTIVE[" + + Bundle.ACTIVE + + "] or RESOLVED[" + + Bundle.RESOLVED + + "]" + + ", but was [" + + b.getState() + + "])", (b.getState() == Bundle.ACTIVE) || (b.getState() == Bundle.RESOLVED)); } } @@ -304,9 +305,7 @@ public class TestOSGiUtil options.add(mavenBundle().groupId("org.slf4j").artifactId("jul-to-slf4j").versionAsInProject().start()); options.add(mavenBundle().groupId("org.slf4j").artifactId("slf4j-log4j12").versionAsInProject().start()); options.add(mavenBundle().groupId("log4j").artifactId("log4j").versionAsInProject().start()); - options.add(systemProperty("org.eclipse.jetty.util.log.class").value(Slf4jLog.class.getName())); */ - options.add(systemProperty("org.eclipse.jetty.util.log.class").value(StdErrLog.class.getName())); options.add(systemProperty("org.eclipse.jetty.LEVEL").value("INFO")); return options; } diff --git a/jetty-osgi/test-jetty-osgi/src/test/resources/log4j.properties b/jetty-osgi/test-jetty-osgi/src/test/resources/log4j.properties deleted file mode 100644 index 8bcbd0700c6..00000000000 --- a/jetty-osgi/test-jetty-osgi/src/test/resources/log4j.properties +++ /dev/null @@ -1,16 +0,0 @@ -# LOG4J levels: OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -# -log4j.rootLogger=ALL,CONSOLE - -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -#log4j.appender.CONSOLE.threshold=INFO -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -#log4j.appender.CONSOLE.layout.ConversionPattern=%d %t [%5p][%c{1}] %m%n -log4j.appender.CONSOLE.layout.ConversionPattern=%d [%5p][%c] %m%n - -# Level tuning -# log4j.logger.org.eclipse.jetty=DEBUG -# log4j.logger.org.eclipse.jetty.security=DEBUG -log4j.logger.shaded.org.eclipse.aether=WARN -log4j.logger.shaded.org.apache.http=WARN -log4j.logger.org.ops4j=WARN diff --git a/jetty-osgi/test-jetty-osgi/src/test/resources/log4j.xml b/jetty-osgi/test-jetty-osgi/src/test/resources/log4j.xml new file mode 100644 index 00000000000..fd9c89961b1 --- /dev/null +++ b/jetty-osgi/test-jetty-osgi/src/test/resources/log4j.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 045a9e76671..8d4198686bb 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -48,6 +48,11 @@ jakarta.transaction jakarta.transaction-api
      + + org.apache.derby + derby + test + org.eclipse.jetty jetty-jndi @@ -58,11 +63,13 @@ jetty-webapp ${project.version} - - org.apache.derby - derby - 10.1.2.1 + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl test diff --git a/jetty-plus/src/main/java/module-info.java b/jetty-plus/src/main/java/module-info.java index a414bb9bd7c..0db6561deb0 100644 --- a/jetty-plus/src/main/java/module-info.java +++ b/jetty-plus/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.plus.webapp.EnvConfiguration; @@ -27,18 +27,14 @@ module org.eclipse.jetty.plus exports org.eclipse.jetty.plus.security; exports org.eclipse.jetty.plus.webapp; - requires java.naming; - requires java.transaction; - requires jetty.servlet.api; requires org.eclipse.jetty.jndi; - requires org.eclipse.jetty.security; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.webapp; - requires org.eclipse.jetty.xml; + requires transitive org.eclipse.jetty.webapp; + requires org.slf4j; // Only required if using DataSourceLoginService. requires static java.sql; + // Only required if using Transaction. + requires static java.transaction; // Only required if using RunAs. requires static org.eclipse.jetty.servlet; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java index 33965713894..b4ff90919a7 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; @@ -32,13 +32,13 @@ import javax.servlet.ServletContainerInitializer; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ContainerInitializer { - private static final Logger LOG = Log.getLogger(ContainerInitializer.class); + private static final Logger LOG = LoggerFactory.getLogger(ContainerInitializer.class); protected final ServletContainerInitializer _target; protected final Class[] _interestedTypes; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java index 81703dc21f7..ff71908e735 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/Injection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; @@ -27,8 +27,8 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import org.eclipse.jetty.util.IntrospectionUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Injection @@ -39,7 +39,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class Injection { - private static final Logger LOG = Log.getLogger(Injection.class); + private static final Logger LOG = LoggerFactory.getLogger(Injection.class); private final Class _targetClass; private final String _jndiName; @@ -205,7 +205,7 @@ public class Injection } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to inject field {} with {}", field, injectable, e); throw new IllegalStateException("Inject failed for field " + field.getName()); } } @@ -227,7 +227,7 @@ public class Injection } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to inject method {} with {}", method, injectable, e); throw new IllegalStateException("Inject failed for method " + method.getName()); } } diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java index 90eec10505f..7d7133b3f7d 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/InjectionCollection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; @@ -21,15 +21,13 @@ package org.eclipse.jetty.plus.annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Iterator; -import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * InjectionCollection @@ -41,7 +39,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class InjectionCollection { - private static final Logger LOG = Log.getLogger(InjectionCollection.class); + private static final Logger LOG = LoggerFactory.getLogger(InjectionCollection.class); public static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection"; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java index 562c403f235..4f1939e928a 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java index 8c3a6330125..a5de0b0467d 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java @@ -1,37 +1,34 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * LifeCycleCallbackCollection @@ -46,7 +43,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class LifeCycleCallbackCollection { - private static final Logger LOG = Log.getLogger(LifeCycleCallbackCollection.class); + private static final Logger LOG = LoggerFactory.getLogger(LifeCycleCallbackCollection.class); public static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection"; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PostConstructCallback.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PostConstructCallback.java index 662da987cef..a5df1454d54 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PostConstructCallback.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PostConstructCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PreDestroyCallback.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PreDestroyCallback.java index f9f2583bdf7..3e0132bfa48 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PreDestroyCallback.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/PreDestroyCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; @@ -21,15 +21,15 @@ package org.eclipse.jetty.plus.annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PreDestroyCallback */ public class PreDestroyCallback extends LifeCycleCallback { - private static final Logger LOG = Log.getLogger(PreDestroyCallback.class); + private static final Logger LOG = LoggerFactory.getLogger(PreDestroyCallback.class); /** * @param clazz the class object to be injected diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAs.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAs.java index a71f48bc35d..f3ba59928b4 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAs.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAs.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAsCollection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAsCollection.java index c7b268a05f9..45305b17ec2 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAsCollection.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/RunAsCollection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; @@ -22,15 +22,15 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * RunAsCollection */ public class RunAsCollection { - private static final Logger LOG = Log.getLogger(RunAsCollection.class); + private static final Logger LOG = LoggerFactory.getLogger(RunAsCollection.class); public static final String RUNAS_COLLECTION = "org.eclipse.jetty.runAsCollection"; private ConcurrentMap _runAsMap = new ConcurrentHashMap();//map of classname to run-as diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/package-info.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/package-info.java index 6c03d84a89e..dbbdb82525e 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/package-info.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/EnvEntry.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/EnvEntry.java index ef1eb07cc5f..6c472ee7b87 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/EnvEntry.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/EnvEntry.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Link.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Link.java index 2bce192f63c..efb7cff816d 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Link.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Link.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingDump.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingDump.java index 5ec65b403b6..169867beb67 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingDump.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingDump.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java index a1da4a8d45d..95e1961bd3f 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntry.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; @@ -26,8 +26,8 @@ import javax.naming.NameParser; import javax.naming.NamingException; import org.eclipse.jetty.jndi.NamingUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * NamingEntry @@ -42,7 +42,7 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class NamingEntry { - private static final Logger LOG = Log.getLogger(NamingEntry.class); + private static final Logger LOG = LoggerFactory.getLogger(NamingEntry.class); public static final String __contextName = "__"; //all NamingEntries stored in context called "__" protected final Object _scope; protected final String _jndiName; //the name representing the object associated with the NamingEntry @@ -115,7 +115,7 @@ public abstract class NamingEntry } catch (NamingException e) { - LOG.warn(e); + LOG.warn("Unable to unbind ENC", e); } } @@ -134,7 +134,7 @@ public abstract class NamingEntry } catch (NamingException e) { - LOG.warn(e); + LOG.warn("Unable to release: {} and {}", _objectNameString, _namingEntryNameString, e); } } diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java index bae499699c1..89dabeed499 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/NamingEntryUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; @@ -31,12 +31,12 @@ import javax.naming.NamingEnumeration; import javax.naming.NamingException; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NamingEntryUtil { - private static final Logger LOG = Log.getLogger(NamingEntryUtil.class); + private static final Logger LOG = LoggerFactory.getLogger(NamingEntryUtil.class); /** * Link a name in a webapp's java:/comp/evn namespace to a pre-existing @@ -196,7 +196,7 @@ public class NamingEntryUtil } catch (NamingException e) { - LOG.warn(e); + LOG.warn("Unable to get name for scope {}", scope, e); return null; } } diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Resource.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Resource.java index e82f77edaa3..d6eb39308de 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Resource.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Resource.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java index 489d9ea38c6..384d69455fd 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/Transaction.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; @@ -26,8 +26,8 @@ import javax.naming.NamingException; import javax.transaction.UserTransaction; import org.eclipse.jetty.jndi.NamingUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Transaction @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class Transaction extends NamingEntry { - private static final Logger LOG = Log.getLogger(Transaction.class); + private static final Logger LOG = LoggerFactory.getLogger(Transaction.class); public static final String USER_TRANSACTION = "UserTransaction"; public static void bindToENC() @@ -109,7 +109,7 @@ public class Transaction extends NamingEntry } catch (NamingException e) { - LOG.warn(e); + LOG.warn("Unable to unbind java:comp/{}", getJndiName(), e); } } } diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/package-info.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/package-info.java index f73fd17908b..c0c8bbc27f4 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/package-info.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/jndi/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java index 9419a5c65c7..6d486fc45f1 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/DataSourceLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.security; @@ -36,9 +36,9 @@ import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.security.AbstractLoginService; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DataSourceUserRealm @@ -48,7 +48,7 @@ import org.eclipse.jetty.util.security.Credential; */ public class DataSourceLoginService extends AbstractLoginService { - private static final Logger LOG = Log.getLogger(DataSourceLoginService.class); + private static final Logger LOG = LoggerFactory.getLogger(DataSourceLoginService.class); private String _jndiName = "javax.sql.DataSource/default"; private DataSource _datasource; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/package-info.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/package-info.java index 8a439ae8d8a..5d45ff23d9f 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/package-info.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/security/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java index 7237902ce6f..20f22c47d90 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/EnvConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.webapp; @@ -36,8 +36,6 @@ import org.eclipse.jetty.jndi.local.localContextRoot; import org.eclipse.jetty.plus.jndi.EnvEntry; import org.eclipse.jetty.plus.jndi.NamingDump; import org.eclipse.jetty.plus.jndi.NamingEntryUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.FragmentConfiguration; @@ -47,13 +45,15 @@ import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebXmlConfiguration; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * EnvConfiguration */ public class EnvConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(EnvConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(EnvConfiguration.class); private static final String JETTY_ENV_BINDINGS = "org.eclipse.jetty.jndi.EnvConfiguration"; private Resource jettyEnvXmlResource; @@ -189,7 +189,7 @@ public class EnvConfiguration extends AbstractConfiguration } catch (NameNotFoundException e) { - LOG.warn(e); + LOG.warn("Unable to destroy InitialContext", e); } finally { @@ -214,7 +214,7 @@ public class EnvConfiguration extends AbstractConfiguration } catch (NameNotFoundException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); LOG.debug("No jndi entries scoped to webapp {}", context); } catch (NamingException e) diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java index 6fd0ca0f33e..93efd634941 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.webapp; @@ -27,21 +27,21 @@ import org.eclipse.jetty.jndi.NamingContext; import org.eclipse.jetty.plus.annotation.InjectionCollection; import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; import org.eclipse.jetty.plus.jndi.Transaction; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.FragmentConfiguration; import org.eclipse.jetty.webapp.JettyWebXmlConfiguration; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebXmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Configuration */ public class PlusConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(PlusConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(PlusConfiguration.class); private Integer _key; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDecorator.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDecorator.java index 51f6ac1609e..6c5d6a74bf7 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDecorator.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDecorator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.webapp; @@ -22,16 +22,16 @@ import org.eclipse.jetty.plus.annotation.InjectionCollection; import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; import org.eclipse.jetty.plus.annotation.RunAsCollection; import org.eclipse.jetty.util.Decorator; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PlusDecorator */ public class PlusDecorator implements Decorator { - private static final Logger LOG = Log.getLogger(PlusDecorator.class); + private static final Logger LOG = LoggerFactory.getLogger(PlusDecorator.class); protected WebAppContext _context; diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java index e3f0d3bde4c..003e7cc1ae6 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessor.java @@ -1,27 +1,30 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.webapp; import java.util.Iterator; +import java.util.Objects; + import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; +import javax.naming.NamingException; import org.eclipse.jetty.jndi.NamingUtil; import org.eclipse.jetty.plus.annotation.Injection; @@ -35,22 +38,23 @@ import org.eclipse.jetty.plus.jndi.EnvEntry; import org.eclipse.jetty.plus.jndi.Link; import org.eclipse.jetty.plus.jndi.NamingEntry; import org.eclipse.jetty.plus.jndi.NamingEntryUtil; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.Descriptor; import org.eclipse.jetty.webapp.FragmentDescriptor; import org.eclipse.jetty.webapp.IterativeDescriptorProcessor; import org.eclipse.jetty.webapp.Origin; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PlusDescriptorProcessor */ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor { - private static final Logger LOG = Log.getLogger(PlusDescriptorProcessor.class); + private static final Logger LOG = LoggerFactory.getLogger(PlusDescriptorProcessor.class); public PlusDescriptorProcessor() { @@ -69,9 +73,6 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor } } - /** - * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#start(WebAppContext, org.eclipse.jetty.webapp.Descriptor) - */ @Override public void start(WebAppContext context, Descriptor descriptor) { @@ -98,9 +99,6 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor } } - /** - * {@inheritDoc} - */ @Override public void end(WebAppContext context, Descriptor descriptor) { @@ -121,14 +119,6 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor String type = node.getString("env-entry-type", false, true); String valueStr = node.getString("env-entry-value", false, true); - //if there's no value there's no point in making a jndi entry - //nor processing injection entries - if (valueStr == null || valueStr.equals("")) - { - LOG.warn("No value for env-entry-name " + name); - return; - } - Origin o = context.getMetaData().getOrigin("env-entry." + name); switch (o) { @@ -136,14 +126,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor { //no descriptor has configured an env-entry of this name previously context.getMetaData().setOrigin("env-entry." + name, descriptor); - //the javaee_5.xsd says that the env-entry-type is optional - //if there is an element, because you can get - //type from the element, but what to do if there is more - //than one element, do you just pick the type - //of the first one? - addInjections(context, descriptor, node, name, TypeUtil.fromName(type)); - Object value = TypeUtil.valueOf(type, valueStr); - bindEnvEntry(name, value); + makeEnvEntryInjectionsAndBindings(context, descriptor, node, name, type, valueStr); break; } case WebXml: @@ -158,9 +141,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor //We're processing web-defaults, web.xml or web-override. Any of them can //set or change the env-entry. context.getMetaData().setOrigin("env-entry." + name, descriptor); - addInjections(context, descriptor, node, name, TypeUtil.fromName(type)); - Object value = TypeUtil.valueOf(type, valueStr); - bindEnvEntry(name, value); + makeEnvEntryInjectionsAndBindings(context, descriptor, node, name, type, valueStr); } else { @@ -721,6 +702,9 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor */ public void addInjections(WebAppContext context, Descriptor descriptor, XmlParser.Node node, String jndiName, Class valueClass) { + Objects.requireNonNull(context); + Objects.requireNonNull(node); + Iterator itor = node.iterator("injection-target"); while (itor.hasNext()) @@ -754,8 +738,9 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor injections.add(injection); //Record which was the first descriptor to declare an injection for this name - if (context.getMetaData().getOriginDescriptor(node.getTag() + "." + jndiName + ".injection") == null) - context.getMetaData().setOrigin(node.getTag() + "." + jndiName + ".injection", descriptor); + String name = node.getTag() + "." + jndiName + ".injection"; + if (context.getMetaData().getOriginDescriptor(name) == null) + context.getMetaData().setOrigin(name, descriptor); } catch (ClassNotFoundException e) { @@ -771,31 +756,59 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor */ public void bindEnvEntry(String name, Object value) throws Exception { - InitialContext ic = null; - boolean bound = false; - //check to see if we bound a value and an EnvEntry with this name already - //when we processed the server and the webapp's naming environment - //@see EnvConfiguration.bindEnvEntries() - ic = new InitialContext(); + InitialContext ic = new InitialContext(); + Context envCtx = (Context)ic.lookup("java:comp/env"); + NamingUtil.bind(envCtx, name, value); + } + + /** + * Make injections and any java:comp/env bindings necessary given an env-entry declaration. + * The handling of env-entries is different to other resource declarations like resource-ref, resource-env-ref etc + * because we allow the EnvEntry (@see org.eclipse.jetty.plus.jndi.EnvEntry) class that is configured externally to the webapp + * to specify a value that can override a value present in a web.xml descriptor. + * + * @param context the WebAppContext of the env-entry + * @param descriptor the web.xml, web-default.xml, web-override.xml or web-fragment.xml + * @param node the parsed xml representation of the env-entry declaration + * @param name the name field of the env-entry + * @param type the type field of the env-entry + * @param value the value field of the env-entry + * @throws Exception + */ + public void makeEnvEntryInjectionsAndBindings(WebAppContext context, Descriptor descriptor, XmlParser.Node node, String name, String type, String value) throws Exception + { + InitialContext ic = new InitialContext(); try { - NamingEntry ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntryUtil.makeNamingEntryName(ic.getNameParser(""), name)); - if (ne != null && ne instanceof EnvEntry) + EnvEntry envEntry = (EnvEntry)ic.lookup("java:comp/env/" + NamingEntryUtil.makeNamingEntryName(ic.getNameParser(""), name)); + + if (StringUtil.isEmpty(value)) { - EnvEntry ee = (EnvEntry)ne; - bound = ee.isOverrideWebXml(); + //There is an empty or missing value in the env-entry: + //If there is an existing EnvEntry (eg from a declaration in jetty-env.xml) that is override=true, then + //we make the injection, but we can skip the rebinding becase we want to use the value already bound. + //If there isn't an existing EnvEntry then there is nothing to do: according to the spec we do not make + //an injection if the env-entry value is missing, and of course there is no value to rebind. + if (envEntry != null && envEntry.isOverrideWebXml()) + addInjections(context, descriptor, node, name, TypeUtil.fromName(type)); + } + else + { + //There is a value for the env-entry: + //According to the spec, we need to make an injection (if one is present). + //If there is an existing EnvEntry(eg from a declaration in jetty-env.xml) that is override=false, then + //we need to rebind name with the value from web.xml. + addInjections(context, descriptor, node, name, TypeUtil.fromName(type)); + + if (envEntry == null || !envEntry.isOverrideWebXml()) + bindEnvEntry(name, TypeUtil.valueOf(type, value)); } } catch (NameNotFoundException e) { - bound = false; - } - - if (!bound) - { - //either nothing was bound or the value from web.xml should override - Context envCtx = (Context)ic.lookup("java:comp/env"); - NamingUtil.bind(envCtx, name, value); + //No matching EnvEntry has previously been bound so make the injection and do the binding with the value from web.xml + addInjections(context, descriptor, node, name, TypeUtil.fromName(type)); + bindEnvEntry(name, TypeUtil.valueOf(type, value)); } } diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/package-info.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/package-info.java index f2978931063..1a74649d50d 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/package-info.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollectionTest.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollectionTest.java index a9369c4357f..f17b57da2ae 100644 --- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollectionTest.java +++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollectionTest.java @@ -1,37 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.annotation; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.anEmptyMap; -import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.hasKey; -import static org.hamcrest.Matchers.hasSize; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.fail; - import java.lang.reflect.Method; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.fail; + public class LifeCycleCallbackCollectionTest { diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/NamingEntryUtilTest.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/NamingEntryUtilTest.java index 50fdb153186..35611c10767 100644 --- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/NamingEntryUtilTest.java +++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/NamingEntryUtilTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java index 07d02585215..c494a107d73 100644 --- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java +++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntries.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java index 95c834744de..693ebbfaebc 100644 --- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java +++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/jndi/TestNamingEntryUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.jndi; diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessorTest.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessorTest.java index 0ee1bfb773a..0386fdcb6ca 100644 --- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessorTest.java +++ b/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/PlusDescriptorProcessorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.plus.webapp; @@ -22,7 +22,14 @@ import java.lang.reflect.InvocationTargetException; import java.net.URL; import javax.naming.Context; import javax.naming.InitialContext; +import javax.naming.Name; +import org.eclipse.jetty.jndi.NamingUtil; +import org.eclipse.jetty.plus.annotation.Injection; +import org.eclipse.jetty.plus.annotation.InjectionCollection; +import org.eclipse.jetty.plus.jndi.EnvEntry; +import org.eclipse.jetty.plus.jndi.NamingEntryUtil; +import org.eclipse.jetty.util.IntrospectionUtil; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.Descriptor; import org.eclipse.jetty.webapp.FragmentDescriptor; @@ -40,6 +47,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -49,6 +57,7 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class PlusDescriptorProcessorTest { + protected static final Class[] STRING_ARG = new Class[]{String.class}; protected WebDescriptor webDescriptor; protected FragmentDescriptor fragDescriptor1; protected FragmentDescriptor fragDescriptor2; @@ -56,6 +65,65 @@ public class PlusDescriptorProcessorTest protected FragmentDescriptor fragDescriptor4; protected WebAppContext context; + public static class TestInjections + { + private String foo; + private String bah; + private String empty; + private String vacuum; + private String webXmlOnly; + + public String getWebXmlOnly() + { + return webXmlOnly; + } + + public void setWebXmlOnly(String webXmlOnly) + { + this.webXmlOnly = webXmlOnly; + } + + public String getVacuum() + { + return vacuum; + } + + public void setVacuum(String val) + { + vacuum = val; + } + + public String getEmpty() + { + return empty; + } + + public void setEmpty(String val) + { + empty = val; + } + + public void setFoo(String val) + { + foo = val; + } + + public String getFoo() + { + return foo; + } + + public String getBah() + { + return bah; + } + + public void setBah(String val) + { + bah = val; + } + } + @BeforeEach public void setUp() throws Exception { @@ -63,31 +131,63 @@ public class PlusDescriptorProcessorTest context.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()}); context.preConfigure(); context.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), context)); + context.getServerClassMatcher().exclude("org.eclipse.jetty.plus.webapp."); //need visbility of the TestInjections class ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(context.getClassLoader()); Context icontext = new InitialContext(); Context compCtx = (Context)icontext.lookup("java:comp"); - compCtx.createSubcontext("env"); - Thread.currentThread().setContextClassLoader(oldLoader); + Context envCtx = compCtx.createSubcontext("env"); + @SuppressWarnings("unused") org.eclipse.jetty.plus.jndi.Resource ds = new org.eclipse.jetty.plus.jndi.Resource(context, "jdbc/mydatasource", new Object()); + + //An EnvEntry that should override any value supplied in a web.xml file + org.eclipse.jetty.plus.jndi.EnvEntry fooStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("foo", "FOO", true); + doEnvConfiguration(envCtx, fooStringEnvEntry); + + //An EnvEntry that should NOT override any value supplied in a web.xml file + org.eclipse.jetty.plus.jndi.EnvEntry bahStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("bah", "BAH", false); + doEnvConfiguration(envCtx, bahStringEnvEntry); + + //An EnvEntry that will override an empty value in web.xml + org.eclipse.jetty.plus.jndi.EnvEntry emptyStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("empty", "EMPTY", true); + doEnvConfiguration(envCtx, emptyStringEnvEntry); + + //An EnvEntry that will NOT override an empty value in web.xml + org.eclipse.jetty.plus.jndi.EnvEntry vacuumStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("vacuum", "VACUUM", false); + doEnvConfiguration(envCtx, vacuumStringEnvEntry); URL webXml = Thread.currentThread().getContextClassLoader().getResource("web.xml"); webDescriptor = new WebDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(webXml)); - webDescriptor.parse(); + webDescriptor.parse(WebDescriptor.getParser(false)); URL frag1Xml = Thread.currentThread().getContextClassLoader().getResource("web-fragment-1.xml"); fragDescriptor1 = new FragmentDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(frag1Xml)); - fragDescriptor1.parse(); + fragDescriptor1.parse(WebDescriptor.getParser(false)); URL frag2Xml = Thread.currentThread().getContextClassLoader().getResource("web-fragment-2.xml"); fragDescriptor2 = new FragmentDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(frag2Xml)); - fragDescriptor2.parse(); + fragDescriptor2.parse(WebDescriptor.getParser(false)); URL frag3Xml = Thread.currentThread().getContextClassLoader().getResource("web-fragment-3.xml"); fragDescriptor3 = new FragmentDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(frag3Xml)); - fragDescriptor3.parse(); + fragDescriptor3.parse(WebDescriptor.getParser(false)); URL frag4Xml = Thread.currentThread().getContextClassLoader().getResource("web-fragment-4.xml"); fragDescriptor4 = new FragmentDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(frag4Xml)); - fragDescriptor4.parse(); + fragDescriptor4.parse(WebDescriptor.getParser(false)); + Thread.currentThread().setContextClassLoader(oldLoader); + } + + /** + * Do the kind of processing that EnvConfiguration would do. + * + * @param envCtx the java:comp/env context + * @param envEntry the EnvEntry + * @throws Exception + */ + private void doEnvConfiguration(Context envCtx, EnvEntry envEntry) throws Exception + { + envEntry.bindToENC(envEntry.getJndiName()); + Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, envEntry); + NamingUtil.bind(envCtx, namingEntryName.toString(), envEntry); } @AfterEach @@ -143,6 +243,59 @@ public class PlusDescriptorProcessorTest Thread.currentThread().setContextClassLoader(oldLoader); } } + + @Test + public void testEnvEntries() throws Exception + { + ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(context.getClassLoader()); + try + { + PlusDescriptorProcessor pdp = new PlusDescriptorProcessor(); + //process web.xml + pdp.process(context, webDescriptor); + InjectionCollection injections = (InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION); + assertNotNull(injections); + + //check that there is an injection for "foo" with the value from the overriding EnvEntry of "FOO" + Injection foo = injections.getInjection("foo", TestInjections.class, + IntrospectionUtil.findMethod(TestInjections.class, "setFoo", STRING_ARG, false, true), + String.class); + assertNotNull(foo); + assertEquals("FOO", foo.lookupInjectedValue()); + + //check that there is an injection for "bah" with the value from web.xml of "beer" + Injection bah = injections.getInjection("bah", TestInjections.class, + IntrospectionUtil.findMethod(TestInjections.class, "setBah", STRING_ARG, false, true), + String.class); + assertNotNull(bah); + assertEquals("beer", bah.lookupInjectedValue()); + + //check that there is an injection for "empty" with the value from the overriding EnvEntry of "EMPTY" + Injection empty = injections.getInjection("empty", TestInjections.class, + IntrospectionUtil.findMethod(TestInjections.class, "setEmpty", STRING_ARG, false, true), + String.class); + assertNotNull(empty); + assertEquals("EMPTY", empty.lookupInjectedValue()); + + //check that there is NOT an injection for "vacuum" + Injection vacuum = injections.getInjection("vacuum", TestInjections.class, + IntrospectionUtil.findMethod(TestInjections.class, "setVacuum", STRING_ARG, false, true), + String.class); + assertNull(vacuum); + + //check that there is an injection for "webxmlonly" with the value from web.xml of "WEBXMLONLY" + Injection webXmlOnly = injections.getInjection("webxmlonly", TestInjections.class, + IntrospectionUtil.findMethod(TestInjections.class, "setWebXmlOnly", STRING_ARG, false, true), + String.class); + assertNotNull(webXmlOnly); + assertEquals("WEBXMLONLY", webXmlOnly.lookupInjectedValue()); + } + finally + { + Thread.currentThread().setContextClassLoader(oldLoader); + } + } @Test public void testMismatchedFragmentResourceDeclarations() diff --git a/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java b/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java deleted file mode 100644 index 353f19b5af3..00000000000 --- a/jetty-plus/src/test/java/org/eclipse/jetty/plus/webapp/TestConfiguration.java +++ /dev/null @@ -1,138 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.plus.webapp; - -import javax.naming.Context; -import javax.naming.InitialContext; - -import org.eclipse.jetty.plus.jndi.EnvEntry; -import org.eclipse.jetty.plus.jndi.NamingEntry; -import org.eclipse.jetty.plus.jndi.NamingEntryUtil; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.webapp.MetaData; -import org.eclipse.jetty.webapp.WebAppClassLoader; -import org.eclipse.jetty.webapp.WebAppContext; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class TestConfiguration -{ - @Test - public void testIt() throws Exception - { - ClassLoader old_loader = Thread.currentThread().getContextClassLoader(); - - try - { - InitialContext ic = new InitialContext(); - - Server server = new Server(); - - WebAppContext wac = new WebAppContext(); - wac.setServer(server); - wac.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), wac)); - wac.getSystemClassMatcher().include("org.eclipse.jetty.jndi."); - wac.getServerClassMatcher().exclude("org.eclipse.jetty.jndi."); - - MetaData metaData = new MetaData(); - - PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor(); - - //bind some EnvEntrys at the server level - EnvEntry ee1 = new EnvEntry(server, "xxx/a", "100", true); - EnvEntry ee2 = new EnvEntry(server, "yyy/b", "200", false); - EnvEntry ee3 = new EnvEntry(server, "zzz/c", "300", false); - EnvEntry ee4 = new EnvEntry(server, "zzz/d", "400", false); - EnvEntry ee5 = new EnvEntry(server, "zzz/f", "500", true); - - //bind some EnvEntrys at the webapp level - EnvEntry ee6 = new EnvEntry(wac, "xxx/a", "900", true); - EnvEntry ee7 = new EnvEntry(wac, "yyy/b", "910", true); - EnvEntry ee8 = new EnvEntry(wac, "zzz/c", "920", false); - EnvEntry ee9 = new EnvEntry(wac, "zzz/e", "930", false); - - assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "xxx/a")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "yyy/b")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/c")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/d")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "xxx/a")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "yyy/b")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/c")); - assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/e")); - - //make a new env configuration - EnvConfiguration envConfig = new EnvConfiguration(); - - Thread.currentThread().setContextClassLoader(wac.getClassLoader()); - MetaData metadata = new MetaData(); - envConfig.preConfigure(wac); - envConfig.configure(wac); - envConfig.bindEnvEntries(wac); - - String val = (String)ic.lookup("java:comp/env/xxx/a"); - assertEquals("900", val); //webapp naming overrides server - val = (String)ic.lookup("java:comp/env/yyy/b"); - assertEquals("910", val);//webapp overrides server - val = (String)ic.lookup("java:comp/env/zzz/c"); - assertEquals("920", val);//webapp overrides server - val = (String)ic.lookup("java:comp/env/zzz/d"); - assertEquals("400", val);//from server naming - val = (String)ic.lookup("java:comp/env/zzz/e"); - assertEquals("930", val);//from webapp naming - - NamingEntry ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/xxx/a"); - assertNotNull(ne); - ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/yyy/b"); - assertNotNull(ne); - ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/c"); - assertNotNull(ne); - ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/d"); - assertNotNull(ne); - ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/e"); - assertNotNull(ne); - - plusProcessor.bindEnvEntry("foo", "99"); - assertEquals("99", ic.lookup("java:comp/env/foo")); - - plusProcessor.bindEnvEntry("xxx/a", "7"); - assertEquals("900", ic.lookup("java:comp/env/xxx/a")); //webapp overrides web.xml - plusProcessor.bindEnvEntry("yyy/b", "7"); - assertEquals("910", ic.lookup("java:comp/env/yyy/b"));//webapp overrides web.xml - plusProcessor.bindEnvEntry("zzz/c", "7"); - assertEquals("7", ic.lookup("java:comp/env/zzz/c"));//webapp does NOT override web.xml - plusProcessor.bindEnvEntry("zzz/d", "7"); - assertEquals("7", ic.lookup("java:comp/env/zzz/d"));//server does NOT override web.xml - plusProcessor.bindEnvEntry("zzz/e", "7"); - assertEquals("7", ic.lookup("java:comp/env/zzz/e"));//webapp does NOT override web.xml - plusProcessor.bindEnvEntry("zzz/f", "7"); - assertEquals("500", ic.lookup("java:comp/env/zzz/f"));//server overrides web.xml - - ((Context)ic.lookup("java:comp")).destroySubcontext("env"); - ic.destroySubcontext("xxx"); - ic.destroySubcontext("yyy"); - ic.destroySubcontext("zzz"); - } - finally - { - Thread.currentThread().setContextClassLoader(old_loader); - } - } -} diff --git a/jetty-plus/src/test/resources/web.xml b/jetty-plus/src/test/resources/web.xml index f64129952ff..f058465baf4 100644 --- a/jetty-plus/src/test/resources/web.xml +++ b/jetty-plus/src/test/resources/web.xml @@ -4,20 +4,70 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="false" - version="3.0"> + version="3.0"> - Test WebApp + Test WebApp jdbc/mydatasource javax.sql.DataSource Container - + + + + foo + java.lang.String + beer + + org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections + foo + + + + + + bah + java.lang.String + beer + + org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections + bah + + + + + + empty + java.lang.String + + + org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections + empty + + + + + + vacuum + java.lang.String + + + org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections + vacuum + + + + + + webxmlonly + java.lang.String + WEBXMLONLY + + org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections + webXmlOnly + + diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index 7e37da58568..0aa8063b19f 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -27,6 +27,10 @@ + + org.slf4j + slf4j-api + org.eclipse.jetty.toolchain jetty-servlet-api @@ -48,7 +52,11 @@ jetty-client ${project.version} - + + org.eclipse.jetty + jetty-alpn-client + ${project.version} + org.eclipse.jetty jetty-util-ajax @@ -61,6 +69,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-proxy/src/main/java/module-info.java b/jetty-proxy/src/main/java/module-info.java index 4b4549c5cc6..10a07fbc8eb 100644 --- a/jetty-proxy/src/main/java/module-info.java +++ b/jetty-proxy/src/main/java/module-info.java @@ -1,29 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.proxy { exports org.eclipse.jetty.proxy; - requires jetty.servlet.api; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.client; + requires transitive org.eclipse.jetty.server; + requires transitive org.slf4j; } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java index d8ad11148a0..19ce91ed7e1 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -42,17 +42,18 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.ProtocolHandlers; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; -import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; +import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; +import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.util.HttpCookieStore; -import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      Abstract base class for proxy servlets.

      @@ -150,7 +151,7 @@ public abstract class AbstractProxyServlet extends HttpServlet catch (Exception x) { if (_log.isDebugEnabled()) - _log.debug(x); + _log.debug("Failed to stop client", x); } } @@ -207,7 +208,7 @@ public abstract class AbstractProxyServlet extends HttpServlet { servletName = getClass().getName() + "." + servletName; } - return Log.getLogger(servletName); + return LoggerFactory.getLogger(servletName); } /** @@ -350,11 +351,23 @@ public abstract class AbstractProxyServlet extends HttpServlet */ protected HttpClient newHttpClient() { - int selectors = Math.max(1, ProcessorUtils.availableProcessors() / 2); + int selectors = 1; String value = getServletConfig().getInitParameter("selectors"); if (value != null) selectors = Integer.parseInt(value); - return new HttpClient(new HttpClientTransportOverHTTP(selectors)); + ClientConnector clientConnector = newClientConnector(); + clientConnector.setSelectors(selectors); + return newHttpClient(clientConnector); + } + + protected HttpClient newHttpClient(ClientConnector clientConnector) + { + return new HttpClient(new HttpClientTransportDynamic(clientConnector)); + } + + protected ClientConnector newClientConnector() + { + return new ClientConnector(); } protected HttpClient getHttpClient() @@ -411,8 +424,14 @@ public abstract class AbstractProxyServlet extends HttpServlet { if (!validateDestination(clientRequest.getServerName(), clientRequest.getServerPort())) return null; - + // If the proxy is secure, we will likely get a proxied URI + // with the "https" scheme, but the upstream server needs + // to be called with the "http" scheme (the ConnectHandler + // is used to call upstream servers with the "https" scheme). StringBuffer target = clientRequest.getRequestURL(); + // Change "https" to "http". + if (HttpScheme.HTTPS.is(target.substring(0, 5))) + target.replace(4, 5, ""); String query = clientRequest.getQueryString(); if (query != null) target.append("?").append(query); @@ -673,7 +692,15 @@ public abstract class AbstractProxyServlet extends HttpServlet } catch (Exception e) { - _log.ignore(e); + _log.trace("IGNORED", e); + try + { + proxyResponse.sendError(-1); + } + catch (Exception e2) + { + _log.trace("IGNORED", e2); + } } finally { diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java index be757347d57..9169004064a 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AfterContentTransformer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -35,8 +35,8 @@ import java.util.List; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A specialized transformer for {@link AsyncMiddleManServlet} that performs @@ -58,7 +58,7 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.ContentTransformer, Destroyable { - private static final Logger LOG = Log.getLogger(AfterContentTransformer.class); + private static final Logger LOG = LoggerFactory.getLogger(AfterContentTransformer.class); private final List sourceBuffers = new ArrayList<>(); private Path overflowDirectory = Paths.get(System.getProperty("java.io.tmpdir")); @@ -290,7 +290,7 @@ public abstract class AfterContentTransformer implements AsyncMiddleManServlet.C } catch (IOException x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java index 56c18225c0f..e119cf44f15 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncMiddleManServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -55,8 +55,8 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.CountingCallback; import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      Servlet 3.1 asynchronous proxy servlet with capability @@ -757,7 +757,7 @@ public class AsyncMiddleManServlet extends AbstractProxyServlet public static class GZIPContentTransformer implements ContentTransformer { - private static final Logger logger = Log.getLogger(GZIPContentTransformer.class); + private static final Logger logger = LoggerFactory.getLogger(GZIPContentTransformer.class); private final List buffers = new ArrayList<>(2); private final ContentTransformer transformer; diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java index 9da5302991d..96be479f463 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java index b21eb6dc86f..7cb7a526977 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/BalancerServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java index a74b5823b32..9cd10814def 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -38,6 +38,8 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; @@ -46,7 +48,7 @@ import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SocketChannelEndPoint; import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HttpConnection; +import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.HandlerWrapper; @@ -54,17 +56,17 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      Implementation of a {@link Handler} that supports HTTP CONNECT.

      */ public class ConnectHandler extends HandlerWrapper { - protected static final Logger LOG = Log.getLogger(ConnectHandler.class); + protected static final Logger LOG = LoggerFactory.getLogger(ConnectHandler.class); private final Set whiteList = new HashSet<>(); private final Set blackList = new HashSet<>(); @@ -192,19 +194,24 @@ public class ConnectHandler extends HandlerWrapper } @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (HttpMethod.CONNECT.is(request.getMethod())) + String tunnelProtocol = jettyRequest.getMetaData().getProtocol(); + if (HttpMethod.CONNECT.is(request.getMethod()) && tunnelProtocol == null) { - String serverAddress = request.getRequestURI(); + String serverAddress = target; + if (HttpVersion.HTTP_2.is(request.getProtocol())) + { + HttpURI httpURI = jettyRequest.getHttpURI(); + serverAddress = httpURI.getHost() + ":" + httpURI.getPort(); + } if (LOG.isDebugEnabled()) LOG.debug("CONNECT request for {}", serverAddress); - - handleConnect(baseRequest, request, response, serverAddress); + handleConnect(jettyRequest, request, response, serverAddress); } else { - super.handle(target, baseRequest, request, response); + super.handle(target, jettyRequest, request, response); } } @@ -244,12 +251,11 @@ public class ConnectHandler extends HandlerWrapper return; } - HttpTransport transport = baseRequest.getHttpChannel().getHttpTransport(); - // TODO Handle CONNECT over HTTP2! - if (!(transport instanceof HttpConnection)) + HttpChannel httpChannel = baseRequest.getHttpChannel(); + if (!httpChannel.isTunnellingSupported()) { if (LOG.isDebugEnabled()) - LOG.debug("CONNECT not supported for {}", transport); + LOG.debug("CONNECT not supported for {}", httpChannel); sendConnectResponse(request, response, HttpServletResponse.SC_FORBIDDEN); return; } @@ -260,12 +266,12 @@ public class ConnectHandler extends HandlerWrapper if (LOG.isDebugEnabled()) LOG.debug("Connecting to {}:{}", host, port); - connectToServer(request, host, port, new Promise() + connectToServer(request, host, port, new Promise<>() { @Override public void succeeded(SocketChannel channel) { - ConnectContext connectContext = new ConnectContext(request, response, asyncContext, (HttpConnection)transport); + ConnectContext connectContext = new ConnectContext(request, response, asyncContext, httpChannel.getTunnellingEndPoint()); if (channel.isConnected()) selector.accept(channel, connectContext); else @@ -313,7 +319,7 @@ public class ConnectHandler extends HandlerWrapper } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } } @@ -335,8 +341,7 @@ public class ConnectHandler extends HandlerWrapper HttpServletRequest request = connectContext.getRequest(); prepareContext(request, context); - HttpConnection httpConnection = connectContext.getHttpConnection(); - EndPoint downstreamEndPoint = httpConnection.getEndPoint(); + EndPoint downstreamEndPoint = connectContext.getEndPoint(); DownstreamConnection downstreamConnection = newDownstreamConnection(downstreamEndPoint, context); downstreamConnection.setInputBufferSize(getBufferSize()); @@ -370,11 +375,10 @@ public class ConnectHandler extends HandlerWrapper response.setContentLength(0); if (statusCode != HttpServletResponse.SC_OK) response.setHeader(HttpHeader.CONNECTION.asString(), HttpHeaderValue.CLOSE.asString()); - response.getOutputStream().close(); if (LOG.isDebugEnabled()) LOG.debug("CONNECT response sent {} {}", request.getProtocol(), response.getStatus()); } - catch (IOException x) + catch (Throwable x) { if (LOG.isDebugEnabled()) LOG.debug("Could not send CONNECT response", x); @@ -411,10 +415,9 @@ public class ConnectHandler extends HandlerWrapper private void upgradeConnection(HttpServletRequest request, HttpServletResponse response, Connection connection) { - // Set the new connection as request attribute and change the status to 101 - // so that Jetty understands that it has to upgrade the connection - request.setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, connection); - response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + // Set the new connection as request attribute so that + // Jetty understands that it has to upgrade the connection. + request.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, connection); if (LOG.isDebugEnabled()) LOG.debug("Upgraded connection to {}", connection); } @@ -501,11 +504,11 @@ public class ConnectHandler extends HandlerWrapper } @Override - protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException + protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) { - SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, key, getScheduler()); - endp.setIdleTimeout(getIdleTimeout()); - return endp; + SocketChannelEndPoint endPoint = new SocketChannelEndPoint(channel, selector, key, getScheduler()); + endPoint.setIdleTimeout(getIdleTimeout()); + return endPoint; } @Override @@ -534,14 +537,14 @@ public class ConnectHandler extends HandlerWrapper private final HttpServletRequest request; private final HttpServletResponse response; private final AsyncContext asyncContext; - private final HttpConnection httpConnection; + private final EndPoint endPoint; - public ConnectContext(HttpServletRequest request, HttpServletResponse response, AsyncContext asyncContext, HttpConnection httpConnection) + public ConnectContext(HttpServletRequest request, HttpServletResponse response, AsyncContext asyncContext, EndPoint endPoint) { this.request = request; this.response = response; this.asyncContext = asyncContext; - this.httpConnection = httpConnection; + this.endPoint = endPoint; } public ConcurrentMap getContext() @@ -564,9 +567,9 @@ public class ConnectHandler extends HandlerWrapper return asyncContext; } - public HttpConnection getHttpConnection() + public EndPoint getEndPoint() { - return httpConnection; + return endPoint; } } @@ -603,7 +606,7 @@ public class ConnectHandler extends HandlerWrapper public class DownstreamConnection extends ProxyConnection implements Connection.UpgradeTo { - private ByteBuffer buffer; + private ByteBuffer buffer = BufferUtil.EMPTY_BUFFER; public DownstreamConnection(EndPoint endPoint, Executor executor, ByteBufferPool bufferPool, ConcurrentMap context) { @@ -613,7 +616,8 @@ public class ConnectHandler extends HandlerWrapper @Override public void onUpgradeTo(ByteBuffer buffer) { - this.buffer = buffer == null ? BufferUtil.EMPTY_BUFFER : buffer; + if (buffer != null) + this.buffer = buffer; } @Override diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyConnection.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyConnection.java index 84bd52b1ba4..196ff272b66 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyConnection.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -29,7 +29,7 @@ import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; public abstract class ProxyConnection extends AbstractConnection { @@ -37,7 +37,7 @@ public abstract class ProxyConnection extends AbstractConnection private final IteratingCallback pipe = new ProxyIteratingCallback(); private final ByteBufferPool bufferPool; private final ConcurrentMap context; - private Connection connection; + private ProxyConnection connection; protected ProxyConnection(EndPoint endp, Executor executor, ByteBufferPool bufferPool, ConcurrentMap context) { @@ -61,7 +61,7 @@ public abstract class ProxyConnection extends AbstractConnection return connection; } - public void setConnection(Connection connection) + public void setConnection(ProxyConnection connection) { this.connection = connection; } @@ -76,6 +76,11 @@ public abstract class ProxyConnection extends AbstractConnection protected abstract void write(EndPoint endPoint, ByteBuffer buffer, Callback callback); + protected void close(Throwable failure) + { + getEndPoint().close(failure); + } + @Override public String toConnectionString() { @@ -92,7 +97,7 @@ public abstract class ProxyConnection extends AbstractConnection private int filled; @Override - protected Action process() throws Exception + protected Action process() { buffer = bufferPool.acquire(getInputBufferSize(), true); try @@ -123,7 +128,7 @@ public abstract class ProxyConnection extends AbstractConnection if (LOG.isDebugEnabled()) LOG.debug(ProxyConnection.this + " could not fill", x); bufferPool.release(buffer); - disconnect(); + disconnect(x); return Action.SUCCEEDED; } } @@ -147,14 +152,14 @@ public abstract class ProxyConnection extends AbstractConnection { if (LOG.isDebugEnabled()) LOG.debug(ProxyConnection.this + " failed to write " + filled + " bytes", x); - disconnect(); + bufferPool.release(buffer); + disconnect(x); } - private void disconnect() + private void disconnect(Throwable x) { - bufferPool.release(buffer); - ProxyConnection.this.close(); - connection.close(); + ProxyConnection.this.close(x); + connection.close(x); } } } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java index 6f352e1a61f..0d153bafd92 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -55,9 +55,9 @@ public class ProxyServlet extends AbstractProxyServlet private static final String CONTINUE_ACTION_ATTRIBUTE = ProxyServlet.class.getName() + ".continueAction"; @Override - protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - final int requestId = getRequestId(request); + int requestId = getRequestId(request); String rewrittenTarget = rewriteTarget(request); @@ -76,7 +76,7 @@ public class ProxyServlet extends AbstractProxyServlet return; } - final Request proxyRequest = getHttpClient().newRequest(rewrittenTarget) + Request proxyRequest = getHttpClient().newRequest(rewrittenTarget) .method(request.getMethod()) .version(HttpVersion.fromString(request.getProtocol())); @@ -84,7 +84,7 @@ public class ProxyServlet extends AbstractProxyServlet addProxyHeaders(request, proxyRequest); - final AsyncContext asyncContext = request.startAsync(); + AsyncContext asyncContext = request.startAsync(); // We do not timeout the continuation, but the proxy request asyncContext.setTimeout(0); proxyRequest.timeout(getTimeout(), TimeUnit.MILLISECONDS); @@ -200,7 +200,7 @@ public class ProxyServlet extends AbstractProxyServlet } @Override - public void onContent(final Response proxyResponse, ByteBuffer content, final Callback callback) + public void onContent(Response proxyResponse, ByteBuffer content, Callback callback) { byte[] buffer; int offset; @@ -332,7 +332,7 @@ public class ProxyServlet extends AbstractProxyServlet } catch (Throwable x) { - _log.ignore(x); + _log.trace("IGNORED", x); } } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/package-info.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/package-info.java index 4ef4cf41da2..a0e102b2fa9 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/package-info.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AbstractConnectHandlerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AbstractConnectHandlerTest.java index 4e160053cff..31797760c2f 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AbstractConnectHandlerTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AbstractConnectHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java index c64d64fb571..bb0b2f5c20d 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -61,6 +61,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.RuntimeIOException; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; @@ -73,13 +74,13 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.Utf8StringBuilder; import org.eclipse.jetty.util.ajax.JSON; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.OS; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -88,9 +89,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +@Disabled("See issue #3974") public class AsyncMiddleManServletTest { - private static final Logger LOG = Log.getLogger(AsyncMiddleManServletTest.class); + private static final Logger LOG = LoggerFactory.getLogger(AsyncMiddleManServletTest.class); private static final String PROXIED_HEADER = "X-Proxied"; private HttpClient client; @@ -861,20 +863,21 @@ public class AsyncMiddleManServletTest @Test public void testAfterContentTransformer() throws Exception { - final String key0 = "id"; + String key0 = "id"; long value0 = 1; - final String key1 = "channel"; + String key1 = "channel"; String value1 = "foo"; - final String json = "{ \"" + key0 + "\":" + value0 + ", \"" + key1 + "\":\"" + value1 + "\" }"; + String jsonString = "{ \"" + key0 + "\":" + value0 + ", \"" + key1 + "\":\"" + value1 + "\" }"; startServer(new HttpServlet() { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.getOutputStream().write(json.getBytes(StandardCharsets.UTF_8)); + response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8)); } }); - final String key2 = "c"; + String key2 = "c"; + JSON json = new JSON(); startProxy(new AsyncMiddleManServlet() { @Override @@ -887,12 +890,12 @@ public class AsyncMiddleManServletTest { InputStream input = source.getInputStream(); @SuppressWarnings("unchecked") - Map obj = (Map)JSON.parse(new InputStreamReader(input, StandardCharsets.UTF_8)); + Map obj = (Map)json.fromJSON(new InputStreamReader(input, StandardCharsets.UTF_8)); // Transform the object. obj.put(key2, obj.remove(key1)); try (OutputStream output = sink.getOutputStream()) { - output.write(JSON.toString(obj).getBytes(StandardCharsets.UTF_8)); + output.write(json.toJSON(obj).getBytes(StandardCharsets.UTF_8)); return true; } } @@ -907,7 +910,7 @@ public class AsyncMiddleManServletTest assertEquals(200, response.getStatus()); @SuppressWarnings("unchecked") - Map obj = (Map)JSON.parse(response.getContentAsString()); + Map obj = (Map)json.fromJSON(response.getContentAsString()); assertNotNull(obj); assertEquals(2, obj.size()); assertEquals(value0, obj.get(key0)); @@ -982,24 +985,25 @@ public class AsyncMiddleManServletTest public void testAfterContentTransformerOverflowingToDisk() throws Exception { // Make sure the temporary directory we use exists and it's empty. - final Path targetTestsDir = prepareTargetTestsDir(); + Path targetTestsDir = prepareTargetTestsDir(); - final String key0 = "id"; + String key0 = "id"; long value0 = 1; - final String key1 = "channel"; + String key1 = "channel"; String value1 = "foo"; - final String json = "{ \"" + key0 + "\":" + value0 + ", \"" + key1 + "\":\"" + value1 + "\" }"; + String jsonString = "{ \"" + key0 + "\":" + value0 + ", \"" + key1 + "\":\"" + value1 + "\" }"; startServer(new HttpServlet() { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.getOutputStream().write(json.getBytes(StandardCharsets.UTF_8)); + response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8)); } }); - final String inputPrefix = "in_"; - final String outputPrefix = "out_"; - final String key2 = "c"; + String inputPrefix = "in_"; + String outputPrefix = "out_"; + String key2 = "c"; + JSON json = new JSON(); startProxy(new AsyncMiddleManServlet() { @Override @@ -1012,18 +1016,18 @@ public class AsyncMiddleManServletTest { InputStream input = source.getInputStream(); @SuppressWarnings("unchecked") - Map obj = (Map)JSON.parse(new InputStreamReader(input, StandardCharsets.UTF_8)); + Map obj = (Map)json.fromJSON(new InputStreamReader(input, StandardCharsets.UTF_8)); // Transform the object. obj.put(key2, obj.remove(key1)); try (OutputStream output = sink.getOutputStream()) { - output.write(JSON.toString(obj).getBytes(StandardCharsets.UTF_8)); + output.write(json.toJSON(obj).getBytes(StandardCharsets.UTF_8)); return true; } } }; transformer.setOverflowDirectory(targetTestsDir); - int maxBufferSize = json.length() / 4; + int maxBufferSize = jsonString.length() / 4; transformer.setMaxInputBufferSize(maxBufferSize); transformer.setInputFilePrefix(inputPrefix); transformer.setMaxOutputBufferSize(maxBufferSize); @@ -1039,7 +1043,7 @@ public class AsyncMiddleManServletTest assertEquals(200, response.getStatus()); @SuppressWarnings("unchecked") - Map obj = (Map)JSON.parse(response.getContentAsString()); + Map obj = (Map)json.fromJSON(response.getContentAsString()); assertNotNull(obj); assertEquals(2, obj.size()); assertEquals(value0, obj.get(key0)); @@ -1200,19 +1204,20 @@ public class AsyncMiddleManServletTest private void testAfterContentTransformerDoNoTransform(final boolean readSource, final boolean useDisk) throws Exception { - final String key0 = "id"; + String key0 = "id"; long value0 = 1; - final String key1 = "channel"; + String key1 = "channel"; String value1 = "foo"; - final String json = "{ \"" + key0 + "\":" + value0 + ", \"" + key1 + "\":\"" + value1 + "\" }"; + String jsonString = "{ \"" + key0 + "\":" + value0 + ", \"" + key1 + "\":\"" + value1 + "\" }"; startServer(new HttpServlet() { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.getOutputStream().write(json.getBytes(StandardCharsets.UTF_8)); + response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8)); } }); + JSON json = new JSON(); startProxy(new AsyncMiddleManServlet() { @Override @@ -1231,7 +1236,7 @@ public class AsyncMiddleManServletTest if (readSource) { InputStream input = source.getInputStream(); - JSON.parse(new InputStreamReader(input, StandardCharsets.UTF_8)); + json.fromJSON(new InputStreamReader(input, StandardCharsets.UTF_8)); } // No transformation. return false; @@ -1247,7 +1252,7 @@ public class AsyncMiddleManServletTest assertEquals(200, response.getStatus()); @SuppressWarnings("unchecked") - Map obj = (Map)JSON.parse(response.getContentAsString()); + Map obj = (Map)json.fromJSON(response.getContentAsString()); assertNotNull(obj); assertEquals(2, obj.size()); assertEquals(value0, obj.get(key0)); diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java index c891a01266a..83946613f98 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/CachingProxyServlet.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/CachingProxyServlet.java index a94babdd1d8..fc53e3a7eba 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/CachingProxyServlet.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/CachingProxyServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java index ab9d273468c..91e004ae6fd 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -53,10 +53,9 @@ public class ConnectHandlerSSLTest extends AbstractConnectHandlerTest public void prepare() throws Exception { sslContextFactory = new SslContextFactory.Server(); - String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); + String keyStorePath = MavenTestingUtils.getTestResourceFile("server_keystore.p12").getAbsolutePath(); sslContextFactory.setKeyStorePath(keyStorePath); sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setKeyManagerPassword("keypwd"); server = new Server(); serverConnector = new ServerConnector(server, sslContextFactory); server.addConnector(serverConnector); diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java index 01a02fe466c..220a349ddfb 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EchoHttpServlet.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EchoHttpServlet.java index d1bf767020b..86c4880326d 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EchoHttpServlet.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EchoHttpServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EmptyHttpServlet.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EmptyHttpServlet.java index e48b1d48e09..f19306e2be9 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EmptyHttpServlet.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/EmptyHttpServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java index 0d8893276f3..36321bed1ae 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -47,7 +47,6 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; @@ -56,36 +55,29 @@ import static org.junit.jupiter.api.Assertions.assertFalse; public class ForwardProxyServerTest { - @SuppressWarnings("Duplicates") - public static Stream scenarios() + public static Stream serverTLS() { - String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); - - // no server SSL - SslContextFactory.Server scenario1 = null; - // basic server SSL - SslContextFactory.Server scenario2 = new SslContextFactory.Server(); - scenario2.setKeyStorePath(keyStorePath); - scenario2.setKeyStorePassword("storepwd"); - scenario2.setKeyManagerPassword("keypwd"); - // TODO: add more SslContextFactory configurations/scenarios? - - return Stream.of(scenario1, scenario2).map(Arguments::of); + return Stream.of(null, newServerSslContextFactory()); + } + + private static SslContextFactory.Server newServerSslContextFactory() + { + SslContextFactory.Server serverTLS = new SslContextFactory.Server(); + String keyStorePath = MavenTestingUtils.getTestResourceFile("server_keystore.p12").getAbsolutePath(); + serverTLS.setKeyStorePath(keyStorePath); + serverTLS.setKeyStorePassword("storepwd"); + return serverTLS; } - private SslContextFactory.Server serverSslContextFactory; private Server server; private ServerConnector serverConnector; + private SslContextFactory.Server serverSslContextFactory; private Server proxy; private ServerConnector proxyConnector; - public void init(SslContextFactory.Server scenario) - { - serverSslContextFactory = scenario; - } - - protected void startServer(ConnectionFactory connectionFactory) throws Exception + protected void startServer(SslContextFactory.Server serverTLS, ConnectionFactory connectionFactory) throws Exception { + serverSslContextFactory = serverTLS; QueuedThreadPool serverThreads = new QueuedThreadPool(); serverThreads.setName("server"); server = new Server(serverThreads); @@ -128,28 +120,20 @@ public class ForwardProxyServerTest protected void stopServer() throws Exception { if (server != null) - { server.stop(); - server.join(); - } } protected void stopProxy() throws Exception { if (proxy != null) - { proxy.stop(); - proxy.join(); - } } @ParameterizedTest - @MethodSource("scenarios") - public void testRequestTarget(SslContextFactory.Server scenario) throws Exception + @MethodSource("serverTLS") + public void testRequestTarget(SslContextFactory.Server serverTLS) throws Exception { - init(scenario); - - startServer(new AbstractConnectionFactory("http/1.1") + startServer(serverTLS, new AbstractConnectionFactory("http/1.1") { @Override public Connection newConnection(Connector connector, EndPoint endPoint) @@ -206,15 +190,9 @@ public class ForwardProxyServerTest }); startProxy(); + SslContextFactory.Client clientTLS = new SslContextFactory.Client(true); ClientConnector clientConnector = new ClientConnector(); - String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); - SslContextFactory.Client clientSsl = new SslContextFactory.Client(); - clientSsl.setKeyStorePath(keyStorePath); - clientSsl.setKeyStorePassword("storepwd"); - clientSsl.setKeyManagerPassword("keypwd"); - clientSsl.setEndpointIdentificationAlgorithm(null); - clientConnector.setSslContextFactory(clientSsl); - + clientConnector.setSslContextFactory(clientTLS); HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); httpClient.getProxyConfiguration().getProxies().add(newHttpProxy()); httpClient.start(); diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java index ab57662feb5..f5f912de160 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -23,11 +23,17 @@ import java.net.ConnectException; import java.net.Socket; import java.net.URI; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.KeyStore; +import java.security.Principal; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedKeyManager; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; @@ -63,8 +69,8 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; @@ -75,56 +81,46 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; public class ForwardProxyTLSServerTest { - @SuppressWarnings("Duplicates") - public static Stream scenarios() + public static Stream proxyTLS() { - String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); - - // no server SSL - SslContextFactory.Server scenario1 = null; - // basic server SSL - SslContextFactory.Server scenario2 = new SslContextFactory.Server(); - scenario2.setKeyStorePath(keyStorePath); - scenario2.setKeyStorePassword("storepwd"); - scenario2.setKeyManagerPassword("keypwd"); - // TODO: add more SslContextFactory configurations/scenarios? - - return Stream.of(scenario1, scenario2).map(Arguments::of); + return Stream.of(null, newProxySslContextFactory()); } - private SslContextFactory.Server proxySslContextFactory; private Server server; private ServerConnector serverConnector; private Server proxy; private ServerConnector proxyConnector; - - public void init(SslContextFactory.Server scenario) - { - proxySslContextFactory = scenario; - } + private SslContextFactory.Server proxySslContextFactory; protected void startTLSServer(Handler handler) throws Exception + { + SslContextFactory.Server sslContextFactory = newServerSslContextFactory(); + startTLSServer(sslContextFactory, handler); + } + + protected void startTLSServer(SslContextFactory.Server sslContextFactory, Handler handler) throws Exception { QueuedThreadPool serverThreads = new QueuedThreadPool(); serverThreads.setName("server"); server = new Server(serverThreads); - serverConnector = new ServerConnector(server, newServerSslContextFactory()); + serverConnector = new ServerConnector(server, sslContextFactory); server.addConnector(serverConnector); server.setHandler(handler); server.start(); } - protected void startProxy() throws Exception + protected void startProxy(SslContextFactory.Server proxyTLS) throws Exception { - startProxy(new ConnectHandler()); + startProxy(proxyTLS, new ConnectHandler()); } - protected void startProxy(ConnectHandler connectHandler) throws Exception + protected void startProxy(SslContextFactory.Server proxyTLS, ConnectHandler connectHandler) throws Exception { + proxySslContextFactory = proxyTLS; QueuedThreadPool proxyThreads = new QueuedThreadPool(); proxyThreads.setName("proxy"); proxy = new Server(proxyThreads); - proxyConnector = new ServerConnector(proxy, proxySslContextFactory); + proxyConnector = new ServerConnector(proxy, proxyTLS); proxy.addConnector(proxyConnector); // Under Windows, it takes a while to detect that a connection // attempt fails, so use an explicit timeout @@ -149,24 +145,24 @@ public class ForwardProxyTLSServerTest private static SslContextFactory.Server newServerSslContextFactory() { SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - configureSslContextFactory(sslContextFactory); + String keyStorePath = MavenTestingUtils.getTestResourceFile("server_keystore.p12").getAbsolutePath(); + sslContextFactory.setKeyStorePath(keyStorePath); + sslContextFactory.setKeyStorePassword("storepwd"); return sslContextFactory; } + private static SslContextFactory.Server newProxySslContextFactory() + { + SslContextFactory.Server proxyTLS = new SslContextFactory.Server(); + String keyStorePath = MavenTestingUtils.getTestResourceFile("proxy_keystore.p12").getAbsolutePath(); + proxyTLS.setKeyStorePath(keyStorePath); + proxyTLS.setKeyStorePassword("storepwd"); + return proxyTLS; + } + private static SslContextFactory.Client newClientSslContextFactory() { - SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); - configureSslContextFactory(sslContextFactory); - sslContextFactory.setEndpointIdentificationAlgorithm(null); - return sslContextFactory; - } - - private static void configureSslContextFactory(SslContextFactory sslContextFactory) - { - String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); - sslContextFactory.setKeyStorePath(keyStorePath); - sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setKeyManagerPassword("keypwd"); + return new SslContextFactory.Client(true); } @AfterEach @@ -195,12 +191,11 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testOneExchange(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testOneExchange(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); startTLSServer(new ServerHandler()); - startProxy(); + startProxy(proxyTLS); HttpClient httpClient = newHttpClient(); httpClient.getProxyConfiguration().getProxies().add(newHttpProxy()); @@ -216,7 +211,7 @@ public class ForwardProxyTLSServerTest ContentResponse response = httpClient.newRequest(host, serverConnector.getLocalPort()) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) .timeout(5, TimeUnit.SECONDS) .send(); @@ -231,12 +226,11 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testTwoExchanges(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testTwoExchanges(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); startTLSServer(new ServerHandler()); - startProxy(); + startProxy(proxyTLS); HttpClient httpClient = newHttpClient(); httpClient.getProxyConfiguration().getProxies().add(newHttpProxy()); @@ -248,7 +242,7 @@ public class ForwardProxyTLSServerTest ContentResponse response1 = httpClient.newRequest("localhost", serverConnector.getLocalPort()) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) .timeout(5, TimeUnit.SECONDS) .send(); @@ -278,12 +272,11 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testTwoConcurrentExchanges(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testTwoConcurrentExchanges(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); startTLSServer(new ServerHandler()); - startProxy(); + startProxy(proxyTLS); HttpClient httpClient = newHttpClient(); httpClient.getProxyConfiguration().getProxies().add(newHttpProxy()); @@ -297,10 +290,10 @@ public class ForwardProxyTLSServerTest ContentResponse response1 = httpClient.newRequest("localhost", serverConnector.getLocalPort()) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(content1, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(content1, StandardCharsets.UTF_8)) .onRequestCommit(request -> { - Destination destination = httpClient.getDestination(HttpScheme.HTTPS.asString(), "localhost", serverConnector.getLocalPort()); + Destination destination = httpClient.resolveDestination(request); destination.newConnection(new Promise.Adapter<>() { @Override @@ -345,15 +338,14 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testShortIdleTimeoutOverriddenByRequest(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testShortIdleTimeoutOverriddenByRequest(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); // Short idle timeout for HttpClient. long idleTimeout = 500; startTLSServer(new ServerHandler()); - startProxy(new ConnectHandler() + startProxy(proxyTLS, new ConnectHandler() { @Override protected void handleConnect(Request baseRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress) @@ -384,7 +376,7 @@ public class ForwardProxyTLSServerTest ContentResponse response = httpClient.newRequest(host, serverConnector.getLocalPort()) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) // Long idle timeout for the request. .idleTimeout(10 * idleTimeout, TimeUnit.MILLISECONDS) .timeout(5, TimeUnit.SECONDS) @@ -401,12 +393,11 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testProxyDown(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testProxyDown(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); startTLSServer(new ServerHandler()); - startProxy(); + startProxy(proxyTLS); int proxyPort = proxyConnector.getLocalPort(); stopProxy(); @@ -420,7 +411,7 @@ public class ForwardProxyTLSServerTest httpClient.newRequest("localhost", serverConnector.getLocalPort()) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) .timeout(5, TimeUnit.SECONDS) .send(); }); @@ -430,14 +421,13 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testServerDown(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testServerDown(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); startTLSServer(new ServerHandler()); int serverPort = serverConnector.getLocalPort(); stopServer(); - startProxy(); + startProxy(proxyTLS); HttpClient httpClient = newHttpClient(); httpClient.getProxyConfiguration().getProxies().add(newHttpProxy()); @@ -449,7 +439,7 @@ public class ForwardProxyTLSServerTest httpClient.newRequest("localhost", serverPort) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) .timeout(5, TimeUnit.SECONDS) .send(); }); @@ -458,12 +448,11 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testProxyClosesConnection(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testProxyClosesConnection(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); startTLSServer(new ServerHandler()); - startProxy(new ConnectHandler() + startProxy(proxyTLS, new ConnectHandler() { @Override protected void handleConnect(Request baseRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress) @@ -486,12 +475,11 @@ public class ForwardProxyTLSServerTest } @ParameterizedTest - @MethodSource("scenarios") - public void testProxyAuthentication(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testProxyAuthentication(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); String realm = "test-realm"; - testProxyAuthentication(realm, new ConnectHandler() + testProxyAuthentication(proxyTLS, new ConnectHandler() { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException @@ -506,16 +494,15 @@ public class ForwardProxyTLSServerTest } super.handle(target, baseRequest, request, response); } - }); + }, realm); } @ParameterizedTest - @MethodSource("scenarios") - public void testProxyAuthenticationWithResponseContent(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testProxyAuthenticationWithResponseContent(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); String realm = "test-realm"; - testProxyAuthentication(realm, new ConnectHandler() + testProxyAuthentication(proxyTLS, new ConnectHandler() { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException @@ -531,16 +518,15 @@ public class ForwardProxyTLSServerTest } super.handle(target, baseRequest, request, response); } - }); + }, realm); } @ParameterizedTest - @MethodSource("scenarios") - public void testProxyAuthenticationWithIncludedAddressWithResponseContent(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testProxyAuthenticationWithIncludedAddressWithResponseContent(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); String realm = "test-realm"; - testProxyAuthentication(realm, new ConnectHandler() + testProxyAuthentication(proxyTLS, new ConnectHandler() { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException @@ -556,16 +542,15 @@ public class ForwardProxyTLSServerTest } super.handle(target, baseRequest, request, response); } - }, true); + }, realm, true); } @ParameterizedTest - @MethodSource("scenarios") - public void testProxyAuthenticationClosesConnection(SslContextFactory.Server scenario) throws Exception + @MethodSource("proxyTLS") + public void testProxyAuthenticationClosesConnection(SslContextFactory.Server proxyTLS) throws Exception { - init(scenario); String realm = "test-realm"; - testProxyAuthentication(realm, new ConnectHandler() + testProxyAuthentication(proxyTLS, new ConnectHandler() { @Override protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) @@ -582,18 +567,18 @@ public class ForwardProxyTLSServerTest return true; } } - }); + }, realm); } - private void testProxyAuthentication(String realm, ConnectHandler connectHandler) throws Exception + private void testProxyAuthentication(SslContextFactory.Server proxyTLS, ConnectHandler connectHandler, String realm) throws Exception { - testProxyAuthentication(realm, connectHandler, false); + testProxyAuthentication(proxyTLS, connectHandler, realm, false); } - private void testProxyAuthentication(String realm, ConnectHandler connectHandler, boolean includeAddress) throws Exception + private void testProxyAuthentication(SslContextFactory.Server proxyTLS, ConnectHandler connectHandler, String realm, boolean includeAddress) throws Exception { startTLSServer(new ServerHandler()); - startProxy(connectHandler); + startProxy(proxyTLS, connectHandler); HttpClient httpClient = newHttpClient(); HttpProxy httpProxy = newHttpProxy(); @@ -611,7 +596,7 @@ public class ForwardProxyTLSServerTest ContentResponse response = httpClient.newRequest(host, serverConnector.getLocalPort()) .scheme(HttpScheme.HTTPS.asString()) .method(HttpMethod.GET) - .path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) .timeout(5, TimeUnit.SECONDS) .send(); @@ -625,13 +610,175 @@ public class ForwardProxyTLSServerTest } } - @ParameterizedTest - @MethodSource("scenarios") - @Tag("Unstable") - @Disabled("External Proxy Server no longer stable enough for testing") - public void testExternalProxy(SslContextFactory.Server scenario) throws Exception + @Test + public void testBothProxyAndServerNeedClientAuth() throws Exception + { + // Keystore server_keystore.p12 contains: + // - alias "mykey": self-signed certificate with private key. + // - alias "client_root": certificate from client_keystore.p12 under the "server" alias. + // Keystore proxy_keystore.p12 contains: + // - alias "mykey": self-signed certificate with private key. + // - alias "client_root": certificate from client_keystore.p12 under the "proxy" alias. + // Keystore client_keystore.p12 contains: + // - alias "proxy": self-signed certificate with private key to send to the proxy. + // - alias "server": self-signed certificate with private key to send to the server. + // - alias "proxy_root": certificate from proxy_keystore under the "mykey" alias. + // - alias "server_root": certificate from server_keystore under the "mykey" alias. + + // We want setEndpointIdentificationAlgorithm(null) for all 3 SslContextFactory + // because the certificate common names do not match the host names. + + SslContextFactory.Server serverTLS = newServerSslContextFactory(); + serverTLS.setEndpointIdentificationAlgorithm(null); + serverTLS.setNeedClientAuth(true); + startTLSServer(serverTLS, new ServerHandler()); + int serverPort = serverConnector.getLocalPort(); + String serverAlias = "server"; + + SslContextFactory.Server proxyTLS = newProxySslContextFactory(); + proxyTLS.setEndpointIdentificationAlgorithm(null); + proxyTLS.setNeedClientAuth(true); + startProxy(proxyTLS); + int proxyPort = proxyConnector.getLocalPort(); + String proxyAlias = "proxy"; + + SslContextFactory.Client clientSslContextFactory = new SslContextFactory.Client() + { + @Override + protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception + { + KeyManager[] keyManagers = super.getKeyManagers(keyStore); + for (int i = 0; i < keyManagers.length; i++) + { + KeyManager keyManager = keyManagers[i]; + if (keyManager instanceof X509ExtendedKeyManager) + { + X509ExtendedKeyManager extKeyManager = (X509ExtendedKeyManager)keyManager; + keyManagers[i] = new X509ExtendedKeyManagerWrapper(extKeyManager) + { + @Override + public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) + { + int port = engine.getPeerPort(); + if (port == serverPort) + return serverAlias; + else if (port == proxyPort) + return proxyAlias; + else + return super.chooseEngineClientAlias(keyType, issuers, engine); + } + }; + } + } + return keyManagers; + } + }; + clientSslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("client_keystore.p12").getAbsolutePath()); + clientSslContextFactory.setKeyStorePassword("storepwd"); + clientSslContextFactory.setEndpointIdentificationAlgorithm(null); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(clientSslContextFactory); + HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); + httpClient.getProxyConfiguration().getProxies().add(newHttpProxy()); + httpClient.start(); + + try + { + String body = "BODY"; + ContentResponse response = httpClient.newRequest("localhost", serverConnector.getLocalPort()) + .scheme(HttpScheme.HTTPS.asString()) + .method(HttpMethod.GET) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + String content = response.getContentAsString(); + assertEquals(body, content); + } + finally + { + httpClient.stop(); + } + } + + @Test + public void testBothProxyAndServerNeedClientAuthWithDifferentKeyStores() throws Exception + { + SslContextFactory.Server serverTLS = newServerSslContextFactory(); + serverTLS.setEndpointIdentificationAlgorithm(null); + serverTLS.setNeedClientAuth(true); + startTLSServer(serverTLS, new ServerHandler()); + int serverPort = serverConnector.getLocalPort(); + + SslContextFactory.Server proxyServerTLS = newProxySslContextFactory(); + proxyServerTLS.setEndpointIdentificationAlgorithm(null); + proxyServerTLS.setNeedClientAuth(true); + startProxy(proxyServerTLS); + int proxyPort = proxyConnector.getLocalPort(); + + SslContextFactory.Client clientTLS = new SslContextFactory.Client() + { + @Override + public SSLEngine newSSLEngine(String host, int port) + { + if (port != serverPort) + throw new IllegalStateException(); + return super.newSSLEngine(host, port); + } + }; + clientTLS.setKeyStorePath(MavenTestingUtils.getTestResourceFile("client_server_keystore.p12").getAbsolutePath()); + clientTLS.setKeyStorePassword("storepwd"); + clientTLS.setEndpointIdentificationAlgorithm(null); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(clientTLS); + HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); + + SslContextFactory.Client proxyClientTLS = new SslContextFactory.Client() + { + @Override + public SSLEngine newSSLEngine(String host, int port) + { + if (port != proxyPort) + throw new IllegalStateException(); + return super.newSSLEngine(host, port); + } + }; + proxyClientTLS.setKeyStorePath(MavenTestingUtils.getTestResourceFile("client_proxy_keystore.p12").getAbsolutePath()); + proxyClientTLS.setKeyStorePassword("storepwd"); + proxyClientTLS.setEndpointIdentificationAlgorithm(null); + proxyClientTLS.start(); + HttpProxy httpProxy = new HttpProxy(new Origin.Address("localhost", proxyConnector.getLocalPort()), proxyClientTLS); + httpClient.getProxyConfiguration().getProxies().add(httpProxy); + httpClient.start(); + + try + { + String body = "BODY"; + ContentResponse response = httpClient.newRequest("localhost", serverConnector.getLocalPort()) + .scheme(HttpScheme.HTTPS.asString()) + .method(HttpMethod.GET) + .path("/echo?body=" + URLEncoder.encode(body, StandardCharsets.UTF_8)) + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + String content = response.getContentAsString(); + assertEquals(body, content); + } + finally + { + httpClient.stop(); + } + } + + @Test + @Tag("external") + @Disabled + public void testExternalProxy() throws Exception { - init(scenario); // Free proxy server obtained from http://hidemyass.com/proxy-list/ String proxyHost = "81.208.25.53"; int proxyPort = 3128; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServer.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServer.java index c8ab33c3443..5c3f5bdf73b 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServer.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java index e267b5f90ad..e226745bae3 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletFailureTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -43,6 +43,7 @@ import org.eclipse.jetty.client.util.BytesContentProvider; import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.tools.HttpTester; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; @@ -50,7 +51,6 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java index ae842c3ba9f..3a1ede5507b 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -43,13 +43,13 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.ProcessorUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -64,7 +64,7 @@ public class ProxyServletLoadTest .stream().map(Arguments::of); } - private static final Logger LOG = Log.getLogger(ProxyServletLoadTest.class); + private static final Logger LOG = LoggerFactory.getLogger(ProxyServletLoadTest.class); private static final String PROXIED_HEADER = "X-Proxied"; private HttpClient client; diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java index ecd99c7856f..7b15315d249 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -214,13 +214,12 @@ public class ProxyServletTest // Shutdown the proxy proxy.stop(); - ExecutionException x = assertThrows(ExecutionException.class, - () -> - { - client.newRequest("localhost", serverConnector.getLocalPort()) - .timeout(5, TimeUnit.SECONDS) - .send(); - }); + ExecutionException x = assertThrows(ExecutionException.class, () -> + { + client.newRequest("localhost", serverConnector.getLocalPort()) + .timeout(5, TimeUnit.SECONDS) + .send(); + }); assertThat(x.getCause(), instanceOf(ConnectException.class)); } @@ -231,7 +230,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -258,7 +257,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -292,7 +291,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -322,7 +321,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { try { @@ -362,7 +361,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -417,7 +416,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { try (InputStream input = Files.newInputStream(temp)) { @@ -466,7 +465,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.getOutputStream().print(req.getQueryString()); } @@ -490,7 +489,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException + protected void doGet(final HttpServletRequest request, final HttpServletResponse response) { if (!request.isAsyncStarted()) { @@ -499,12 +498,12 @@ public class ProxyServletTest asyncContext.addListener(new AsyncListener() { @Override - public void onComplete(AsyncEvent event) throws IOException + public void onComplete(AsyncEvent event) { } @Override - public void onTimeout(AsyncEvent event) throws IOException + public void onTimeout(AsyncEvent event) { if (request.getHeader("Via") != null) response.addHeader(PROXIED_HEADER, "true"); @@ -512,12 +511,12 @@ public class ProxyServletTest } @Override - public void onError(AsyncEvent event) throws IOException + public void onError(AsyncEvent event) { } @Override - public void onStartAsync(AsyncEvent event) throws IOException + public void onStartAsync(AsyncEvent event) { } }); @@ -541,7 +540,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { PrintWriter writer = resp.getWriter(); writer.write(req.getHeader("X-Forwarded-Host")); @@ -610,7 +609,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -665,7 +664,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -722,7 +721,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -767,7 +766,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -808,7 +807,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -840,7 +839,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -875,7 +874,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -902,7 +901,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -932,7 +931,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { byte[] message = "tooshort".getBytes("ascii"); resp.setContentType("text/plain;charset=ascii"); @@ -964,7 +963,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { if (req.getHeader("Via") != null) resp.addHeader(PROXIED_HEADER, "true"); @@ -1036,7 +1035,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { ServletOutputStream output = response.getOutputStream(); output.write(chunk1); @@ -1069,7 +1068,8 @@ public class ProxyServletTest InputStreamResponseListener listener = new InputStreamResponseListener(); int port = serverConnector.getLocalPort(); - client.newRequest("localhost", port).send(listener); + Request request = client.newRequest("localhost", port); + request.send(listener); // Make the proxy request fail; given the small content, the // proxy-to-client response is not committed yet so it will be reset. @@ -1091,7 +1091,7 @@ public class ProxyServletTest // Make sure the proxy does not receive chunk2. assertEquals(-1, input.read()); - HttpDestination destination = (HttpDestination)client.getDestination("http", "localhost", port); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); ConnectionPool connectionPool = destination.getConnectionPool(); assertTrue(connectionPool.isEmpty()); } @@ -1101,14 +1101,14 @@ public class ProxyServletTest public void testProxyRequestFailureInTheMiddleOfProxyingBigContent(Class proxyServletClass) throws Exception { int outputBufferSize = 1024; - final CountDownLatch chunk1Latch = new CountDownLatch(1); - final byte[] chunk1 = new byte[outputBufferSize]; + CountDownLatch chunk1Latch = new CountDownLatch(1); + byte[] chunk1 = new byte[outputBufferSize]; new Random().nextBytes(chunk1); - final int chunk2 = 'w'; + int chunk2 = 'w'; startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { ServletOutputStream output = response.getOutputStream(); output.write(chunk1); @@ -1142,29 +1142,29 @@ public class ProxyServletTest InputStreamResponseListener listener = new InputStreamResponseListener(); int port = serverConnector.getLocalPort(); - client.newRequest("localhost", port).send(listener); + Request request = client.newRequest("localhost", port); + request.send(listener); Response response = listener.get(5, TimeUnit.SECONDS); assertEquals(200, response.getStatus()); InputStream input = listener.getInputStream(); - for (int i = 0; i < chunk1.length; ++i) + for (byte b : chunk1) { - assertEquals(chunk1[i] & 0xFF, input.read()); + assertEquals(b & 0xFF, input.read()); } TimeUnit.MILLISECONDS.sleep(2 * proxyTimeout); chunk1Latch.countDown(); - assertThrows(EOFException.class, - () -> - { - // Make sure the proxy does not receive chunk2. - input.read(); - }); + assertThrows(EOFException.class, () -> + { + // Make sure the proxy does not receive chunk2. + input.read(); + }); - HttpDestination destination = (HttpDestination)client.getDestination("http", "localhost", port); + HttpDestination destination = (HttpDestination)client.resolveDestination(request); ConnectionPool connectionPool = destination.getConnectionPool(); assertTrue(connectionPool.isEmpty()); } @@ -1181,7 +1181,7 @@ public class ProxyServletTest proxyContext.addFilter(new FilterHolder(new Filter() { @Override - public void init(FilterConfig filterConfig) throws ServletException + public void init(FilterConfig filterConfig) { } @@ -1221,7 +1221,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { List names = Collections.list(request.getHeaderNames()); for (String name : names) @@ -1255,7 +1255,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { serverLatch1.countDown(); @@ -1321,7 +1321,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { // Send the 100 Continue. ServletInputStream input = request.getInputStream(); @@ -1373,7 +1373,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { // Send the 100 Continue. ServletInputStream input = request.getInputStream(); @@ -1423,7 +1423,7 @@ public class ProxyServletTest startServer(new HttpServlet() { @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException { serverLatch1.countDown(); diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ReverseProxyTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ReverseProxyTest.java index 5a032128670..630382f3136 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ReverseProxyTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ReverseProxyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.proxy; @@ -141,9 +141,11 @@ public class ReverseProxyTest } }); startProxy(new HashMap() - {{ - put("preserveHost", "true"); - }}); + { + { + put("preserveHost", "true"); + } + }); startClient(); ContentResponse response = client.newRequest("localhost", proxyConnector.getLocalPort()).send(); diff --git a/jetty-proxy/src/test/resources/client_keystore.p12 b/jetty-proxy/src/test/resources/client_keystore.p12 new file mode 100644 index 00000000000..03e6830340f Binary files /dev/null and b/jetty-proxy/src/test/resources/client_keystore.p12 differ diff --git a/jetty-proxy/src/test/resources/client_proxy_keystore.p12 b/jetty-proxy/src/test/resources/client_proxy_keystore.p12 new file mode 100644 index 00000000000..0b55322162e Binary files /dev/null and b/jetty-proxy/src/test/resources/client_proxy_keystore.p12 differ diff --git a/jetty-proxy/src/test/resources/client_server_keystore.p12 b/jetty-proxy/src/test/resources/client_server_keystore.p12 new file mode 100644 index 00000000000..f7b6729309f Binary files /dev/null and b/jetty-proxy/src/test/resources/client_server_keystore.p12 differ diff --git a/jetty-proxy/src/test/resources/jetty-logging.properties b/jetty-proxy/src/test/resources/jetty-logging.properties index af4d4f4fd55..7e7e5ce6384 100644 --- a/jetty-proxy/src/test/resources/jetty-logging.properties +++ b/jetty-proxy/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.client.LEVEL=DEBUG #org.eclipse.jetty.proxy.LEVEL=DEBUG diff --git a/jetty-proxy/src/test/resources/keystore b/jetty-proxy/src/test/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/jetty-proxy/src/test/resources/keystore and /dev/null differ diff --git a/jetty-proxy/src/test/resources/proxy_keystore.p12 b/jetty-proxy/src/test/resources/proxy_keystore.p12 new file mode 100644 index 00000000000..61c8109702b Binary files /dev/null and b/jetty-proxy/src/test/resources/proxy_keystore.p12 differ diff --git a/jetty-proxy/src/test/resources/server_keystore.p12 b/jetty-proxy/src/test/resources/server_keystore.p12 new file mode 100644 index 00000000000..5bf1bc7ee2f Binary files /dev/null and b/jetty-proxy/src/test/resources/server_keystore.p12 differ diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index 1134d4ff73e..f55c9242981 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -30,7 +30,15 @@ jetty-annotations ${project.version}
      - + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-quickstart/src/main/config/etc/example-quickstart.xml b/jetty-quickstart/src/main/config/etc/example-quickstart.xml deleted file mode 100644 index c042d89d724..00000000000 --- a/jetty-quickstart/src/main/config/etc/example-quickstart.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - true - / - /application.war - - diff --git a/jetty-quickstart/src/main/config/etc/jetty-quickstart.xml b/jetty-quickstart/src/main/config/etc/jetty-quickstart.xml new file mode 100644 index 00000000000..84d030260b0 --- /dev/null +++ b/jetty-quickstart/src/main/config/etc/jetty-quickstart.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + /etc/quickstart-webapp.xml + + + + + + diff --git a/jetty-quickstart/src/main/config/modules/jetty-quickstart.d/quickstart-webapp.xml b/jetty-quickstart/src/main/config/modules/jetty-quickstart.d/quickstart-webapp.xml new file mode 100644 index 00000000000..b0f07545e95 --- /dev/null +++ b/jetty-quickstart/src/main/config/modules/jetty-quickstart.d/quickstart-webapp.xml @@ -0,0 +1,28 @@ + + + + + + org.eclipse.jetty.quickstart.origin + + + + + org.eclipse.jetty.quickstart.xml + + + + + org.eclipse.jetty.quickstart.mode + + + + + + + + true + false + false + + diff --git a/jetty-quickstart/src/main/config/modules/quickstart.mod b/jetty-quickstart/src/main/config/modules/quickstart.mod index 102801714b6..c531ea648d0 100644 --- a/jetty-quickstart/src/main/config/modules/quickstart.mod +++ b/jetty-quickstart/src/main/config/modules/quickstart.mod @@ -6,8 +6,21 @@ deployment of preconfigured webapplications. [depend] server -plus -annotations +deploy [lib] lib/jetty-quickstart-${jetty.version}.jar + +[xml] +etc/jetty-quickstart.xml + +[files] +basehome:modules/jetty-quickstart.d/quickstart-webapp.xml|etc/quickstart-webapp.xml + + +[ini-template] + +# Modes are AUTO, GENERATE, QUICKSTART +# jetty.quickstart.mode=AUTO +# jetty.quickstart.origin=origin +# jetty.quickstart.xml= diff --git a/jetty-quickstart/src/main/java/module-info.java b/jetty-quickstart/src/main/java/module-info.java index 846d8451fc7..2bf0a15d606 100644 --- a/jetty-quickstart/src/main/java/module-info.java +++ b/jetty-quickstart/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.quickstart @@ -21,13 +21,6 @@ module org.eclipse.jetty.quickstart exports org.eclipse.jetty.quickstart; requires jetty.servlet.api; - requires org.eclipse.jetty.annotations; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.plus; - requires org.eclipse.jetty.security; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.servlet; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.webapp; - requires org.eclipse.jetty.xml; + requires transitive org.eclipse.jetty.annotations; + requires org.slf4j; } diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java index 05a15cd3050..3f68329e5e9 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; @@ -38,9 +38,9 @@ import java.util.regex.Pattern; import java.util.stream.Stream; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Normalize Attribute to String. @@ -62,7 +62,7 @@ import org.eclipse.jetty.util.resource.Resource; */ public class AttributeNormalizer { - private static final Logger LOG = Log.getLogger(AttributeNormalizer.class); + private static final Logger LOG = LoggerFactory.getLogger(AttributeNormalizer.class); private static final Pattern __propertyPattern = Pattern.compile("(?<=[^$]|^)\\$\\{([^}]*)\\}"); private static class Attribute @@ -326,7 +326,7 @@ public class AttributeNormalizer } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to normalize {}", o, e); } return String.valueOf(o); } @@ -376,7 +376,7 @@ public class AttributeNormalizer } catch (IOException ignore) { - LOG.ignore(ignore); + LOG.trace("IGNORED", ignore); } if (path.startsWith(a.path)) diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/ExtraXmlDescriptorProcessor.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/ExtraXmlDescriptorProcessor.java index f87bd1eca53..9e4f29d695f 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/ExtraXmlDescriptorProcessor.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/ExtraXmlDescriptorProcessor.java @@ -1,29 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.Descriptor; import org.eclipse.jetty.webapp.IterativeDescriptorProcessor; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ExtraXmlDescriptorProcessor @@ -33,7 +33,7 @@ import org.eclipse.jetty.xml.XmlParser; public class ExtraXmlDescriptorProcessor extends IterativeDescriptorProcessor { - private static final Logger LOG = Log.getLogger(ExtraXmlDescriptorProcessor.class); + private static final Logger LOG = LoggerFactory.getLogger(ExtraXmlDescriptorProcessor.class); private final StringBuilder _buffer = new StringBuilder(); private final boolean _showOrigin; diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java index 627f676588a..6534eed84ce 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java @@ -1,35 +1,39 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; import java.util.Locale; +import org.eclipse.jetty.annotations.AnnotationConfiguration; +import org.eclipse.jetty.plus.webapp.EnvConfiguration; +import org.eclipse.jetty.plus.webapp.PlusConfiguration; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PreconfigureQuickStartWar { - private static final Logger LOG = Log.getLogger(PreconfigureQuickStartWar.class); + private static final Logger LOG = LoggerFactory.getLogger(PreconfigureQuickStartWar.class); static final boolean ORIGIN = LOG.isDebugEnabled(); public static void main(String... args) throws Exception @@ -98,7 +102,13 @@ public class PreconfigureQuickStartWar final Server server = new Server(); - QuickStartWebApp webapp = new QuickStartWebApp(); + WebAppContext webapp = new WebAppContext(); + webapp.addConfiguration(new QuickStartConfiguration(), + new EnvConfiguration(), + new PlusConfiguration(), + new AnnotationConfiguration()); + webapp.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.GENERATE); + webapp.setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, ""); if (xml != null) { @@ -108,10 +118,21 @@ public class PreconfigureQuickStartWar xmlConfiguration.configure(webapp); } webapp.setResourceBase(dir.getFile().getAbsolutePath()); - webapp.setMode(QuickStartConfiguration.Mode.GENERATE); server.setHandler(webapp); - server.start(); - server.stop(); + try + { + server.setDryRun(true); + server.start(); + } + catch (Exception e) + { + throw e; + } + finally + { + if (!server.isStopped()) + server.stop(); + } } private static void error(String message) diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java index 2462ad4e326..35ba26a4055 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; +import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Set; @@ -26,30 +27,32 @@ import java.util.stream.Collectors; import org.eclipse.jetty.annotations.AnnotationConfiguration; import org.eclipse.jetty.annotations.AnnotationDecorator; import org.eclipse.jetty.annotations.ServletContainerInitializersStarter; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.StandardDescriptorProcessor; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.WebDescriptor; import org.eclipse.jetty.webapp.WebInfConfiguration; import org.eclipse.jetty.webapp.WebXmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * QuickStartConfiguration *

      - * Re-inflate a deployable webapp from a saved effective-web.xml - * which combines all pre-parsed web xml descriptors and annotations. + * Prepare for quickstart generation, or usage. */ public class QuickStartConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(QuickStartConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(QuickStartConfiguration.class); public static final Set> __replacedConfigurations = new HashSet<>(); - public static final String ORIGIN_ATTRIBUTE = "org.eclipse.jetty.quickstart.ORIGIN_ATTRIBUTE"; - public static final String GENERATE_ORIGIN = "org.eclipse.jetty.quickstart.GENERATE_ORIGIN"; - public static final String QUICKSTART_WEB_XML = "org.eclipse.jetty.quickstart.QUICKSTART_WEB_XML"; + public static final String ORIGIN_ATTRIBUTE = "org.eclipse.jetty.quickstart.origin"; + public static final String QUICKSTART_WEB_XML = "org.eclipse.jetty.quickstart.xml"; + public static final String MODE = "org.eclipse.jetty.quickstart.mode"; static { @@ -59,18 +62,25 @@ public class QuickStartConfiguration extends AbstractConfiguration __replacedConfigurations.add(org.eclipse.jetty.annotations.AnnotationConfiguration.class); } - ; + /** Configure the server for the quickstart mode. + *

      In practise this means calling server.setDryRun(true) for GENERATE mode

      + * @see Server#setDryRun(boolean) + * @param server The server to configure + * @param mode The quickstart mode + */ + public static void configureMode(Server server, String mode) + { + if (mode != null && Mode.valueOf(mode) == Mode.GENERATE) + server.setDryRun(true); + } public enum Mode { - DISABLED, // No Quick start GENERATE, // Generate quickstart-web.xml and then stop AUTO, // use or generate depending on the existance of quickstart-web.xml QUICKSTART // Use quickstart-web.xml } - ; - private Mode _mode = Mode.AUTO; private boolean _quickStart; @@ -81,19 +91,6 @@ public class QuickStartConfiguration extends AbstractConfiguration addDependents(WebXmlConfiguration.class); } - public void setMode(Mode mode) - { - _mode = mode; - } - - public Mode getMode() - { - return _mode; - } - - /** - * @see org.eclipse.jetty.webapp.AbstractConfiguration#preConfigure(org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void preConfigure(WebAppContext context) throws Exception { @@ -106,39 +103,46 @@ public class QuickStartConfiguration extends AbstractConfiguration Resource quickStartWebXml = getQuickStartWebXml(context); LOG.debug("quickStartWebXml={} exists={}", quickStartWebXml, quickStartWebXml.exists()); + //Get the mode + Mode mode = (Mode)context.getAttribute(MODE); + if (mode != null) + _mode = mode; + _quickStart = false; + switch (_mode) { - case DISABLED: - super.preConfigure(context); - break; - case GENERATE: { + if (quickStartWebXml.exists()) + LOG.info("Regenerating {}", quickStartWebXml); + else + LOG.info("Generating {}", quickStartWebXml); + super.preConfigure(context); + //generate the quickstart file then abort QuickStartGeneratorConfiguration generator = new QuickStartGeneratorConfiguration(true); configure(generator, context); context.addConfiguration(generator); break; } - case AUTO: { if (quickStartWebXml.exists()) - quickStart(context, quickStartWebXml); + { + quickStart(context); + } else { + if (LOG.isDebugEnabled()) + LOG.debug("No quickstart xml file, starting webapp {} normally", context); super.preConfigure(context); - QuickStartGeneratorConfiguration generator = new QuickStartGeneratorConfiguration(false); - configure(generator, context); - context.addConfiguration(generator); } break; } - case QUICKSTART: if (quickStartWebXml.exists()) - quickStart(context, quickStartWebXml); + quickStart(context); else throw new IllegalStateException("No " + quickStartWebXml); break; @@ -151,27 +155,20 @@ public class QuickStartConfiguration extends AbstractConfiguration protected void configure(QuickStartGeneratorConfiguration generator, WebAppContext context) throws IOException { Object attr; - attr = context.getAttribute(GENERATE_ORIGIN); - if (attr != null) - generator.setGenerateOrigin(Boolean.valueOf(attr.toString())); attr = context.getAttribute(ORIGIN_ATTRIBUTE); if (attr != null) generator.setOriginAttribute(attr.toString()); - attr = context.getAttribute(QUICKSTART_WEB_XML); - if (attr instanceof Resource) - generator.setQuickStartWebXml((Resource)attr); - else if (attr != null) - generator.setQuickStartWebXml(Resource.newResource(attr.toString())); + + generator.setQuickStartWebXml((Resource)context.getAttribute(QUICKSTART_WEB_XML)); } - /** - * @see org.eclipse.jetty.webapp.AbstractConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void configure(WebAppContext context) throws Exception { if (!_quickStart) + { super.configure(context); + } else { //add the processor to handle normal web.xml content @@ -195,16 +192,29 @@ public class QuickStartConfiguration extends AbstractConfiguration } } - protected void quickStart(WebAppContext context, Resource quickStartWebXml) + @Override + public void postConfigure(WebAppContext context) throws Exception + { + super.postConfigure(context); + ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER); + if (starter != null) + { + context.removeBean(starter); + context.removeAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER); + } + } + + protected void quickStart(WebAppContext context) throws Exception { + LOG.info("Quickstarting {}", context); _quickStart = true; - context.setConfigurations(context.getWebAppConfigurations().stream() + context.setConfigurations(context.getConfigurations().stream() .filter(c -> !__replacedConfigurations.contains(c.replaces()) && !__replacedConfigurations.contains(c.getClass())) .collect(Collectors.toList()).toArray(new Configuration[]{})); - context.getMetaData().setWebXml(quickStartWebXml); - context.getServletContext().setEffectiveMajorVersion(context.getMetaData().getWebXml().getMajorVersion()); - context.getServletContext().setEffectiveMinorVersion(context.getMetaData().getWebXml().getMinorVersion()); + context.getMetaData().setWebDescriptor(new WebDescriptor((Resource)context.getAttribute(QUICKSTART_WEB_XML))); + context.getServletContext().setEffectiveMajorVersion(context.getMetaData().getWebDescriptor().getMajorVersion()); + context.getServletContext().setEffectiveMinorVersion(context.getMetaData().getWebDescriptor().getMinorVersion()); } /** @@ -216,12 +226,38 @@ public class QuickStartConfiguration extends AbstractConfiguration */ public Resource getQuickStartWebXml(WebAppContext context) throws Exception { + Object attr = context.getAttribute(QUICKSTART_WEB_XML); + if (attr instanceof Resource) + return (Resource)attr; + Resource webInf = context.getWebInf(); if (webInf == null || !webInf.exists()) - throw new IllegalStateException("No WEB-INF"); - LOG.debug("webinf={}", webInf); + { + File tmp = new File(context.getBaseResource().getFile(), "WEB-INF"); + tmp.mkdirs(); + webInf = context.getWebInf(); + } - Resource quickStartWebXml = webInf.addPath("quickstart-web.xml"); - return quickStartWebXml; + Resource qstart; + if (attr == null || StringUtil.isBlank(attr.toString())) + { + qstart = webInf.addPath("quickstart-web.xml"); + } + else + { + try + { + // Try a relative resolution + qstart = Resource.newResource(webInf.getFile().toPath().resolve(attr.toString())); + } + catch (Throwable th) + { + // try as a resource + qstart = (Resource.newResource(attr.toString())); + } + context.setAttribute(QUICKSTART_WEB_XML, qstart); + } + context.setAttribute(QUICKSTART_WEB_XML, qstart); + return qstart; } } diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java index dca3abff08d..386c0258187 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; @@ -65,18 +65,12 @@ public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor } } - /** - * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#start(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.Descriptor) - */ @Override public void start(WebAppContext context, Descriptor descriptor) { _originAttributeName = context.getInitParameter(QuickStartGeneratorConfiguration.ORIGIN); } - /** - * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#end(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.Descriptor) - */ @Override public void end(WebAppContext context, Descriptor descriptor) { diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartGeneratorConfiguration.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartGeneratorConfiguration.java index 20cfab4535b..0cf047c4c87 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartGeneratorConfiguration.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartGeneratorConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; @@ -52,8 +52,7 @@ import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletMapping; import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.webapp.AbstractConfiguration; @@ -61,10 +60,13 @@ import org.eclipse.jetty.webapp.MetaData; import org.eclipse.jetty.webapp.MetaData.OriginInfo; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.webapp.WebInfConfiguration; import org.eclipse.jetty.xml.XmlAppendable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * QuickStartDescriptorGenerator + * QuickStartGeneratorConfiguration *

      * Generate an effective web.xml from a WebAppContext, including all components * from web.xml, web-fragment.xmls annotations etc. @@ -75,16 +77,15 @@ import org.eclipse.jetty.xml.XmlAppendable; */ public class QuickStartGeneratorConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(QuickStartGeneratorConfiguration.class); + static final Logger LOG = LoggerFactory.getLogger(QuickStartGeneratorConfiguration.class); public static final String ORIGIN = "org.eclipse.jetty.originAttribute"; public static final String DEFAULT_ORIGIN_ATTRIBUTE_NAME = "origin"; protected final boolean _abort; protected String _originAttribute; - protected boolean _generateOrigin; protected int _count; protected Resource _quickStartWebXml; - + public QuickStartGeneratorConfiguration() { this(false); @@ -92,7 +93,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration public QuickStartGeneratorConfiguration(boolean abort) { - super(true); + super(false); _count = 0; _abort = abort; } @@ -116,22 +117,6 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration return _originAttribute; } - /** - * @return the generateOrigin - */ - public boolean isGenerateOrigin() - { - return _generateOrigin; - } - - /** - * @param generateOrigin the generateOrigin to set - */ - public void setGenerateOrigin(boolean generateOrigin) - { - _generateOrigin = generateOrigin; - } - public Resource getQuickStartWebXml() { return _quickStartWebXml; @@ -163,8 +148,6 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration if (context.getBaseResource() == null) throw new IllegalArgumentException("No base resource for " + this); - LOG.info("Quickstart generating"); - MetaData md = context.getMetaData(); Map webappAttr = new HashMap<>(); @@ -195,13 +178,21 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration //the META-INF/resources discovered addContextParamFromAttribute(context, out, MetaInfConfiguration.METAINF_RESOURCES, normalizer); - // the default-context-path, if presernt + // the default-context-path, if present String defaultContextPath = (String)context.getAttribute("default-context-path"); if (defaultContextPath != null) out.tag("default-context-path", defaultContextPath); + + String requestEncoding = (String)context.getAttribute("request-character-encoding"); + if (!StringUtil.isBlank(requestEncoding)) + out.tag("request-character-encoding", requestEncoding); + + String responseEncoding = (String)context.getAttribute("response-character-encoding"); + if (!StringUtil.isBlank(responseEncoding)) + out.tag("response-character-encoding", responseEncoding); //add the name of the origin attribute, if it is being used - if (_generateOrigin) + if (StringUtil.isNotBlank(_originAttribute)) { out.openTag("context-param") .tag("param-name", ORIGIN) @@ -766,7 +757,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration */ public Map origin(MetaData md, String name) { - if (!(_generateOrigin || LOG.isDebugEnabled())) + if (StringUtil.isBlank(_originAttribute)) return Collections.emptyMap(); if (name == null) return Collections.emptyMap(); @@ -792,13 +783,19 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration { MetaData metadata = context.getMetaData(); metadata.resolve(context); - - Resource quickStartWebXml = _quickStartWebXml; - if (_quickStartWebXml == null) - quickStartWebXml = context.getWebInf().addPath("/quickstart-web.xml"); - try (FileOutputStream fos = new FileOutputStream(quickStartWebXml.getFile(), false)) + try (FileOutputStream fos = new FileOutputStream(_quickStartWebXml.getFile(), false)) { generateQuickStartWebXml(context, fos); + LOG.info("Generated {}", _quickStartWebXml); + if (context.getAttribute(WebInfConfiguration.TEMPORARY_RESOURCE_BASE) != null && !context.isPersistTempDirectory()) + LOG.warn("Generated to non persistent location: " + _quickStartWebXml); } } + + @Override + public void deconfigure(WebAppContext context) throws Exception + { + super.deconfigure(context); + } + } diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java deleted file mode 100644 index 0cf95f8f1b5..00000000000 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.quickstart; - -import org.eclipse.jetty.annotations.AnnotationConfiguration; -import org.eclipse.jetty.plus.webapp.EnvConfiguration; -import org.eclipse.jetty.plus.webapp.PlusConfiguration; -import org.eclipse.jetty.quickstart.QuickStartConfiguration.Mode; -import org.eclipse.jetty.webapp.WebAppContext; - -/** - * QuickStartWar - */ -public class QuickStartWebApp extends WebAppContext -{ - private final QuickStartConfiguration _quickStartConfiguration; - - private String _originAttribute; - private boolean _generateOrigin; - - public QuickStartWebApp() - { - super(); - addConfiguration( - _quickStartConfiguration = new QuickStartConfiguration(), - new EnvConfiguration(), - new PlusConfiguration(), - new AnnotationConfiguration()); - setExtractWAR(true); - setCopyWebDir(false); - setCopyWebInf(false); - } - - public void setOriginAttribute(String name) - { - setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, name); - } - - /** - * @return the originAttribute - */ - public String getOriginAttribute() - { - Object attr = getAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE); - return attr == null ? null : attr.toString(); - } - - /** - * @param generateOrigin the generateOrigin to set - */ - public void setGenerateOrigin(boolean generateOrigin) - { - setAttribute(QuickStartConfiguration.GENERATE_ORIGIN, generateOrigin); - } - - /** - * @return the generateOrigin - */ - public boolean isGenerateOrigin() - { - Object attr = getAttribute(QuickStartConfiguration.GENERATE_ORIGIN); - return attr == null ? false : Boolean.valueOf(attr.toString()); - } - - public Mode getMode() - { - return _quickStartConfiguration.getMode(); - } - - public void setMode(Mode mode) - { - _quickStartConfiguration.setMode(mode); - } -} diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooContextListener.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooContextListener.java index 0d5ed19a3ed..150977c8d05 100644 --- a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooContextListener.java +++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooServlet.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooServlet.java index 750c6bcfb37..36a0bf9ea51 100644 --- a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooServlet.java +++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/FooServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; @@ -27,9 +27,6 @@ import javax.servlet.http.HttpServletResponse; public class FooServlet extends HttpServlet { - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java index 6e7b3ed3834..ba0541986d1 100644 --- a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java +++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.quickstart; @@ -27,6 +27,8 @@ import org.eclipse.jetty.servlet.ListenerHolder; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.webapp.WebAppContext; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -42,6 +44,7 @@ public class TestQuickStart { File testDir; File webInf; + Server server; @BeforeEach public void setUp() @@ -50,6 +53,13 @@ public class TestQuickStart FS.ensureEmpty(testDir); webInf = new File(testDir, "WEB-INF"); FS.ensureDirExists(webInf); + server = new Server(); + } + + @AfterEach + public void tearDown() throws Exception + { + server.stop(); } @Test @@ -58,13 +68,12 @@ public class TestQuickStart File quickstartXml = new File(webInf, "quickstart-web.xml"); assertFalse(quickstartXml.exists()); - Server server = new Server(); - //generate a quickstart-web.xml - QuickStartWebApp quickstart = new QuickStartWebApp(); + WebAppContext quickstart = new WebAppContext(); + quickstart.addConfiguration(new QuickStartConfiguration()); + quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.GENERATE); + quickstart.setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, "origin"); quickstart.setResourceBase(testDir.getAbsolutePath()); - quickstart.setMode(QuickStartConfiguration.Mode.GENERATE); - quickstart.setGenerateOrigin(true); ServletHolder fooHolder = new ServletHolder(); fooHolder.setServlet(new FooServlet()); fooHolder.setName("foo"); @@ -73,26 +82,27 @@ public class TestQuickStart lholder.setListener(new FooContextListener()); quickstart.getServletHandler().addListener(lholder); server.setHandler(quickstart); + server.setDryRun(true); server.start(); - server.stop(); assertTrue(quickstartXml.exists()); //now run the webapp again purely from the generated quickstart - QuickStartWebApp webapp = new QuickStartWebApp(); + WebAppContext webapp = new WebAppContext(); webapp.setResourceBase(testDir.getAbsolutePath()); - webapp.setMode(QuickStartConfiguration.Mode.QUICKSTART); + webapp.addConfiguration(new QuickStartConfiguration()); + webapp.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART); webapp.setClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader())); server.setHandler(webapp); + server.setDryRun(false); server.start(); + server.dumpStdErr(); //verify that FooServlet is now mapped to / and not the DefaultServlet ServletHolder sh = webapp.getServletHandler().getMappedServlet("/").getResource(); assertNotNull(sh); assertEquals("foo", sh.getName()); - - server.stop(); } @Test @@ -101,37 +111,70 @@ public class TestQuickStart File quickstartXml = new File(webInf, "quickstart-web.xml"); assertFalse(quickstartXml.exists()); - Server server = new Server(); - // generate a quickstart-web.xml - QuickStartWebApp quickstart = new QuickStartWebApp(); + WebAppContext quickstart = new WebAppContext(); quickstart.setResourceBase(testDir.getAbsolutePath()); - quickstart.setMode(QuickStartConfiguration.Mode.GENERATE); - quickstart.setGenerateOrigin(true); + quickstart.addConfiguration(new QuickStartConfiguration()); + quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.GENERATE); + quickstart.setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, "origin"); quickstart.setDescriptor(MavenTestingUtils.getTestResourceFile("web.xml").getAbsolutePath()); quickstart.setContextPath("/foo"); server.setHandler(quickstart); + server.setDryRun(true); server.start(); - assertEquals("/foo", quickstart.getContextPath()); assertFalse(quickstart.isContextPathDefault()); - server.stop(); assertTrue(quickstartXml.exists()); // quick start - QuickStartWebApp webapp = new QuickStartWebApp(); + WebAppContext webapp = new WebAppContext(); + webapp.addConfiguration(new QuickStartConfiguration()); + quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART); webapp.setResourceBase(testDir.getAbsolutePath()); - webapp.setMode(QuickStartConfiguration.Mode.QUICKSTART); webapp.setClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader())); server.setHandler(webapp); + server.setDryRun(false); server.start(); // verify the context path is the default-context-path assertEquals("/thisIsTheDefault", webapp.getContextPath()); assertTrue(webapp.isContextPathDefault()); + } + + @Test + public void testDefaultRequestAndResponseEncodings() throws Exception + { + File quickstartXml = new File(webInf, "quickstart-web.xml"); + assertFalse(quickstartXml.exists()); - server.stop(); + // generate a quickstart-web.xml + WebAppContext quickstart = new WebAppContext(); + quickstart.setResourceBase(testDir.getAbsolutePath()); + quickstart.addConfiguration(new QuickStartConfiguration()); + quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.GENERATE); + quickstart.setAttribute(QuickStartConfiguration.ORIGIN_ATTRIBUTE, "origin"); + quickstart.setDescriptor(MavenTestingUtils.getTestResourceFile("web.xml").getAbsolutePath()); + quickstart.setContextPath("/foo"); + server.setHandler(quickstart); + server.setDryRun(true); + server.start(); + + assertTrue(quickstartXml.exists()); + + // quick start + WebAppContext webapp = new WebAppContext(); + webapp.addConfiguration(new QuickStartConfiguration()); + quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART); + webapp.setResourceBase(testDir.getAbsolutePath()); + webapp.setClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader())); + server.setHandler(webapp); + + server.setDryRun(false); + server.start(); + + assertEquals("ascii", webapp.getDefaultRequestCharacterEncoding()); + assertEquals("utf-16", webapp.getDefaultResponseCharacterEncoding()); } } diff --git a/jetty-quickstart/src/test/resources/web.xml b/jetty-quickstart/src/test/resources/web.xml index 68b02eec221..cf4aef929c5 100644 --- a/jetty-quickstart/src/test/resources/web.xml +++ b/jetty-quickstart/src/test/resources/web.xml @@ -10,6 +10,8 @@ /thisIsTheDefault + ascii + utf-16 diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 76b9b905bc1..5083912a1a8 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -36,7 +36,15 @@ org.eclipse.jetty.toolchain jetty-servlet-api - + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.tests jetty-http-tools diff --git a/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod b/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod index 5caea6942c8..a1231ca8def 100644 --- a/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod +++ b/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod @@ -1,4 +1,4 @@ -DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] Enables a rewrite Rules container as a request customizer on diff --git a/jetty-rewrite/src/main/config/modules/rewrite.mod b/jetty-rewrite/src/main/config/modules/rewrite.mod index 939acebdd12..3d9bb91b074 100644 --- a/jetty-rewrite/src/main/config/modules/rewrite.mod +++ b/jetty-rewrite/src/main/config/modules/rewrite.mod @@ -1,11 +1,11 @@ -DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] Enables the jetty-rewrite handler. Specific rewrite rules must be added to either to etc/jetty-rewrite.xml or a custom xml/module [provides] -rewrite +rewrite|default [depend] server diff --git a/jetty-rewrite/src/main/java/module-info.java b/jetty-rewrite/src/main/java/module-info.java index c942ff0c359..7fa740254e8 100644 --- a/jetty-rewrite/src/main/java/module-info.java +++ b/jetty-rewrite/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.rewrite @@ -22,8 +22,6 @@ module org.eclipse.jetty.rewrite exports org.eclipse.jetty.rewrite.handler; requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.server; + requires org.slf4j; } diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java index 3b59b28908d..59d1a898587 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java index a6663fb3dcf..d091820f089 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java index 3acb75f05e7..9290dd3811e 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -70,10 +70,6 @@ public class CookiePatternRule extends PatternRule _value = value; } - /* - * (non-Javadoc) - * @see org.eclipse.jetty.server.server.handler.rules.RuleBase#apply(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException { diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java index 2d26ed8f21b..9295b8be393 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -46,7 +46,8 @@ public class ForwardedSchemeHeaderRule extends HeaderRule @Override protected String apply(String target, String value, HttpServletRequest request, HttpServletResponse response) { - ((Request)request).setScheme(_scheme); + Request baseRequest = Request.getBaseRequest(request); + baseRequest.setScheme(_scheme); return target; } } diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java index fcd47684c16..65140255343 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java index 2efea541045..6dc87089b0d 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java index f2977d86488..47caa3d18b8 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/MsieSslRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/MsieSslRule.java index 1b92add9c28..f88e5640b46 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/MsieSslRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/MsieSslRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/PatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/PatternRule.java index 16b2221c141..11afc47b21d 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/PatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/PatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -57,9 +57,6 @@ public abstract class PatternRule extends Rule _pattern = pattern; } - /* (non-Javadoc) - * @see org.eclipse.jetty.server.server.handler.rules.RuleBase#matchAndApply(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException { diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRule.java index 8f07ad9547f..c4102db73fb 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java index 2b4c88e6fbc..9e683033a96 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectUtil.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectUtil.java index fcc8a9096be..f0d0eb7ccf0 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectUtil.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexRule.java index 46ec0f4aaec..9f222addd70 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRule.java index 86abf843ef4..01d866148c2 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -68,10 +68,6 @@ public class ResponsePatternRule extends PatternRule _message = message; } - /* - * (non-Javadoc) - * @see org.eclipse.jetty.server.server.handler.rules.RuleBase#apply(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException { diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java index c7ab806e28a..81db59e9457 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -293,9 +293,6 @@ public class RewriteHandler extends HandlerWrapper _dispatchTypes = EnumSet.copyOf(Arrays.asList(types)); } - /* (non-Javadoc) - * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java index a7f46ccbb80..aaf70aa1dde 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java index 2702683da73..fdfe7587216 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -75,9 +75,6 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI } } - /* (non-Javadoc) - * @see org.eclipse.jetty.server.handler.rules.RegexRule#apply(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.util.regex.Matcher) - */ @Override public String apply(String target, HttpServletRequest request, HttpServletResponse response, Matcher matcher) throws IOException { diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java index be70389776c..2be6568d7ce 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java index f04b7f3c1bd..a1eff8f762d 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -22,12 +22,14 @@ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.ArrayUtil; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Base container to group rules. Can be extended so that the contained rules @@ -36,7 +38,7 @@ import org.eclipse.jetty.util.log.Logger; public class RuleContainer extends Rule implements Dumpable { public static final String ORIGINAL_QUERYSTRING_ATTRIBUTE_SUFFIX = ".QUERYSTRING"; - private static final Logger LOG = Log.getLogger(RuleContainer.class); + private static final Logger LOG = LoggerFactory.getLogger(RuleContainer.class); protected Rule[] _rules; @@ -185,7 +187,18 @@ public class RuleContainer extends Rule implements Dumpable if (rule instanceof Rule.ApplyURI) ((Rule.ApplyURI)rule).applyURI(baseRequest, baseRequest.getRequestURI(), encoded); else - baseRequest.setURIPathQuery(encoded); + { + String uriPathQuery = encoded; + HttpURI baseUri = baseRequest.getHttpURI(); + // Copy path params from original URI if present + if ((baseUri != null) && StringUtil.isNotBlank(baseUri.getParam())) + { + HttpURI uri = new HttpURI(uriPathQuery); + uri.setParam(baseUri.getParam()); + uriPathQuery = uri.toString(); + } + baseRequest.setURIPathQuery(uriPathQuery); + } } if (_rewritePathInfo) diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java index 7cff30164a4..4764d73cccc 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java index 80b0860d848..2bfb2663ede 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java index 0e81441951e..e159703cf02 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -23,8 +23,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This rule can be used to protect against invalid unicode characters in a url making it into applications. @@ -38,7 +38,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ValidUrlRule extends Rule { - private static final Logger LOG = Log.getLogger(ValidUrlRule.class); + private static final Logger LOG = LoggerFactory.getLogger(ValidUrlRule.class); String _code = "400"; String _message = "Illegal Url"; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java index d3041d2c008..e4f853a0fbf 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java index 75058dae819..260562c6051 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java index 799bef6a00c..63eb6de98c0 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTestCase.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java index 45a59faa1fd..08253d96c50 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -37,7 +37,6 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -48,7 +47,6 @@ import static org.junit.jupiter.api.Assertions.fail; public class CookiePatternRuleTest { - private Server server; private LocalConnector localConnector; @@ -150,7 +148,6 @@ public class CookiePatternRuleTest } @Test - @Disabled("See #2675 for details") // TODO: needs to be fixed in RuleContainer public void testUrlParameter() throws Exception { CookiePatternRule rule = new CookiePatternRule(); @@ -170,7 +167,6 @@ public class CookiePatternRuleTest HttpTester.Response response = HttpTester.parseResponse(rawResponse); String responseContent = response.getContent(); - System.out.println(responseContent); assertResponseContentLine(responseContent, "baseRequest.requestUri=", "/other;fruit=apple"); // verify diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java index 736888cc320..ec5dd69f079 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java index 49136242fde..c7d90a6d955 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -42,7 +42,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase public void testHeaderWithTextValues() throws IOException { // different keys - String headers[][] = { + String[][] headers = { {"hnum#1", "test1"}, {"hnum#2", "2test2"}, {"hnum#3", "test3"} @@ -53,7 +53,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase @Test public void testHeaderWithNumberValues() throws IOException { - String headers[][] = { + String[][] headers = { {"hello", "1"}, {"hello", "-1"}, {"hello", "100"}, @@ -70,7 +70,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase @Test public void testHeaderOverwriteValues() throws IOException { - String headers[][] = { + String[][] headers = { {"size", "100"}, {"size", "200"}, {"size", "300"}, @@ -100,7 +100,7 @@ public class HeaderPatternRuleTest extends AbstractRuleTestCase assertEquals("abba1", _response.getHeader("title1")); } - private void assertHeaders(String headers[][]) throws IOException + private void assertHeaders(String[][] headers) throws IOException { for (String[] header : headers) { diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java index 52851f5a92a..871b77203b6 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -43,7 +43,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase public void testHeaderWithTextValues() throws IOException { // different keys - String headers[][] = + String[][] headers = { {"hnum#1", "test1"}, {"hnum#2", "2test2"}, @@ -55,7 +55,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase @Test public void testHeaderWithNumberValues() throws IOException { - String headers[][] = + String[][] headers = { {"hello", "1"}, {"hello", "-1"}, @@ -72,7 +72,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase @Test public void testHeaderOverwriteValues() throws IOException { - String headers[][] = + String[][] headers = { {"size", "100"}, {"size", "200"}, @@ -122,7 +122,7 @@ public class HeaderRegexRuleTest extends AbstractRuleTestCase assertEquals(null, _response.getHeader("cache-control")); } - private void assertHeaders(String headers[][]) throws IOException + private void assertHeaders(String[][] headers) throws IOException { for (String[] header : headers) { diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java index 859b9b4c4bd..a0e9e82375e 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/MsieSslRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java index 7e70d0d2406..587f5bea674 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java index ee0f47b9c60..96d24ef4b5a 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java index f31089fa34a..de776bb95a9 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java index 8aa7f64407b..e2438c274ed 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java index bef3e4af1c6..b41d5424864 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java index dff9a7bf3b1..49703c1799e 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java index 4977d6a5425..280e22df079 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -37,7 +37,7 @@ public class RewritePatternRuleTest extends AbstractRuleTestCase {"/foo/bar", "/foo/bar", "/replace"}, {"/foo/bar.txt", "*.txt", "/replace"}, {"/foo/bar/%20x", "/foo/*", "/replace/bar/%20x"}, - }; + }; private RewritePatternRule _rule; @BeforeEach diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java index f68353cc153..ef9638fa39d 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java index a19f61c9cea..9f27fc1b72d 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java index dbdaf2d17e3..53d8ca80b27 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ValidUrlRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ValidUrlRuleTest.java index 2eef7648bca..1da1486a9d9 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ValidUrlRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ValidUrlRuleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; @@ -120,7 +120,9 @@ public class ValidUrlRuleTest extends AbstractRuleTestCase // space assertTrue(_rule.isValidChar("\u0020".charAt(0))); // form feed + //@checkstyle-disable-check : IllegalTokenText assertFalse(_rule.isValidChar("\u000c".charAt(0))); + //@checkstyle-enable-check : IllegalTokenText } } diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java index 9aed943fd46..300e7e82bdc 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.rewrite.handler; diff --git a/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml b/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml index 90dc198b4f3..dedac35bc32 100644 --- a/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml +++ b/jetty-rewrite/src/test/resources/org.mortbay.jetty.rewrite.handler/jetty-rewrite.xml @@ -43,7 +43,7 @@ - + diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 03dac2de706..b979e13e777 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -113,7 +113,7 @@ org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} @@ -131,5 +131,14 @@ apache-jstl ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + runtime + diff --git a/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java b/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java index 49160ff6e2f..0e67904d8f4 100644 --- a/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java +++ b/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.runner; @@ -53,13 +53,13 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.StatisticsServlet; import org.eclipse.jetty.util.RolloverFileOutputStream; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Runner @@ -71,7 +71,7 @@ import org.eclipse.jetty.xml.XmlConfiguration; @Deprecated public class Runner { - private static final Logger LOG = Log.getLogger(Runner.class); + private static final Logger LOG = LoggerFactory.getLogger(Runner.class); public static final String[] PLUS_CONFIGURATION_CLASSES = { diff --git a/jetty-runner/src/main/java/org/eclipse/jetty/runner/package-info.java b/jetty-runner/src/main/java/org/eclipse/jetty/runner/package-info.java index 57a9ac3b871..8cf44e618e9 100644 --- a/jetty-runner/src/main/java/org/eclipse/jetty/runner/package-info.java +++ b/jetty-runner/src/main/java/org/eclipse/jetty/runner/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-runner/src/main/resources/jetty-logging.properties b/jetty-runner/src/main/resources/jetty-logging.properties new file mode 100644 index 00000000000..1de0a5d8bb8 --- /dev/null +++ b/jetty-runner/src/main/resources/jetty-logging.properties @@ -0,0 +1,2 @@ +# Jetty Logging using jetty-slf4j-impl +org.eclipse.jetty.LEVEL=INFO \ No newline at end of file diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 90569d68b0f..15cae93142c 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -24,6 +24,23 @@ org.eclipse.jetty.security.* + + org.apache.felix + maven-bundle-plugin + true + + + + manifest + + + + osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory)";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional + + + + + @@ -33,7 +50,16 @@ jetty-server ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.tests jetty-http-tools diff --git a/jetty-security/src/main/java/module-info.java b/jetty-security/src/main/java/module-info.java index d5a8d543724..06c20fccb8e 100644 --- a/jetty-security/src/main/java/module-info.java +++ b/jetty-security/src/main/java/module-info.java @@ -1,33 +1,35 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // +import org.eclipse.jetty.security.Authenticator; + module org.eclipse.jetty.security { exports org.eclipse.jetty.security; exports org.eclipse.jetty.security.authentication; - requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.server; + requires org.slf4j; // Only required if using JDBCLoginService. requires static java.sql; // Only required if using SPNEGO. requires static java.security.jgss; + + uses Authenticator.Factory; } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java index 481ad94322f..3584be44c36 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -25,16 +25,16 @@ import javax.servlet.ServletRequest; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractLoginService */ public abstract class AbstractLoginService extends ContainerLifeCycle implements LoginService { - private static final Logger LOG = Log.getLogger(AbstractLoginService.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractLoginService.class); protected IdentityService _identityService = new DefaultIdentityService(); protected String _name; @@ -107,9 +107,6 @@ public abstract class AbstractLoginService extends ContainerLifeCycle implements addBean(_identityService); } - /** - * @see org.eclipse.jetty.security.LoginService#getName() - */ @Override public String getName() { @@ -148,9 +145,6 @@ public abstract class AbstractLoginService extends ContainerLifeCycle implements return String.format("%s@%x[%s]", this.getClass().getSimpleName(), hashCode(), _name); } - /** - * @see org.eclipse.jetty.security.LoginService#login(java.lang.String, java.lang.Object, javax.servlet.ServletRequest) - */ @Override public UserIdentity login(String username, Object credentials, ServletRequest request) { @@ -178,9 +172,6 @@ public abstract class AbstractLoginService extends ContainerLifeCycle implements return null; } - /** - * @see org.eclipse.jetty.security.LoginService#validate(org.eclipse.jetty.server.UserIdentity) - */ @Override public boolean validate(UserIdentity user) { @@ -200,18 +191,12 @@ public abstract class AbstractLoginService extends ContainerLifeCycle implements throw new IllegalStateException("UserPrincipal not KnownUser"); //can't validate } - /** - * @see org.eclipse.jetty.security.LoginService#getIdentityService() - */ @Override public IdentityService getIdentityService() { return _identityService; } - /** - * @see org.eclipse.jetty.security.LoginService#logout(org.eclipse.jetty.server.UserIdentity) - */ @Override public void logout(UserIdentity user) { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index e831c006095..bc9057965d1 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 7fb46640bcf..26c81c974bc 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java index ab3008edd5c..9f521f9a277 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -36,14 +36,14 @@ import javax.servlet.http.HttpSession; import org.eclipse.jetty.security.authentication.AuthorizationService; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import org.ietf.jgss.Oid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A configurable (as opposed to using system properties) SPNEGO LoginService.

      @@ -51,14 +51,14 @@ import org.ietf.jgss.Oid; * of the {@link #getServiceName() service name} and the {@link #getHostName() host name}, * for example {@code HTTP/wonder.com}, using a {@code keyTab} file as the service principal * credentials.

      - *

      Upon receiving a HTTP request, the server tries to authenticate the client + *

      Upon receiving an HTTP request, the server tries to authenticate the client * calling {@link #login(String, Object, ServletRequest)} where the GSS APIs are used to * verify client tokens and (perhaps after a few round-trips) a {@code GSSContext} is * established.

      */ public class ConfigurableSpnegoLoginService extends ContainerLifeCycle implements LoginService { - private static final Logger LOG = Log.getLogger(ConfigurableSpnegoLoginService.class); + private static final Logger LOG = LoggerFactory.getLogger(ConfigurableSpnegoLoginService.class); private final GSSManager _gssManager = GSSManager.getInstance(); private final String _realm; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java index 09d4112fc20..0f2a41cb9fe 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java index 20ed69c66df..9752749a203 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java index 26aede1f640..fae59423c75 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -47,9 +47,9 @@ import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ConstraintSecurityHandler @@ -60,7 +60,7 @@ import org.eclipse.jetty.util.security.Constraint; */ public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware { - private static final Logger LOG = Log.getLogger(SecurityHandler.class); //use same as SecurityHandler + private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); //use same as SecurityHandler private static final String OMISSION_SUFFIX = ".omission"; private static final String ALL_METHODS = "*"; @@ -352,9 +352,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr _roles.addAll(roles); } - /** - * @see org.eclipse.jetty.security.ConstraintAware#addConstraintMapping(org.eclipse.jetty.security.ConstraintMapping) - */ @Override public void addConstraintMapping(ConstraintMapping mapping) { @@ -377,9 +374,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr } } - /** - * @see org.eclipse.jetty.security.ConstraintAware#addRole(java.lang.String) - */ @Override public void addRole(String role) { @@ -399,9 +393,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr } } - /** - * @see org.eclipse.jetty.security.SecurityHandler#doStart() - */ @Override protected void doStart() throws Exception { @@ -677,9 +668,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr return constraintInfo != null && ((RoleInfo)constraintInfo).isChecked(); } - /** - * @see org.eclipse.jetty.security.SecurityHandler#checkWebResourcePermissions(java.lang.String, org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object, org.eclipse.jetty.server.UserIdentity) - */ @Override protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity) throws IOException @@ -735,9 +723,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr DumpableCollection.from("constraints", _constraintMappings)); } - /** - * @see org.eclipse.jetty.security.ConstraintAware#setDenyUncoveredHttpMethods(boolean) - */ @Override public void setDenyUncoveredHttpMethods(boolean deny) { @@ -759,12 +744,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr Set paths = getPathsWithUncoveredHttpMethods(); if (paths != null && !paths.isEmpty()) { + ContextHandler.Context currentContext = ContextHandler.getCurrentContext(); + for (String p : paths) { - LOG.warn("{} has uncovered http methods for path: {}", ContextHandler.getCurrentContext(), p); + LOG.warn("{} has uncovered http methods for path: {}", currentContext, p); } if (LOG.isDebugEnabled()) - LOG.debug(new Throwable()); + LOG.debug("{} has uncovered http methods", currentContext, new Throwable()); return true; } return false; @@ -814,7 +801,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr { //an exact method name if (!hasOmissions) - //a http-method does not have http-method-omission to cover the other method names + //an http-method does not have http-method-omission to cover the other method names uncoveredPaths.add(path); } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java index 039a4f46f96..1b7edcec9cd 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java index 5715c73dd15..440b498b23b 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java index cab3fb2e124..40fb9396258 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java index 527ebbf090d..12ab94ec680 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -23,8 +23,8 @@ import java.util.Set; import java.util.stream.Collectors; import org.eclipse.jetty.server.UserIdentity; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Properties User Realm. @@ -44,7 +44,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HashLoginService extends AbstractLoginService { - private static final Logger LOG = Log.getLogger(HashLoginService.class); + private static final Logger LOG = LoggerFactory.getLogger(HashLoginService.class); private String _config; private boolean hotReload = false; // default is not to reload @@ -150,9 +150,6 @@ public class HashLoginService extends AbstractLoginService return null; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -191,9 +188,6 @@ public class HashLoginService extends AbstractLoginService return _userStoreAutoCreate; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index f99c0863036..fce20924d37 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java index 09be2a96985..67c35d85eb6 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -31,10 +31,10 @@ import java.util.Properties; import javax.servlet.ServletRequest; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * HashMapped User Realm with JDBC as data source. @@ -51,7 +51,7 @@ import org.eclipse.jetty.util.security.Credential; */ public class JDBCLoginService extends AbstractLoginService { - private static final Logger LOG = Log.getLogger(JDBCLoginService.class); + private static final Logger LOG = LoggerFactory.getLogger(JDBCLoginService.class); protected String _config; protected String _jdbcDriver; @@ -262,9 +262,6 @@ public class JDBCLoginService extends AbstractLoginService return null; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -287,7 +284,7 @@ public class JDBCLoginService extends AbstractLoginService } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } _con = null; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java index 6732ee95885..918d5790e93 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java index c2f0d300cff..b9e691889a4 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index 9ad42f9cfa8..aec9c720f95 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -35,12 +35,12 @@ import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.PathWatcher; import org.eclipse.jetty.util.PathWatcher.PathWatchEvent; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarFileResource; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      This class monitors a property file of the format mentioned below @@ -59,7 +59,7 @@ import org.eclipse.jetty.util.security.Credential; */ public class PropertyUserStore extends UserStore implements PathWatcher.Listener { - private static final Logger LOG = Log.getLogger(PropertyUserStore.class); + private static final Logger LOG = LoggerFactory.getLogger(PropertyUserStore.class); protected Path _configPath; protected PathWatcher _pathWatcher; @@ -305,7 +305,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener } catch (IOException e) { - LOG.warn(e); + LOG.warn("Unable to load users", e); } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java b/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java index a2699188b22..ccb8f7af891 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java b/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java index 6309c64365a..7b382792b95 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java b/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java index 3750ee0d105..ee0aafe2b11 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 62df3199fd7..020c12b0005 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -1,29 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; import java.io.IOException; import java.security.Principal; +import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.ServiceLoader; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -38,8 +41,10 @@ import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.component.DumpableCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Abstract SecurityHandler. @@ -57,21 +62,29 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class SecurityHandler extends HandlerWrapper implements Authenticator.AuthConfiguration { - private static final Logger LOG = Log.getLogger(SecurityHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); + private static final List __knownAuthenticatorFactories = new ArrayList<>(); private boolean _checkWelcomeFiles = false; private Authenticator _authenticator; - private Authenticator.Factory _authenticatorFactory = new DefaultAuthenticatorFactory(); + private Authenticator.Factory _authenticatorFactory; private String _realmName; private String _authMethod; - private final Map _initParameters = new HashMap(); + private final Map _initParameters = new HashMap<>(); private LoginService _loginService; private IdentityService _identityService; private boolean _renewSession = true; + static + { + TypeUtil.serviceStream(ServiceLoader.load(Authenticator.Factory.class)) + .forEach(__knownAuthenticatorFactories::add); + __knownAuthenticatorFactories.add(new DefaultAuthenticatorFactory()); + } + protected SecurityHandler() { - addBean(_authenticatorFactory); + addBean(new DumpableCollection("knownAuthenticatorFactories", __knownAuthenticatorFactories)); } /** @@ -163,6 +176,14 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti _authenticatorFactory = authenticatorFactory; } + /** + * @return the list of discovered authenticatorFactories + */ + public List getKnownAuthenticatorFactories() + { + return __knownAuthenticatorFactories; + } + /** * @return the realmName */ @@ -241,12 +262,12 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti * @param key the init key * @param value the init value * @return previous value - * @throws IllegalStateException if the SecurityHandler is running + * @throws IllegalStateException if the SecurityHandler is started */ public String setInitParameter(String key, String value) { - if (isRunning()) - throw new IllegalStateException("running"); + if (isStarted()) + throw new IllegalStateException("started"); return _initParameters.put(key, value); } @@ -336,9 +357,40 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti throw new IllegalStateException("LoginService has different IdentityService to " + this); } - Authenticator.Factory authenticatorFactory = getAuthenticatorFactory(); - if (_authenticator == null && authenticatorFactory != null && _identityService != null) - setAuthenticator(authenticatorFactory.getAuthenticator(getServer(), ContextHandler.getCurrentContext(), this, _identityService, _loginService)); + if (_authenticator == null && _identityService != null) + { + // If someone has set an authenticator factory only use that, otherwise try the list of discovered factories. + if (_authenticatorFactory != null) + { + Authenticator authenticator = _authenticatorFactory.getAuthenticator(getServer(), ContextHandler.getCurrentContext(), + this, _identityService, _loginService); + + if (authenticator != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("Created authenticator {} with {}", authenticator, _authenticatorFactory); + + setAuthenticator(authenticator); + } + } + else + { + for (Authenticator.Factory factory : getKnownAuthenticatorFactories()) + { + Authenticator authenticator = factory.getAuthenticator(getServer(), ContextHandler.getCurrentContext(), + this, _identityService, _loginService); + + if (authenticator != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("Created authenticator {} with {}", authenticator, factory); + + setAuthenticator(authenticator); + break; + } + } + } + } if (_authenticator != null) _authenticator.setConfiguration(this); @@ -390,9 +442,6 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } } - /** - * @see org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication() - */ @Override public boolean isSessionRenewedOnAuthentication() { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java index 4a459d89eed..a5dbe06781c 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java index cd54c05fd9b..63433549c25 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java index 8365b8af725..4508cb94310 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java index 91c2c36843a..98ac0bf2316 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java b/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java index 0cf53a2d038..fd297ab63e5 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java index 426c76713bb..9efde97029e 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java index 82da2fa15e2..e150ec98666 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java index 71b6cd3a31c..d60dcd09901 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -44,18 +44,12 @@ public class BasicAuthenticator extends LoginAuthenticator { } - /** - * @see org.eclipse.jetty.security.Authenticator#getAuthMethod() - */ @Override public String getAuthMethod() { return Constraint.__BASIC_AUTH; } - /** - * @see org.eclipse.jetty.security.Authenticator#validateRequest(javax.servlet.ServletRequest, javax.servlet.ServletResponse, boolean) - */ @Override public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java index 1677d1c6d9e..330928ee58d 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -58,7 +58,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator /** * Truststore type */ - private String _trustStoreType = "JKS"; + private String _trustStoreType = "PKCS12"; /** * Truststore password */ @@ -251,7 +251,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator } /** - * @return The type of the trust store (default "JKS") + * @return The type of the trust store (default "PKCS12") */ public String getTrustStoreType() { @@ -259,7 +259,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator } /** - * @param trustStoreType The type of the trust store (default "JKS") + * @param trustStoreType The type of the trust store */ public void setTrustStoreType(String trustStoreType) { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java index 48bf5cdd7e8..4861a25cdbf 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -38,9 +38,9 @@ import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Authentication.User; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.UserIdentity; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A LoginAuthenticator that uses SPNEGO and the GSS API to authenticate requests.

      @@ -52,7 +52,7 @@ import org.eclipse.jetty.util.security.Constraint; */ public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator { - private static final Logger LOG = Log.getLogger(ConfigurableSpnegoAuthenticator.class); + private static final Logger LOG = LoggerFactory.getLogger(ConfigurableSpnegoAuthenticator.class); private final String _authMethod; private Duration _authenticationDuration = Duration.ofNanos(-1); diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index e89dbed9d6d..71a25034bac 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -39,12 +39,12 @@ import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DeferredAuthentication implements Authentication.Deferred { - private static final Logger LOG = Log.getLogger(DeferredAuthentication.class); + private static final Logger LOG = LoggerFactory.getLogger(DeferredAuthentication.class); protected final LoginAuthenticator _authenticator; private Object _previousAssociation; @@ -55,9 +55,6 @@ public class DeferredAuthentication implements Authentication.Deferred this._authenticator = authenticator; } - /** - * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(ServletRequest) - */ @Override public Authentication authenticate(ServletRequest request) { @@ -77,15 +74,12 @@ public class DeferredAuthentication implements Authentication.Deferred } catch (ServerAuthException e) { - LOG.debug(e); + LOG.debug("Unable to authenticate {}", request, e); } return this; } - /** - * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(javax.servlet.ServletRequest, javax.servlet.ServletResponse) - */ @Override public Authentication authenticate(ServletRequest request, ServletResponse response) { @@ -101,14 +95,11 @@ public class DeferredAuthentication implements Authentication.Deferred } catch (ServerAuthException e) { - LOG.debug(e); + LOG.debug("Unable to authenticate {}", request, e); } return this; } - /** - * @see org.eclipse.jetty.server.Authentication.Deferred#login(String, Object, ServletRequest) - */ @Override public Authentication login(String username, Object password, ServletRequest request) { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index ce8e1bc281b..d97750c1f45 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -44,10 +44,10 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} @@ -56,7 +56,7 @@ import org.eclipse.jetty.util.security.Credential; */ public class DigestAuthenticator extends LoginAuthenticator { - private static final Logger LOG = Log.getLogger(DigestAuthenticator.class); + private static final Logger LOG = LoggerFactory.getLogger(DigestAuthenticator.class); private final SecureRandom _random = new SecureRandom(); private long _maxNonceAgeMs = 60 * 1000; @@ -121,6 +121,8 @@ public class DigestAuthenticator extends LoginAuthenticator try { + Request baseRequest = Request.getBaseRequest(request); + boolean stale = false; if (credentials != null) { @@ -173,7 +175,7 @@ public class DigestAuthenticator extends LoginAuthenticator } } - int n = checkNonce(digest, (Request)request); + int n = checkNonce(digest, baseRequest); if (n > 0) { @@ -195,7 +197,7 @@ public class DigestAuthenticator extends LoginAuthenticator domain = "/"; response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), "Digest realm=\"" + _loginService.getName() + "\", domain=\"" + domain + - "\", nonce=\"" + newNonce((Request)request) + + "\", nonce=\"" + newNonce(baseRequest) + "\", algorithm=MD5" + ", qop=\"auth\"" + ", stale=" + stale); @@ -273,7 +275,7 @@ public class DigestAuthenticator extends LoginAuthenticator } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return -1; } @@ -382,7 +384,7 @@ public class DigestAuthenticator extends LoginAuthenticator } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to process digest", e); } return false; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index ea913c476da..383dfd6f274 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -47,9 +47,9 @@ import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * FORM Authenticator. @@ -66,7 +66,7 @@ import org.eclipse.jetty.util.security.Constraint; */ public class FormAuthenticator extends LoginAuthenticator { - private static final Logger LOG = Log.getLogger(FormAuthenticator.class); + private static final Logger LOG = LoggerFactory.getLogger(FormAuthenticator.class); public static final String __FORM_LOGIN_PAGE = "org.eclipse.jetty.security.form_login_page"; public static final String __FORM_ERROR_PAGE = "org.eclipse.jetty.security.form_error_page"; @@ -117,9 +117,6 @@ public class FormAuthenticator extends LoginAuthenticator return _alwaysSaveUri; } - /** - * @see org.eclipse.jetty.security.authentication.LoginAuthenticator#setConfiguration(org.eclipse.jetty.security.Authenticator.AuthConfiguration) - */ @Override public void setConfiguration(AuthConfiguration configuration) { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 2052911e973..1c9ac1a659a 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -30,12 +30,12 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.session.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class LoginAuthenticator implements Authenticator { - private static final Logger LOG = Log.getLogger(LoginAuthenticator.class); + private static final Logger LOG = LoggerFactory.getLogger(LoginAuthenticator.class); protected LoginService _loginService; protected IdentityService _identityService; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java index cbfbfc5008c..07a61da6d57 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java index 2367042ba3a..e3e0e00b3f3 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index eaa66a0d81a..8092529925d 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; @@ -23,7 +23,6 @@ import java.io.ObjectInputStream; import java.io.Serializable; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionActivationListener; -import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionEvent; @@ -31,20 +30,20 @@ import org.eclipse.jetty.security.AbstractUserAuthentication; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.server.UserIdentity; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SessionAuthentication * * When a user has been successfully authenticated with some types * of Authenticator, the Authenticator stashes a SessionAuthentication - * into a HttpSession to remember that the user is authenticated. + * into an HttpSession to remember that the user is authenticated. */ public class SessionAuthentication extends AbstractUserAuthentication implements Serializable, HttpSessionActivationListener, HttpSessionBindingListener { - private static final Logger LOG = Log.getLogger(SessionAuthentication.class); + private static final Logger LOG = LoggerFactory.getLogger(SessionAuthentication.class); private static final long serialVersionUID = -4643200685888258706L; @@ -113,16 +112,4 @@ public class SessionAuthentication extends AbstractUserAuthentication _session = se.getSession(); } } - - @Override - @Deprecated - public void valueBound(HttpSessionBindingEvent event) - { - } - - @Override - @Deprecated - public void valueUnbound(HttpSessionBindingEvent event) - { - } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java index eab242900bc..fb9864833d0 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java b/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java index 77b20e4921b..5b287aff581 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java index 927f14935cc..413bebee3ec 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java index 9fdc629230d..2cb0382f398 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/ConstraintTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -99,27 +99,27 @@ public class ConstraintTest _config = _connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration(); _server.setConnectors(new Connector[]{_connector}); - ContextHandler _context = new ContextHandler(); - SessionHandler _session = new SessionHandler(); + ContextHandler contextHandler = new ContextHandler(); + SessionHandler sessionHandler = new SessionHandler(); - TestLoginService _loginService = new TestLoginService(TEST_REALM); + TestLoginService loginService = new TestLoginService(TEST_REALM); - _loginService.putUser("user0", new Password("password"), new String[]{}); - _loginService.putUser("user", new Password("password"), new String[]{"user"}); - _loginService.putUser("user2", new Password("password"), new String[]{"user"}); - _loginService.putUser("admin", new Password("password"), new String[]{"user", "administrator"}); - _loginService.putUser("user3", new Password("password"), new String[]{"foo"}); + loginService.putUser("user0", new Password("password"), new String[]{}); + loginService.putUser("user", new Password("password"), new String[]{"user"}); + loginService.putUser("user2", new Password("password"), new String[]{"user"}); + loginService.putUser("admin", new Password("password"), new String[]{"user", "administrator"}); + loginService.putUser("user3", new Password("password"), new String[]{"foo"}); - _context.setContextPath("/ctx"); - _server.setHandler(_context); - _context.setHandler(_session); + contextHandler.setContextPath("/ctx"); + _server.setHandler(contextHandler); + contextHandler.setHandler(sessionHandler); - _server.addBean(_loginService); + _server.addBean(loginService); _security = new ConstraintSecurityHandler(); - _session.setHandler(_security); - RequestHandler _handler = new RequestHandler(); - _security.setHandler(_handler); + sessionHandler.setHandler(_security); + RequestHandler requestHandler = new RequestHandler(); + _security.setHandler(requestHandler); _security.setConstraintMappings(getConstraintMappings(), getKnownRoles()); } @@ -242,7 +242,7 @@ public class ConstraintTest * @throws Exception if test fails */ @Test - public void testSecurityElementExample13_1() throws Exception + public void testSecurityElementExample131() throws Exception { ServletSecurityElement element = new ServletSecurityElement(); List mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element); @@ -256,7 +256,7 @@ public class ConstraintTest * @throws Exception if test fails */ @Test - public void testSecurityElementExample13_2() throws Exception + public void testSecurityElementExample132() throws Exception { HttpConstraintElement httpConstraintElement = new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL); ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement); @@ -274,7 +274,7 @@ public class ConstraintTest * @ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY)) */ @Test - public void testSecurityElementExample13_3() throws Exception + public void testSecurityElementExample133() throws Exception { HttpConstraintElement httpConstraintElement = new HttpConstraintElement(EmptyRoleSemantic.DENY); ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement); @@ -292,7 +292,7 @@ public class ConstraintTest * @ServletSecurity(@HttpConstraint(rolesAllowed = "R1")) */ @Test - public void testSecurityElementExample13_4() throws Exception + public void testSecurityElementExample134() throws Exception { HttpConstraintElement httpConstraintElement = new HttpConstraintElement(TransportGuarantee.NONE, "R1"); ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement); @@ -317,7 +317,7 @@ public class ConstraintTest * transportGuarantee = TransportGuarantee.CONFIDENTIAL)}) */ @Test - public void testSecurityElementExample13_5() throws Exception + public void testSecurityElementExample135() throws Exception { List methodElements = new ArrayList(); methodElements.add(new HttpMethodConstraintElement("GET", new HttpConstraintElement(TransportGuarantee.NONE, "R1"))); @@ -343,7 +343,7 @@ public class ConstraintTest * @ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"), httpMethodConstraints = @HttpMethodConstraint("GET")) */ @Test - public void testSecurityElementExample13_6() throws Exception + public void testSecurityElementExample136() throws Exception { List methodElements = new ArrayList(); methodElements.add(new HttpMethodConstraintElement("GET")); @@ -370,7 +370,7 @@ public class ConstraintTest * emptyRoleSemantic = EmptyRoleSemantic.DENY)) */ @Test - public void testSecurityElementExample13_7() throws Exception + public void testSecurityElementExample137() throws Exception { List methodElements = new ArrayList(); methodElements.add(new HttpMethodConstraintElement("TRACE", new HttpConstraintElement(EmptyRoleSemantic.DENY))); @@ -423,7 +423,7 @@ public class ConstraintTest assertEquals(1, uncoveredPaths.size()); assertThat("/user/*", is(in(uncoveredPaths))); - //Test an explicitly named method with a http-method-omission to cover all other methods + //Test an explicitly named method with an http-method-omission to cover all other methods Constraint constraint2a = new Constraint(); constraint2a.setAuthenticate(true); constraint2a.setName("forbid constraint"); @@ -437,7 +437,7 @@ public class ConstraintTest assertNotNull(uncoveredPaths); assertEquals(0, uncoveredPaths.size()); - //Test a http-method-omission only + //Test an http-method-omission only Constraint constraint3 = new Constraint(); constraint3.setAuthenticate(true); constraint3.setName("omit constraint"); @@ -1708,7 +1708,7 @@ public class ConstraintTest { request.login("admin", "fail"); } - catch (ServletException se) + catch (ServletException e) { request.login("admin", "password"); } @@ -1747,9 +1747,6 @@ public class ConstraintTest private class RoleRefHandler extends HandlerWrapper { - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java index b0330ae6980..72d8650c406 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -79,12 +79,12 @@ public class DataConstraintsTest _connectorS = new LocalConnector(_server, https); _server.setConnectors(new Connector[]{_connector, _connectorS}); - ContextHandler _context = new ContextHandler(); + ContextHandler contextHandler = new ContextHandler(); _session = new SessionHandler(); - _context.setContextPath("/ctx"); - _server.setHandler(_context); - _context.setHandler(_session); + contextHandler.setContextPath("/ctx"); + _server.setHandler(contextHandler); + contextHandler.setHandler(_session); _security = new ConstraintSecurityHandler(); _session.setHandler(_security); diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java index 39d9f7953a5..7957c057dc3 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java index 122dd44b009..9feba87321b 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/SessionAuthenticationTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/SessionAuthenticationTest.java new file mode 100644 index 00000000000..ce9eb8767d1 --- /dev/null +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/SessionAuthenticationTest.java @@ -0,0 +1,93 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.security; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.eclipse.jetty.security.authentication.SessionAuthentication; +import org.eclipse.jetty.server.UserIdentity; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.security.Password; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * SessionAuthenticationTest + * + */ +public class SessionAuthenticationTest +{ + /** + * Check that a SessionAuthenticator is serializable, and that + * the deserialized SessionAuthenticator contains the same authentication + * and authorization information. + */ + @Test + public void testSessionAuthenticationSerialization() + throws Exception + { + + ContextHandler contextHandler = new ContextHandler(); + SecurityHandler securityHandler = new ConstraintSecurityHandler(); + contextHandler.setHandler(securityHandler); + TestLoginService loginService = new TestLoginService("SessionAuthTest"); + Password pwd = new Password("foo"); + loginService.putUser("foo", pwd, new String[]{"boss", "worker"}); + securityHandler.setLoginService(loginService); + securityHandler.setAuthMethod("FORM"); + UserIdentity user = loginService.login("foo", pwd, null); + assertNotNull(user); + assertNotNull(user.getUserPrincipal()); + assertEquals("foo", user.getUserPrincipal().getName()); + SessionAuthentication sessionAuth = new SessionAuthentication("FORM", user, pwd); + assertTrue(sessionAuth.isUserInRole(null, "boss")); + contextHandler.handle(new Runnable() + { + public void run() + { + try + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(sessionAuth); + oos.close(); + ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); + SessionAuthentication reactivatedSessionAuth = (SessionAuthentication)ois.readObject(); + assertNotNull(reactivatedSessionAuth); + assertNotNull(reactivatedSessionAuth.getUserIdentity()); + assertNotNull(reactivatedSessionAuth.getUserIdentity().getUserPrincipal()); + assertEquals("foo", reactivatedSessionAuth.getUserIdentity().getUserPrincipal().getName()); + assertNotNull(reactivatedSessionAuth.getUserIdentity().getSubject()); + assertTrue(reactivatedSessionAuth.isUserInRole(null, "boss")); + } + catch (Exception e) + { + fail(e); + } + } + }); + } +} diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/SpecExampleConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/SpecExampleConstraintTest.java index 234646c807f..0a8c0252217 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/SpecExampleConstraintTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/SpecExampleConstraintTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -44,6 +44,7 @@ import org.junit.jupiter.api.Test; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -66,21 +67,21 @@ public class SpecExampleConstraintTest _connector = new LocalConnector(_server); _server.setConnectors(new Connector[]{_connector}); - ContextHandler _context = new ContextHandler(); + ContextHandler context = new ContextHandler(); _session = new SessionHandler(); - TestLoginService _loginService = new TestLoginService(TEST_REALM); + TestLoginService loginService = new TestLoginService(TEST_REALM); - _loginService.putUser("fred", new Password("password"), IdentityService.NO_ROLES); - _loginService.putUser("harry", new Password("password"), new String[]{"HOMEOWNER"}); - _loginService.putUser("chris", new Password("password"), new String[]{"CONTRACTOR"}); - _loginService.putUser("steven", new Password("password"), new String[]{"SALESCLERK"}); + loginService.putUser("fred", new Password("password"), IdentityService.NO_ROLES); + loginService.putUser("harry", new Password("password"), new String[]{"HOMEOWNER"}); + loginService.putUser("chris", new Password("password"), new String[]{"CONTRACTOR"}); + loginService.putUser("steven", new Password("password"), new String[]{"SALESCLERK"}); - _context.setContextPath("/ctx"); - _server.setHandler(_context); - _context.setHandler(_session); + context.setContextPath("/ctx"); + _server.setHandler(context); + context.setHandler(_session); - _server.addBean(_loginService); + _server.addBean(loginService); } @BeforeEach @@ -88,8 +89,8 @@ public class SpecExampleConstraintTest { _security = new ConstraintSecurityHandler(); _session.setHandler(_security); - RequestHandler _handler = new RequestHandler(); - _security.setHandler(_handler); + RequestHandler handler = new RequestHandler(); + _security.setHandler(handler); /* @@ -322,7 +323,8 @@ public class SpecExampleConstraintTest response = _connector.getResponse("POST /ctx/acme/wholesale/index.html HTTP/1.0\r\n" + "Authorization: Basic " + encodedChris + "\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 403 ")); + assertThat(response, startsWith("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!Secure")); //a user in role HOMEOWNER can do a GET response = _connector.getResponse("GET /ctx/acme/retail/index.html HTTP/1.0\r\n" + diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java b/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java index bacddb41f8a..d54b1dd8dc1 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; @@ -43,9 +43,6 @@ public class TestLoginService extends AbstractLoginService userStore.addUser(username, credential, roles); } - /** - * @see org.eclipse.jetty.security.AbstractLoginService#loadRoleInfo(org.eclipse.jetty.security.AbstractLoginService.UserPrincipal) - */ @Override protected String[] loadRoleInfo(UserPrincipal user) { @@ -63,9 +60,6 @@ public class TestLoginService extends AbstractLoginService return list.toArray(new String[roles.size()]); } - /** - * @see org.eclipse.jetty.security.AbstractLoginService#loadUserInfo(java.lang.String) - */ @Override protected UserPrincipal loadUserInfo(String username) { diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java index fe5dfb2c423..fdd14c2d825 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security; diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticatorTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticatorTest.java index 60f7fe510cd..af41cc266c8 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticatorTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticatorTest.java @@ -1,31 +1,34 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.security.authentication; +import java.io.IOException; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpChannelState; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.server.Request; @@ -34,6 +37,8 @@ import org.eclipse.jetty.server.Server; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; public class SpnegoAuthenticatorTest @@ -49,27 +54,34 @@ public class SpnegoAuthenticatorTest @Test public void testChallengeSentWithNoAuthorization() throws Exception { - HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null) + HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null) { @Override public Server getServer() { return null; } - }; - Request req = new Request(channel, null); - HttpOutput out = new HttpOutput(channel) - { + @Override - public void close() + protected HttpOutput newHttpOutput() { + return new HttpOutput(this) + { + @Override + public void close() {} + + @Override + public void flush() throws IOException {} + }; } }; - Response res = new Response(channel, out); + Request req = channel.getRequest(); + Response res = channel.getResponse(); MetaData.Request metadata = new MetaData.Request(new HttpFields()); metadata.setURI(new HttpURI("http://localhost")); req.setMetaData(metadata); + assertThat(channel.getState().handling(), is(HttpChannelState.Action.DISPATCH)); assertEquals(Authentication.SEND_CONTINUE, _authenticator.validateRequest(req, res, true)); assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString())); assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus()); @@ -78,32 +90,65 @@ public class SpnegoAuthenticatorTest @Test public void testChallengeSentWithUnhandledAuthorization() throws Exception { - HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null) + HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null) { @Override public Server getServer() { return null; } - }; - Request req = new Request(channel, null); - HttpOutput out = new HttpOutput(channel) - { + @Override - public void close() + protected HttpOutput newHttpOutput() { + return new HttpOutput(this) + { + @Override + public void close() {} + + @Override + public void flush() throws IOException {} + }; } }; - Response res = new Response(channel, out); - HttpFields http_fields = new HttpFields(); + Request req = channel.getRequest(); + Response res = channel.getResponse(); + HttpFields httpFields = new HttpFields(); // Create a bogus Authorization header. We don't care about the actual credentials. - http_fields.add(HttpHeader.AUTHORIZATION, "Basic asdf"); - MetaData.Request metadata = new MetaData.Request(http_fields); + httpFields.add(HttpHeader.AUTHORIZATION, "Basic asdf"); + MetaData.Request metadata = new MetaData.Request(httpFields); metadata.setURI(new HttpURI("http://localhost")); req.setMetaData(metadata); + assertThat(channel.getState().handling(), is(HttpChannelState.Action.DISPATCH)); assertEquals(Authentication.SEND_CONTINUE, _authenticator.validateRequest(req, res, true)); assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString())); assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus()); } + + class MockConnector extends AbstractConnector + { + public MockConnector() + { + super(new Server(), null, null, null, 0); + } + + @Override + protected void accept(int acceptorID) throws IOException, InterruptedException + { + } + + @Override + public Object getTransport() + { + return null; + } + + @Override + public String dumpSelf() + { + return null; + } + } } + diff --git a/jetty-security/src/test/resources/jetty-logging.properties b/jetty-security/src/test/resources/jetty-logging.properties index 24d5e3aadc7..bd86a8c5369 100755 --- a/jetty-security/src/test/resources/jetty-logging.properties +++ b/jetty-security/src/test/resources/jetty-logging.properties @@ -1,7 +1,5 @@ # Setup default logging implementation for during testing -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog - +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG - #org.eclipse.jetty.util.PathWatcher.LEVEL=DEBUG #org.eclipse.jetty.util.PathWatcher.Noisy.LEVEL=OFF diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 16cfef78863..f37980beea8 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -61,6 +61,10 @@ ${project.version} true
      + + org.slf4j + slf4j-api + org.eclipse.jetty @@ -79,6 +83,17 @@ ${project.version} test + + org.eclipse.jetty + jetty-util-ajax + ${project.version} + test + + + org.eclipse.jetty + jetty-slf4j-impl + test +
      diff --git a/jetty-server/src/main/config/etc/jetty-http.xml b/jetty-server/src/main/config/etc/jetty-http.xml index ccf02559439..17aa2453587 100644 --- a/jetty-server/src/main/config/etc/jetty-http.xml +++ b/jetty-server/src/main/config/etc/jetty-http.xml @@ -3,13 +3,13 @@ - + - + diff --git a/jetty-server/src/main/config/etc/jetty-https.xml b/jetty-server/src/main/config/etc/jetty-https.xml index bbeaa5a6cc7..a71de579531 100644 --- a/jetty-server/src/main/config/etc/jetty-https.xml +++ b/jetty-server/src/main/config/etc/jetty-https.xml @@ -2,7 +2,7 @@ - + diff --git a/jetty-server/src/main/config/etc/jetty-ssl-context.xml b/jetty-server/src/main/config/etc/jetty-ssl-context.xml index cf4aa60ffd4..44da09f579f 100644 --- a/jetty-server/src/main/config/etc/jetty-ssl-context.xml +++ b/jetty-server/src/main/config/etc/jetty-ssl-context.xml @@ -12,12 +12,12 @@ - / - + / + - - / + + / @@ -29,6 +29,7 @@ + - + @@ -49,6 +49,7 @@ + diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml index f63bf25c846..0c6f3b4d948 100644 --- a/jetty-server/src/main/config/etc/jetty.xml +++ b/jetty-server/src/main/config/etc/jetty.xml @@ -3,7 +3,7 @@ - + @@ -35,7 +35,11 @@ - + + + + + @@ -55,8 +59,8 @@ - - + + diff --git a/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml b/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml index c40486e363e..35d7bfb28f0 100644 --- a/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml +++ b/jetty-server/src/main/config/etc/sessions/session-cache-hash.xml @@ -5,15 +5,16 @@ - + - - - - + + + + + diff --git a/jetty-server/src/main/config/etc/sessions/session-cache-null.xml b/jetty-server/src/main/config/etc/sessions/session-cache-null.xml index 84d26c24ef7..7de90393a52 100644 --- a/jetty-server/src/main/config/etc/sessions/session-cache-null.xml +++ b/jetty-server/src/main/config/etc/sessions/session-cache-null.xml @@ -10,8 +10,9 @@ - - + + + diff --git a/jetty-server/src/main/config/modules/bytebufferpool.mod b/jetty-server/src/main/config/modules/bytebufferpool.mod index 7a813148b6e..d4b28f9244d 100644 --- a/jetty-server/src/main/config/modules/bytebufferpool.mod +++ b/jetty-server/src/main/config/modules/bytebufferpool.mod @@ -3,6 +3,9 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-m [description] Configures the ByteBufferPool used by ServerConnectors. +[depends] +logging + [xml] etc/jetty-bytebufferpool.xml diff --git a/jetty-server/src/main/config/modules/gzip.mod b/jetty-server/src/main/config/modules/gzip.mod index 24c045a37c4..96be4bb9c01 100644 --- a/jetty-server/src/main/config/modules/gzip.mod +++ b/jetty-server/src/main/config/modules/gzip.mod @@ -15,7 +15,7 @@ etc/jetty-gzip.xml [ini-template] ## Minimum content length after which gzip is enabled -# jetty.gzip.minGzipSize=2048 +# jetty.gzip.minGzipSize=32 ## Check whether a file with *.gz extension exists # jetty.gzip.checkGzExists=false diff --git a/jetty-server/src/main/config/modules/http.mod b/jetty-server/src/main/config/modules/http.mod index e1f89b00dbe..a0b26e12663 100644 --- a/jetty-server/src/main/config/modules/http.mod +++ b/jetty-server/src/main/config/modules/http.mod @@ -1,7 +1,7 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Enables a HTTP connector on the server. +Enables an HTTP connector on the server. By default HTTP/1 is support, but HTTP2C can be added to the connector with the http2c module. diff --git a/jetty-server/src/main/config/modules/jdbc.mod b/jetty-server/src/main/config/modules/jdbc.mod new file mode 100644 index 00000000000..a78fcc256aa --- /dev/null +++ b/jetty-server/src/main/config/modules/jdbc.mod @@ -0,0 +1,4 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[jpms] +add-modules: java.sql diff --git a/jetty-server/src/main/config/modules/server.mod b/jetty-server/src/main/config/modules/server.mod index be9bff04e0d..8e76acec0d0 100644 --- a/jetty-server/src/main/config/modules/server.mod +++ b/jetty-server/src/main/config/modules/server.mod @@ -1,4 +1,4 @@ -DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] Enables the core Jetty server on the classpath. @@ -7,11 +7,11 @@ Enables the core Jetty server on the classpath. jvm ext resources -logging [depend] threadpool bytebufferpool +logging [lib] lib/jetty-servlet-api-4.0.*.jar @@ -51,7 +51,7 @@ etc/jetty.xml # jetty.httpConfig.sendDateHeader=false ## Max per-connection header cache size (in nodes) -# jetty.httpConfig.headerCacheSize=4096 +# jetty.httpConfig.headerCacheSize=1024 ## Whether, for requests with content, delay dispatch until some content has arrived # jetty.httpConfig.delayDispatchUntilContent=true @@ -80,3 +80,8 @@ etc/jetty.xml ## Dump the state of the Jetty server, components, and webapps before shutdown # jetty.server.dumpBeforeStop=false + +## Scheduler Configuration +# jetty.scheduler.name= +# jetty.scheduler.deamon=false +# jetty.scheduler.threads=-1 diff --git a/jetty-server/src/main/config/modules/session-cache-hash.mod b/jetty-server/src/main/config/modules/session-cache-hash.mod index 32ab705c7a2..2d336bc1d99 100644 --- a/jetty-server/src/main/config/modules/session-cache-hash.mod +++ b/jetty-server/src/main/config/modules/session-cache-hash.mod @@ -1,10 +1,9 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Enable first level session cache in ConcurrentHashMap. -If not enabled, sessions will use a HashSessionCache by default, so enabling -via this module is only needed if the configuration properties need to be -changed. +Enable first level session cache. If this module is not enabled, sessions will +use the DefaultSessionCache by default, so enabling via this module is only needed +if the configuration properties need to be changed from their defaults. [tags] session @@ -23,3 +22,4 @@ etc/sessions/session-cache-hash.xml #jetty.session.saveOnInactiveEvict=false #jetty.session.saveOnCreate=false #jetty.session.removeUnloadableSessions=false +#jetty.session.flushOnResponseCommit=false diff --git a/jetty-server/src/main/config/modules/session-cache-null.mod b/jetty-server/src/main/config/modules/session-cache-null.mod index abdf2d7e076..2a94f59cb82 100644 --- a/jetty-server/src/main/config/modules/session-cache-null.mod +++ b/jetty-server/src/main/config/modules/session-cache-null.mod @@ -18,3 +18,4 @@ etc/sessions/session-cache-null.xml [ini-template] #jetty.session.saveOnCreate=false #jetty.session.removeUnloadableSessions=false +#jetty.session.flushOnResponseCommit=false diff --git a/jetty-server/src/main/config/modules/session-store-jdbc.mod b/jetty-server/src/main/config/modules/session-store-jdbc.mod index 297cf2c69a4..e97457d0781 100644 --- a/jetty-server/src/main/config/modules/session-store-jdbc.mod +++ b/jetty-server/src/main/config/modules/session-store-jdbc.mod @@ -10,6 +10,7 @@ session session-store [depend] +jdbc sessions sessions/jdbc/${db-connection-type} @@ -54,7 +55,3 @@ db-connection-type=datasource #jetty.session.jdbc.schema.maxIntervalColumn=maxInterval #jetty.session.jdbc.schema.mapColumn=map #jetty.session.jdbc.schema.table=JettySessions - - - - diff --git a/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod b/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod index be665ff9f3b..d30b911a3b9 100644 --- a/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod +++ b/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod @@ -3,5 +3,8 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-m [description] JDBC Datasource connections for session storage +[depends] +jdbc + [xml] etc/sessions/jdbc/datasource.xml diff --git a/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod b/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod index eb7391a807d..ad387114cd6 100644 --- a/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod +++ b/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod @@ -3,5 +3,8 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-m [description] JDBC Driver connections for session storage +[depend] +jdbc + [xml] etc/sessions/jdbc/driver.xml diff --git a/jetty-server/src/main/config/modules/ssl.mod b/jetty-server/src/main/config/modules/ssl.mod index be27d35546f..bd64f9d7a7a 100644 --- a/jetty-server/src/main/config/modules/ssl.mod +++ b/jetty-server/src/main/config/modules/ssl.mod @@ -43,6 +43,12 @@ etc/jetty-ssl-context.xml ## Connect Timeout in milliseconds # jetty.ssl.connectTimeout=15000 +## Whether SNI is required for all secure connections. Rejections are in TLS handshakes. +# jetty.sslContext.sniRequired=false + +## Whether SNI is required for all secure connections. Rejections are in HTTP 400 response. +# jetty.ssl.sniRequired=false + ## Whether request host names are checked to match any SNI names # jetty.ssl.sniHostCheck=true @@ -73,7 +79,7 @@ etc/jetty-ssl-context.xml # jetty.sslContext.keyStorePassword= ## Keystore type and provider -# jetty.sslContext.keyStoreType=JKS +# jetty.sslContext.keyStoreType=PKCS12 # jetty.sslContext.keyStoreProvider= ## KeyManager password @@ -83,7 +89,7 @@ etc/jetty-ssl-context.xml # jetty.sslContext.trustStorePassword= ## Truststore type and provider -# jetty.sslContext.trustStoreType=JKS +# jetty.sslContext.trustStoreType=PKCS12 # jetty.sslContext.trustStoreProvider= ## whether client certificate authentication is required diff --git a/jetty-server/src/main/config/modules/test-keystore.mod b/jetty-server/src/main/config/modules/test-keystore.mod index f375e9ca540..42dd6a0a90c 100644 --- a/jetty-server/src/main/config/modules/test-keystore.mod +++ b/jetty-server/src/main/config/modules/test-keystore.mod @@ -9,13 +9,10 @@ ssl ssl [files] -basehome:modules/test-keystore/keystore|etc/test-keystore +basehome:modules/test-keystore/test-keystore.p12|etc/test-keystore.p12 [ini] -jetty.sslContext.keyStorePath?=etc/test-keystore -jetty.sslContext.trustStorePath?=etc/test-keystore +jetty.sslContext.keyStorePath?=etc/test-keystore.p12 +jetty.sslContext.trustStorePath?=etc/test-keystore.p12 +jetty.sslContext.keyStoreType?=PKCS12 jetty.sslContext.keyStorePassword?=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4 -jetty.sslContext.keyStoreType?=JKS -jetty.sslContext.keyManagerPassword?=OBF:1u2u1wml1z7s1z7a1wnl1u2g -jetty.sslContext.trustStorePassword?=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4 -jetty.sslContext.trustStoreType?=JKS diff --git a/jetty-server/src/main/config/modules/test-keystore/keystore b/jetty-server/src/main/config/modules/test-keystore/keystore deleted file mode 100644 index d6592f95ee9..00000000000 Binary files a/jetty-server/src/main/config/modules/test-keystore/keystore and /dev/null differ diff --git a/jetty-server/src/main/config/modules/test-keystore/test-keystore.p12 b/jetty-server/src/main/config/modules/test-keystore/test-keystore.p12 new file mode 100644 index 00000000000..ee7a51f5344 Binary files /dev/null and b/jetty-server/src/main/config/modules/test-keystore/test-keystore.p12 differ diff --git a/jetty-server/src/main/config/modules/threadpool.mod b/jetty-server/src/main/config/modules/threadpool.mod index c0201b3c7e0..36541ef9664 100644 --- a/jetty-server/src/main/config/modules/threadpool.mod +++ b/jetty-server/src/main/config/modules/threadpool.mod @@ -3,6 +3,9 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-m [description] Enables the Server thread pool. +[depends] +logging + [xml] etc/jetty-threadpool.xml diff --git a/jetty-server/src/main/java/module-info.java b/jetty-server/src/main/java/module-info.java index f2839eae376..f7153549730 100644 --- a/jetty-server/src/main/java/module-info.java +++ b/jetty-server/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.server @@ -25,10 +25,9 @@ module org.eclipse.jetty.server exports org.eclipse.jetty.server.jmx to org.eclipse.jetty.jmx; exports org.eclipse.jetty.server.session; - requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; + requires transitive jetty.servlet.api; + requires transitive org.eclipse.jetty.http; + requires transitive org.slf4j; // Only required if using DatabaseAdaptor/JDBCSessionDataStore. requires static java.sql; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java index af5bf1f0ec9..021eef155ee 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java @@ -1,29 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; @@ -32,17 +32,7 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.ssl.SslContextFactory; /** - *

      Provides the common handling for {@link ConnectionFactory} implementations including:

      - *
        - *
      • Protocol identification
      • - *
      • Configuration of new Connections: - *
          - *
        • Setting inputbuffer size
        • - *
        • Calling {@link Connection#addListener(Connection.Listener)} for all - * Connection.Listener instances found as beans on the {@link Connector} - * and this {@link ConnectionFactory}
        • - *
        - *
      + *

      Provides the common handling for {@link ConnectionFactory} implementations.

      */ @ManagedObject public abstract class AbstractConnectionFactory extends ContainerLifeCycle implements ConnectionFactory @@ -87,24 +77,35 @@ public abstract class AbstractConnectionFactory extends ContainerLifeCycle imple _inputbufferSize = size; } + protected String findNextProtocol(Connector connector) + { + return findNextProtocol(connector, getProtocol()); + } + + protected static String findNextProtocol(Connector connector, String currentProtocol) + { + String nextProtocol = null; + for (Iterator it = connector.getProtocols().iterator(); it.hasNext(); ) + { + String protocol = it.next(); + if (currentProtocol.equalsIgnoreCase(protocol)) + { + nextProtocol = it.hasNext() ? it.next() : null; + break; + } + } + return nextProtocol; + } + protected AbstractConnection configure(AbstractConnection connection, Connector connector, EndPoint endPoint) { connection.setInputBufferSize(getInputBufferSize()); // Add Connection.Listeners from Connector - if (connector instanceof ContainerLifeCycle) - { - ContainerLifeCycle aggregate = (ContainerLifeCycle)connector; - for (Connection.Listener listener : aggregate.getBeans(Connection.Listener.class)) - { - connection.addListener(listener); - } - } + connector.getEventListeners().forEach(connection::addEventListener); + // Add Connection.Listeners from this factory - for (Connection.Listener listener : getBeans(Connection.Listener.class)) - { - connection.addListener(listener); - } + getEventListeners().forEach(connection::addEventListener); return connection; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index 46c18701b7e..357286a7c82 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -30,12 +30,11 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; +import java.util.stream.Collectors; import org.eclipse.jetty.io.ArrayByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool; @@ -45,16 +44,17 @@ import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.component.Container; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.Graceful; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.util.thread.Locker; +import org.eclipse.jetty.util.thread.AutoLock; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.ThreadPoolBudget; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      An abstract implementation of {@link Connector} that provides a {@link ConnectionFactory} mechanism @@ -115,7 +115,7 @@ import org.eclipse.jetty.util.thread.ThreadPoolBudget; * {@link ConnectionFactory}s may also create temporary {@link org.eclipse.jetty.io.Connection} instances that will exchange bytes * over the connection to determine what is the next protocol to use. For example the ALPN protocol is an extension * of SSL to allow a protocol to be specified during the SSL handshake. ALPN is used by the HTTP/2 protocol to - * negotiate the protocol that the client and server will speak. Thus to accept a HTTP/2 connection, the + * negotiate the protocol that the client and server will speak. Thus to accept an HTTP/2 connection, the * connector will be configured with {@link ConnectionFactory}s for "SSL-ALPN", "h2", "http/1.1" * with the default protocol being "SSL-ALPN". Thus a newly accepted connection uses "SSL-ALPN", which specifies a * SSLConnectionFactory with "ALPN" as the next protocol. Thus an SSL connection instance is created chained to an ALPN @@ -141,10 +141,10 @@ import org.eclipse.jetty.util.thread.ThreadPoolBudget; @ManagedObject("Abstract implementation of the Connector Interface") public abstract class AbstractConnector extends ContainerLifeCycle implements Connector, Dumpable { - protected static final Logger LOG = Log.getLogger(AbstractConnector.class); + protected static final Logger LOG = LoggerFactory.getLogger(AbstractConnector.class); - private final Locker _locker = new Locker(); - private final Condition _setAccepting = _locker.newCondition(); + private final AutoLock _lock = new AutoLock(); + private final Condition _setAccepting = _lock.newCondition(); private final Map _factories = new LinkedHashMap<>(); // Order is important on server side, so we use a LinkedHashMap private final Server _server; private final Executor _executor; @@ -153,9 +153,10 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co private final Thread[] _acceptors; private final Set _endpoints = Collections.newSetFromMap(new ConcurrentHashMap<>()); private final Set _immutableEndPoints = Collections.unmodifiableSet(_endpoints); - private final Graceful.Shutdown _shutdown = new Graceful.Shutdown(); - private CountDownLatch _stopping; + private Shutdown _shutdown; + private HttpChannel.Listener _httpChannelListeners = HttpChannel.NOOP_LISTENER; private long _idleTimeout = 30000; + private long _shutdownIdleTimeout = 1000L; private String _defaultProtocol; private ConnectionFactory _defaultConnectionFactory; private String _name; @@ -181,20 +182,35 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co { _server = server; _executor = executor != null ? executor : _server.getThreadPool(); - if (scheduler == null) - scheduler = _server.getBean(Scheduler.class); - _scheduler = scheduler != null ? scheduler : new ScheduledExecutorScheduler(String.format("Connector-Scheduler-%x", hashCode()), false); - if (pool == null) - pool = _server.getBean(ByteBufferPool.class); - _byteBufferPool = pool != null ? pool : new ArrayByteBufferPool(); - - addBean(_server, false); addBean(_executor); if (executor == null) unmanage(_executor); // inherited from server + if (scheduler == null) + scheduler = _server.getBean(Scheduler.class); + _scheduler = scheduler != null ? scheduler : new ScheduledExecutorScheduler(String.format("Connector-Scheduler-%x", hashCode()), false); addBean(_scheduler); + if (pool == null) + pool = _server.getBean(ByteBufferPool.class); + _byteBufferPool = pool != null ? pool : new ArrayByteBufferPool(); addBean(_byteBufferPool); + addEventListener(new Container.Listener() + { + @Override + public void beanAdded(Container parent, Object bean) + { + if (bean instanceof HttpChannel.Listener) + _httpChannelListeners = new HttpChannelListeners(getBeans(HttpChannel.Listener.class)); + } + + @Override + public void beanRemoved(Container parent, Object bean) + { + if (bean instanceof HttpChannel.Listener) + _httpChannelListeners = new HttpChannelListeners(getBeans(HttpChannel.Listener.class)); + } + }); + for (ConnectionFactory factory : factories) { addConnectionFactory(factory); @@ -208,6 +224,24 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co _acceptors = new Thread[acceptors]; } + /** + * Get the {@link HttpChannel.Listener}s added to the connector + * as a single combined Listener. + * This is equivalent to a listener that iterates over the individual + * listeners returned from {@code getBeans(HttpChannel.Listener.class);}, + * except that:

        + *
      • The result is precomputed, so it is more efficient
      • + *
      • The result is ordered by the order added.
      • + *
      • The result is immutable.
      • + *
      + * @see #getBeans(Class) + * @return An unmodifiable list of EventListener beans + */ + public HttpChannel.Listener getHttpChannelListeners() + { + return _httpChannelListeners; + } + @Override public Server getServer() { @@ -249,6 +283,20 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co public void setIdleTimeout(long idleTimeout) { _idleTimeout = idleTimeout; + if (_idleTimeout == 0) + _shutdownIdleTimeout = 0; + else if (_idleTimeout < _shutdownIdleTimeout) + _shutdownIdleTimeout = Math.min(1000L, _idleTimeout); + } + + public void setShutdownIdleTimeout(long idle) + { + _shutdownIdleTimeout = idle; + } + + public long getShutdownIdleTimeout() + { + return _shutdownIdleTimeout; } /** @@ -263,7 +311,21 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co @Override protected void doStart() throws Exception { - _shutdown.cancel(); + _shutdown = new Graceful.Shutdown(this) + { + @Override + public boolean isShutdownDone() + { + if (!_endpoints.isEmpty()) + return false; + + for (Thread a : _acceptors) + if (a != null) + return false; + + return true; + } + }; if (_defaultProtocol == null) throw new IllegalStateException("No default protocol for " + this); @@ -282,7 +344,6 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co _lease = ThreadPoolBudget.leaseFrom(getExecutor(), this, _acceptors.length); super.doStart(); - _stopping = new CountDownLatch(_acceptors.length); for (int i = 0; i < _acceptors.length; i++) { Acceptor a = new Acceptor(i); @@ -295,7 +356,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co protected void interruptAcceptors() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { for (Thread thread : _acceptors) { @@ -306,15 +367,29 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co } @Override - public Future shutdown() + public CompletableFuture shutdown() { - return _shutdown.shutdown(); + Shutdown shutdown = _shutdown; + if (shutdown == null) + return CompletableFuture.completedFuture(null); + + // Signal for the acceptors to stop + CompletableFuture done = shutdown.shutdown(); + interruptAcceptors(); + + // Reduce the idle timeout of existing connections + for (EndPoint ep : _endpoints) + ep.setIdleTimeout(getShutdownIdleTimeout()); + + // Return Future that waits for no acceptors and no connections. + return done; } @Override public boolean isShutdown() { - return _shutdown.isShutdown(); + Shutdown shutdown = _shutdown; + return shutdown == null || shutdown.isShutdown(); } @Override @@ -325,20 +400,11 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co // Tell the acceptors we are stopping interruptAcceptors(); - - // If we have a stop timeout - long stopTimeout = getStopTimeout(); - CountDownLatch stopping = _stopping; - if (stopTimeout > 0 && stopping != null && getAcceptors() > 0) - stopping.await(stopTimeout, TimeUnit.MILLISECONDS); - _stopping = null; - super.doStop(); - for (Acceptor a : getBeans(Acceptor.class)) - { removeBean(a); - } + + _shutdown = null; LOG.info("Stopped {}", this); } @@ -350,7 +416,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co public void join(long timeout) throws InterruptedException { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { for (Thread thread : _acceptors) { @@ -367,7 +433,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co */ public boolean isAccepting() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { return _accepting; } @@ -375,7 +441,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co public void setAccepting(boolean accepting) { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { _accepting = accepting; _setAccepting.signalAll(); @@ -385,7 +451,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co @Override public ConnectionFactory getConnectionFactory(String protocol) { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { return _factories.get(StringUtil.asciiToLowerCase(protocol)); } @@ -394,7 +460,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co @Override public T getConnectionFactory(Class factoryType) { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { for (ConnectionFactory f : _factories.values()) { @@ -452,35 +518,23 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co throw new IllegalStateException(getState()); List existings = new ArrayList<>(_factories.values()); - _factories.clear(); + clearConnectionFactories(); addConnectionFactory(factory); for (ConnectionFactory existing : existings) { addConnectionFactory(existing); } - _defaultProtocol = factory.getProtocol(); } + // Used from XML, do not remove. public void addIfAbsentConnectionFactory(ConnectionFactory factory) { if (isRunning()) throw new IllegalStateException(getState()); String key = StringUtil.asciiToLowerCase(factory.getProtocol()); - if (_factories.containsKey(key)) - { - if (LOG.isDebugEnabled()) - LOG.debug("{} addIfAbsent ignored {}", this, factory); - } - else - { - _factories.put(key, factory); - addBean(factory); - if (_defaultProtocol == null) - _defaultProtocol = factory.getProtocol(); - if (LOG.isDebugEnabled()) - LOG.debug("{} addIfAbsent added {}", this, factory); - } + if (!_factories.containsKey(key)) + addConnectionFactory(factory); } public ConnectionFactory removeConnectionFactory(String protocol) @@ -489,6 +543,8 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co throw new IllegalStateException(getState()); ConnectionFactory factory = _factories.remove(StringUtil.asciiToLowerCase(protocol)); + if (_factories.isEmpty()) + _defaultProtocol = null; removeBean(factory); return factory; } @@ -516,6 +572,15 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co } } + public void clearConnectionFactories() + { + if (isRunning()) + throw new IllegalStateException(getState()); + + _factories.clear(); + _defaultProtocol = null; + } + @ManagedAttribute("The priority delta to apply to acceptor threads") public int getAcceptorPriorityDelta() { @@ -551,14 +616,6 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co return new ArrayList<>(_factories.keySet()); } - public void clearConnectionFactories() - { - if (isRunning()) - throw new IllegalStateException(getState()); - - _factories.clear(); - } - @ManagedAttribute("This connector's default protocol") public String getDefaultProtocol() { @@ -586,17 +643,17 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co { if (ex instanceof InterruptedException) { - LOG.debug(ex); + LOG.debug("Accept Interrupted", ex); return true; } if (ex instanceof ClosedByInterruptException) { - LOG.debug(ex); + LOG.debug("Accept Closed by Interrupt", ex); return false; } - LOG.warn(ex); + LOG.warn("Accept Failure", ex); try { // Arbitrary sleep to avoid spin looping. @@ -607,13 +664,13 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co } catch (Throwable x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } return false; } else { - LOG.ignore(ex); + LOG.trace("IGNORED", ex); return false; } } @@ -644,9 +701,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co try { - while (isRunning()) + while (isRunning() && !_shutdown.isShutdown()) { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { if (!_accepting && isRunning()) { @@ -680,9 +737,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co { _acceptors[_id] = null; } - CountDownLatch stopping = _stopping; - if (stopping != null) - stopping.countDown(); + Shutdown shutdown = _shutdown; + if (shutdown != null) + shutdown.check(); } } @@ -710,6 +767,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co protected void onEndPointClosed(EndPoint endp) { _endpoints.remove(endp); + Shutdown shutdown = _shutdown; + if (shutdown != null) + shutdown.check(); } @Override @@ -739,9 +799,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co @Override public String toString() { - return String.format("%s@%x{%s,%s}", + return String.format("%s@%x{%s, %s}", _name == null ? getClass().getSimpleName() : _name, hashCode(), - getDefaultProtocol(), getProtocols()); + getDefaultProtocol(), getProtocols().stream().collect(Collectors.joining(", ", "(", ")"))); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java index 4da690fa655..69ff10b546a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java @@ -1,26 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; import java.io.IOException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.concurrent.Future; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.annotation.ManagedAttribute; @@ -99,7 +99,7 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme } @Override - public Future shutdown() + public CompletableFuture shutdown() { close(); return super.shutdown(); @@ -110,7 +110,7 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme { if (isOpen()) return super.handleAcceptFailure(ex); - LOG.ignore(ex); + LOG.trace("IGNORED", ex); return false; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AcceptRateLimit.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AcceptRateLimit.java index 16f72754bcf..28d9ca77db4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AcceptRateLimit.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AcceptRateLimit.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -30,10 +30,10 @@ import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.Container; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.RateStatistic; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A Listener that limits the rate at which new connections are accepted

      @@ -62,7 +62,7 @@ import org.eclipse.jetty.util.thread.Scheduler; @ManagedObject public class AcceptRateLimit extends AbstractLifeCycle implements SelectorManager.AcceptListener, Runnable { - private static final Logger LOG = Log.getLogger(AcceptRateLimit.class); + private static final Logger LOG = LoggerFactory.getLogger(AcceptRateLimit.class); private final Server _server; private final List _connectors = new ArrayList<>(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextEvent.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextEvent.java index 0cd93ff67be..4da7cc87e67 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextEvent.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextEvent.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -60,6 +60,7 @@ public class AsyncContextEvent extends AsyncEvent implements Runnable baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, baseRequest.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH)); baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO, baseRequest.getAttribute(RequestDispatcher.FORWARD_PATH_INFO)); baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING, baseRequest.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING)); + baseRequest.setAttribute(AsyncContext.ASYNC_MAPPING, baseRequest.getAttribute(RequestDispatcher.FORWARD_MAPPING)); } else { @@ -68,6 +69,7 @@ public class AsyncContextEvent extends AsyncEvent implements Runnable baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, baseRequest.getServletPath()); baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO, baseRequest.getPathInfo()); baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING, baseRequest.getQueryString()); + baseRequest.setAttribute(AsyncContext.ASYNC_MAPPING, baseRequest.getHttpServletMapping()); } } } @@ -160,7 +162,7 @@ public class AsyncContextEvent extends AsyncEvent implements Runnable Scheduler.Task task = _timeoutTask; _timeoutTask = null; if (task != null) - _state.getHttpChannel().execute(() -> _state.onTimeout()); + _state.timeout(); } public void addThrowable(Throwable e) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextState.java index d02f9768e1f..a68785ef616 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContextState.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -77,7 +77,7 @@ public class AsyncContextState implements AsyncContext { ContextHandler contextHandler = state().getContextHandler(); if (contextHandler != null) - return contextHandler.getServletContext().createListener(clazz); + return contextHandler.getServletContext().createInstance(clazz); try { return clazz.getDeclaredConstructor().newInstance(); @@ -146,7 +146,11 @@ public class AsyncContextState implements AsyncContext @Override public void run() { - state().getAsyncContextEvent().getContext().getContextHandler().handle(channel.getRequest(), task); + ContextHandler.Context context = state().getAsyncContextEvent().getContext(); + if (context == null) + task.run(); + else + context.getContextHandler().handle(channel.getRequest(), task); } }); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequestLogWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequestLogWriter.java index 6fab81b1312..f1a9ba6cb88 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequestLogWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequestLogWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -23,15 +23,15 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BlockingArrayQueue; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An asynchronously writing RequestLogWriter */ public class AsyncRequestLogWriter extends RequestLogWriter { - private static final Logger LOG = Log.getLogger(AsyncRequestLogWriter.class); + private static final Logger LOG = LoggerFactory.getLogger(AsyncRequestLogWriter.class); private final BlockingQueue _queue; private transient AsyncRequestLogWriter.WriterThread _thread; private boolean _warnedFull; @@ -81,11 +81,11 @@ public class AsyncRequestLogWriter extends RequestLogWriter } catch (InterruptedException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } catch (Throwable t) { - LOG.warn(t); + LOG.warn("Failed to write log", t); } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java index 71c4e786b91..c7c71dd36cf 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CachedContentFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CachedContentFactory.java index aa6b597f819..3d4cc0f52de 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/CachedContentFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CachedContentFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -44,14 +44,14 @@ import org.eclipse.jetty.http.PreEncodedHttpField; import org.eclipse.jetty.http.PrecompressedHttpContent; import org.eclipse.jetty.http.ResourceHttpContent; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class CachedContentFactory implements HttpContent.ContentFactory { - private static final Logger LOG = Log.getLogger(CachedContentFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(CachedContentFactory.class); private static final Map NO_PRECOMPRESSED = Collections.unmodifiableMap(Collections.emptyMap()); private final ConcurrentMap _cache; @@ -334,7 +334,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory catch (IOException | IllegalArgumentException e) { if (LOG.isDebugEnabled()) - LOG.debug(e); + LOG.debug("Unable to get Indirect Buffer for {}", resource, e); } return null; } @@ -351,7 +351,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory catch (IOException | IllegalArgumentException e) { if (LOG.isDebugEnabled()) - LOG.debug(e); + LOG.debug("Unable to get Mapped Buffer for {}", resource, e); } return null; } @@ -365,7 +365,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory catch (IOException | IllegalArgumentException e) { if (LOG.isDebugEnabled()) - LOG.debug(e); + LOG.debug("Unable to get Direct Buffer for {}", resource, e); } return null; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java index e9e358814c2..63bd2f755b8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java index ffc6153bc12..ebba5f00a6c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; +import java.nio.ByteBuffer; import java.util.List; import org.eclipse.jetty.http.BadMessageException; @@ -35,11 +36,11 @@ import org.eclipse.jetty.io.EndPoint; * A ConnectionFactory has a protocol name that represents the protocol of the Connections * created. Example of protocol names include: *
      - *
      http
      Creates a HTTP connection that can handle multiple versions of HTTP from 0.9 to 1.1
      - *
      h2
      Creates a HTTP/2 connection that handles the HTTP/2 protocol
      + *
      http
      Creates an HTTP connection that can handle multiple versions of HTTP from 0.9 to 1.1
      + *
      h2
      Creates an HTTP/2 connection that handles the HTTP/2 protocol
      *
      SSL-XYZ
      Create an SSL connection chained to a connection obtained from a connection factory * with a protocol "XYZ".
      - *
      SSL-http
      Create an SSL connection chained to a HTTP connection (aka https)
      + *
      SSL-http
      Create an SSL connection chained to an HTTP connection (aka https)
      *
      SSL-ALPN
      Create an SSL connection chained to a ALPN connection, that uses a negotiation with * the client to determine the next protocol.
      *
      @@ -85,4 +86,43 @@ public interface ConnectionFactory */ public Connection upgradeConnection(Connector connector, EndPoint endPoint, MetaData.Request upgradeRequest, HttpFields responseFields) throws BadMessageException; } + + /** + *

      Connections created by this factory MUST implement {@link Connection.UpgradeTo}.

      + */ + interface Detecting extends ConnectionFactory + { + /** + * The possible outcomes of the {@link #detect(ByteBuffer)} method. + */ + enum Detection + { + /** + * A {@link Detecting} can work with the given bytes. + */ + RECOGNIZED, + /** + * A {@link Detecting} cannot work with the given bytes. + */ + NOT_RECOGNIZED, + /** + * A {@link Detecting} requires more bytes to make a decision. + */ + NEED_MORE_BYTES + } + + /** + *

      Check the bytes in the given {@code buffer} to figure out if this {@link Detecting} instance + * can work with them or not.

      + *

      The {@code buffer} MUST be left untouched by this method: bytes MUST NOT be consumed and MUST NOT be modified.

      + * @param buffer the buffer. + * @return One of: + *
        + *
      • {@link Detection#RECOGNIZED} if this {@link Detecting} instance can work with the bytes in the buffer
      • + *
      • {@link Detection#NOT_RECOGNIZED} if this {@link Detecting} instance cannot work with the bytes in the buffer
      • + *
      • {@link Detection#NEED_MORE_BYTES} if this {@link Detecting} instance requires more bytes to make a decision
      • + *
      + */ + Detection detect(ByteBuffer buffer); + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java index cc57b2d654f..054923a2862 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -33,8 +33,8 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.Container; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A Listener that limits the number of Connections.

      @@ -60,7 +60,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public class ConnectionLimit extends AbstractLifeCycle implements Listener, SelectorManager.AcceptListener { - private static final Logger LOG = Log.getLogger(ConnectionLimit.class); + private static final Logger LOG = LoggerFactory.getLogger(ConnectionLimit.class); private final Server _server; private final List _connectors = new ArrayList<>(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java index b7dd22f73fb..b46a6cc77ea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Cookies.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Cookies.java index 29004592c13..f4bea7da7d5 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Cookies.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Cookies.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -25,8 +25,8 @@ import javax.servlet.http.Cookie; import org.eclipse.jetty.http.ComplianceViolation; import org.eclipse.jetty.http.CookieCompliance; import org.eclipse.jetty.http.CookieCutter; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Cookie parser @@ -38,7 +38,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class Cookies extends CookieCutter { - protected static final Logger LOG = Log.getLogger(Cookies.class); + protected static final Logger LOG = LoggerFactory.getLogger(Cookies.class); protected final List _rawFields = new ArrayList<>(); protected final List _cookieList = new ArrayList<>(); private int _addedFields; @@ -137,7 +137,8 @@ public class Cookies extends CookieCutter } catch (Exception e) { - LOG.debug(e); + LOG.debug("Unable to add Cookie name={}, value={}, domain={}, path={}, version={}, comment={}", + name, value, domain, path, version, comment, e); } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java index b1280114776..e67ad99993d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -31,17 +31,19 @@ import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.QuotedCSV; import org.eclipse.jetty.http.pathmap.PathMappings; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.DateCache; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.lang.invoke.MethodHandles.dropArguments; import static java.lang.invoke.MethodHandles.foldArguments; @@ -233,8 +235,9 @@ import static java.lang.invoke.MethodType.methodType; * * %{d}u * - * Remote user if the request was authenticated. May be bogus if return status (%s) is 401 (unauthorized). - * Optional parameter d, with this parameter deferred authentication will also be checked. + * Remote user if the request was authenticated with servlet authentication. May be bogus if return status (%s) is 401 (unauthorized). + * Optional parameter d, with this parameter deferred authentication will also be checked, + * this is equivalent to {@link HttpServletRequest#getRemoteUser()}. * * * @@ -268,12 +271,12 @@ import static java.lang.invoke.MethodType.methodType; @ManagedObject("Custom format request log") public class CustomRequestLog extends ContainerLifeCycle implements RequestLog { - protected static final Logger LOG = Log.getLogger(CustomRequestLog.class); + protected static final Logger LOG = LoggerFactory.getLogger(CustomRequestLog.class); public static final String DEFAULT_DATE_FORMAT = "dd/MMM/yyyy:HH:mm:ss ZZZ"; public static final String NCSA_FORMAT = "%{client}a - %u %t \"%r\" %s %O"; - public static final String EXTENDED_NCSA_FORMAT = "%{client}a - %u %t \"%r\" %s %O \"%{Referer}i\" \"%{User-Agent}i\""; + public static final String EXTENDED_NCSA_FORMAT = NCSA_FORMAT + " \"%{Referer}i\" \"%{User-Agent}i\""; private static ThreadLocal _buffers = ThreadLocal.withInitial(() -> new StringBuilder(256)); @@ -284,6 +287,21 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog private final MethodHandle _logHandle; private final String _formatString; + public CustomRequestLog() + { + this(new Slf4jRequestLogWriter(), EXTENDED_NCSA_FORMAT); + } + + public CustomRequestLog(String file) + { + this(file, EXTENDED_NCSA_FORMAT); + } + + public CustomRequestLog(String file, String format) + { + this(new RequestLogWriter(file), format); + } + public CustomRequestLog(RequestLog.Writer writer, String formatString) { _formatString = formatString; @@ -294,24 +312,10 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog { _logHandle = getLogHandle(formatString); } - catch (NoSuchMethodException e) + catch (NoSuchMethodException | IllegalAccessException e) { throw new IllegalStateException(e); } - catch (IllegalAccessException e) - { - throw new IllegalStateException(e); - } - } - - public CustomRequestLog(String file) - { - this(file, EXTENDED_NCSA_FORMAT); - } - - public CustomRequestLog(String file, String format) - { - this(new RequestLogWriter(file), format); } @ManagedAttribute("The RequestLogWriter") @@ -343,7 +347,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Unable to log request", e); } } @@ -357,20 +361,14 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog protected static String getAuthentication(Request request, boolean checkDeferred) { Authentication authentication = request.getAuthentication(); + if (checkDeferred && authentication instanceof Authentication.Deferred) + authentication = ((Authentication.Deferred)authentication).authenticate(request); String name = null; - - boolean deferred = false; - if (checkDeferred && authentication instanceof Authentication.Deferred) - { - authentication = ((Authentication.Deferred)authentication).authenticate(request); - deferred = true; - } - if (authentication instanceof Authentication.User) name = ((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName(); - return (name == null) ? null : (deferred ? ("?" + name) : name); + return name; } /** @@ -415,9 +413,9 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog if (_ignorePaths != null && _ignorePaths.length > 0) { _ignorePathMap = new PathMappings<>(); - for (int i = 0; i < _ignorePaths.length; i++) + for (String ignorePath : _ignorePaths) { - _ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]); + _ignorePathMap.put(ignorePath, ignorePath); } } else @@ -441,8 +439,9 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog private MethodHandle getLogHandle(String formatString) throws NoSuchMethodException, IllegalAccessException { - MethodHandle append = MethodHandles.lookup().findStatic(CustomRequestLog.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class)); - MethodHandle logHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, "logNothing", methodType(Void.TYPE, StringBuilder.class, Request.class, Response.class)); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandle append = lookup.findStatic(CustomRequestLog.class, "append", methodType(void.class, String.class, StringBuilder.class)); + MethodHandle logHandle = lookup.findStatic(CustomRequestLog.class, "logNothing", methodType(void.class, StringBuilder.class, Request.class, Response.class)); List tokens = getTokens(formatString); Collections.reverse(tokens); @@ -452,7 +451,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog if (t.isLiteralString()) logHandle = updateLogHandle(logHandle, append, t.literal); else - logHandle = updateLogHandle(logHandle, append, t.code, t.arg, t.modifiers, t.negated); + logHandle = updateLogHandle(logHandle, append, lookup, t.code, t.arg, t.modifiers, t.negated); } return logHandle; @@ -485,7 +484,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog String arg = m.group("ARG"); String modifierString = m.group("MOD"); - Boolean negated = false; + boolean negated = false; if (modifierString != null) { if (modifierString.startsWith("!")) @@ -578,10 +577,10 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog return foldArguments(logHandle, dropArguments(dropArguments(append.bindTo(literal), 1, Request.class), 2, Response.class)); } - private MethodHandle updateLogHandle(MethodHandle logHandle, MethodHandle append, String code, String arg, List modifiers, boolean negated) throws NoSuchMethodException, IllegalAccessException + private MethodHandle updateLogHandle(MethodHandle logHandle, MethodHandle append, MethodHandles.Lookup lookup, String code, String arg, List modifiers, boolean negated) throws NoSuchMethodException, IllegalAccessException { - MethodType logType = methodType(Void.TYPE, StringBuilder.class, Request.class, Response.class); - MethodType logTypeArg = methodType(Void.TYPE, String.class, StringBuilder.class, Request.class, Response.class); + MethodType logType = methodType(void.class, StringBuilder.class, Request.class, Response.class); + MethodType logTypeArg = methodType(void.class, String.class, StringBuilder.class, Request.class, Response.class); //TODO should we throw IllegalArgumentExceptions when given arguments for codes which do not take them MethodHandle specificHandle; @@ -595,7 +594,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog case "a": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) arg = "server"; String method; @@ -621,13 +620,13 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog throw new IllegalArgumentException("Invalid arg for %a"); } - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "p": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) arg = "server"; String method; @@ -654,63 +653,61 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog throw new IllegalArgumentException("Invalid arg for %p"); } - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "I": { String method; - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) method = "logBytesReceived"; else if (arg.equalsIgnoreCase("clf")) method = "logBytesReceivedCLF"; else throw new IllegalArgumentException("Invalid argument for %I"); - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "O": { String method; - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) method = "logBytesSent"; else if (arg.equalsIgnoreCase("clf")) method = "logBytesSentCLF"; else throw new IllegalArgumentException("Invalid argument for %O"); - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "S": { String method; - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) method = "logBytesTransferred"; else if (arg.equalsIgnoreCase("clf")) method = "logBytesTransferredCLF"; else throw new IllegalArgumentException("Invalid argument for %S"); - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "C": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) { - String method = "logRequestCookies"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestCookies", logType); } else { - String method = "logRequestCookie"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeArg); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestCookie", logTypeArg); specificHandle = specificHandle.bindTo(arg); } break; @@ -718,97 +715,85 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog case "D": { - String method = "logLatencyMicroseconds"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logLatencyMicroseconds", logType); break; } case "e": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) throw new IllegalArgumentException("No arg for %e"); - String method = "logEnvironmentVar"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeArg); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logEnvironmentVar", logTypeArg); specificHandle = specificHandle.bindTo(arg); break; } case "f": { - String method = "logFilename"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logFilename", logType); break; } case "H": { - String method = "logRequestProtocol"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestProtocol", logType); break; } case "i": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) throw new IllegalArgumentException("No arg for %i"); - String method = "logRequestHeader"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeArg); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestHeader", logTypeArg); specificHandle = specificHandle.bindTo(arg); break; } case "k": { - String method = "logKeepAliveRequests"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logKeepAliveRequests", logType); break; } case "m": { - String method = "logRequestMethod"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestMethod", logType); break; } case "o": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) throw new IllegalArgumentException("No arg for %o"); - String method = "logResponseHeader"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeArg); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logResponseHeader", logTypeArg); specificHandle = specificHandle.bindTo(arg); break; } case "q": { - String method = "logQueryString"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logQueryString", logType); break; } case "r": { - String method = "logRequestFirstLine"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestFirstLine", logType); break; } case "R": { - String method = "logRequestHandler"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestHandler", logType); break; } case "s": { - String method = "logResponseStatus"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logResponseStatus", logType); break; } @@ -845,9 +830,8 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog DateCache logDateCache = new DateCache(format, locale, timeZone); - String method = "logRequestTime"; - MethodType logTypeDateCache = methodType(Void.TYPE, DateCache.class, StringBuilder.class, Request.class, Response.class); - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeDateCache); + MethodType logTypeDateCache = methodType(void.class, DateCache.class, StringBuilder.class, Request.class, Response.class); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestTime", logTypeDateCache); specificHandle = specificHandle.bindTo(logDateCache); break; } @@ -873,54 +857,52 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog throw new IllegalArgumentException("Invalid arg for %T"); } - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "u": { String method; - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) + method = "logRequestAuthentication"; + else if ("d".equals(arg)) method = "logRequestAuthenticationWithDeferred"; else - method = "logRequestAuthentication"; + throw new IllegalArgumentException("Invalid arg for %u: " + arg); - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, method, logType); break; } case "U": { - String method = "logUrlRequestPath"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logUrlRequestPath", logType); break; } case "X": { - String method = "logConnectionStatus"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logConnectionStatus", logType); break; } case "ti": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) throw new IllegalArgumentException("No arg for %ti"); - String method = "logRequestTrailer"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeArg); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logRequestTrailer", logTypeArg); specificHandle = specificHandle.bindTo(arg); break; } case "to": { - if (arg == null || arg.isEmpty()) + if (StringUtil.isEmpty(arg)) throw new IllegalArgumentException("No arg for %to"); - String method = "logResponseTrailer"; - specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logTypeArg); + specificHandle = lookup.findStatic(CustomRequestLog.class, "logResponseTrailer", logTypeArg); specificHandle = specificHandle.bindTo(arg); break; } @@ -931,7 +913,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog if (modifiers != null && !modifiers.isEmpty()) { - MethodHandle modifierTest = MethodHandles.lookup().findStatic(CustomRequestLog.class, "modify", methodType(Boolean.TYPE, List.class, Boolean.class, StringBuilder.class, Request.class, Response.class)); + MethodHandle modifierTest = lookup.findStatic(CustomRequestLog.class, "modify", methodType(Boolean.TYPE, List.class, Boolean.class, StringBuilder.class, Request.class, Response.class)); MethodHandle dash = updateLogHandle(logHandle, append, "-"); MethodHandle log = foldArguments(logHandle, specificHandle); @@ -1052,12 +1034,16 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog private static void logRequestCookie(String arg, StringBuilder b, Request request, Response response) { - for (Cookie c : request.getCookies()) + Cookie[] cookies = request.getCookies(); + if (cookies != null) { - if (arg.equals(c.getName())) + for (Cookie c : cookies) { - b.append(c.getValue()); - return; + if (arg.equals(c.getName())) + { + b.append(c.getValue()); + return; + } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/DebugListener.java b/jetty-server/src/main/java/org/eclipse/jetty/server/DebugListener.java index a26ded230a8..0b62297ec6e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/DebugListener.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/DebugListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -42,8 +42,8 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A Context Listener that produces additional debug. @@ -55,7 +55,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject("Debug Listener") public class DebugListener extends AbstractLifeCycle implements ServletContextListener { - private static final Logger LOG = Log.getLogger(DebugListener.class); + private static final Logger LOG = LoggerFactory.getLogger(DebugListener.class); private static final DateCache __date = new DateCache("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); private final String _attr = String.format("__R%s@%x", this.getClass().getSimpleName(), System.identityHashCode(this)); @@ -140,7 +140,7 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to dump {}", handler, e); } } } @@ -192,7 +192,7 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi if (_out != null) _out.printf("%s.%03d:%s%n", __date.formatNow(now), ms, s); if (LOG.isDebugEnabled()) - LOG.info(s); + LOG.debug(s); } final AsyncListener _asyncListener = new AsyncListener() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/DetectorConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/DetectorConnectionFactory.java new file mode 100644 index 00000000000..2e93350a9dc --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/DetectorConnectionFactory.java @@ -0,0 +1,301 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.jetty.io.AbstractConnection; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.BufferUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link ConnectionFactory} combining multiple {@link Detecting} instances that will upgrade to + * the first one recognizing the bytes in the buffer. + */ +public class DetectorConnectionFactory extends AbstractConnectionFactory implements ConnectionFactory.Detecting +{ + private static final Logger LOG = LoggerFactory.getLogger(DetectorConnectionFactory.class); + + private final List _detectingConnectionFactories; + + /** + *

      When the first bytes are not recognized by the {@code detectingConnectionFactories}, the default behavior is to + * upgrade to the protocol returned by {@link #findNextProtocol(Connector)}.

      + * @param detectingConnectionFactories the {@link Detecting} instances. + */ + public DetectorConnectionFactory(Detecting... detectingConnectionFactories) + { + super(toProtocolString(detectingConnectionFactories)); + _detectingConnectionFactories = Arrays.asList(detectingConnectionFactories); + for (Detecting detectingConnectionFactory : detectingConnectionFactories) + { + addBean(detectingConnectionFactory); + } + } + + private static String toProtocolString(Detecting... detectingConnectionFactories) + { + if (detectingConnectionFactories.length == 0) + throw new IllegalArgumentException("At least one detecting instance is required"); + + // remove protocol duplicates while keeping their ordering -> use LinkedHashSet + LinkedHashSet protocols = Arrays.stream(detectingConnectionFactories).map(ConnectionFactory::getProtocol).collect(Collectors.toCollection(LinkedHashSet::new)); + + String protocol = protocols.stream().collect(Collectors.joining("|", "[", "]")); + if (LOG.isDebugEnabled()) + LOG.debug("Detector generated protocol name : {}", protocol); + return protocol; + } + + /** + * Performs a detection using multiple {@link ConnectionFactory.Detecting} instances and returns the aggregated outcome. + * @param buffer the buffer to perform a detection against. + * @return A {@link Detecting.Detection} value with the detection outcome of the {@code detectingConnectionFactories}. + */ + @Override + public Detecting.Detection detect(ByteBuffer buffer) + { + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} detecting from buffer {} using {}", getProtocol(), BufferUtil.toHexString(buffer), _detectingConnectionFactories); + boolean needMoreBytes = true; + for (Detecting detectingConnectionFactory : _detectingConnectionFactories) + { + Detecting.Detection detection = detectingConnectionFactory.detect(buffer); + if (detection == Detecting.Detection.RECOGNIZED) + { + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} recognized bytes using {}", getProtocol(), detection); + return Detecting.Detection.RECOGNIZED; + } + needMoreBytes &= detection == Detection.NEED_MORE_BYTES; + } + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} {}", getProtocol(), (needMoreBytes ? "requires more bytes" : "failed to recognize bytes")); + return needMoreBytes ? Detection.NEED_MORE_BYTES : Detection.NOT_RECOGNIZED; + } + + /** + * Utility method that performs an upgrade to the specified connection factory, disposing of the given resources when needed. + * @param connectionFactory the connection factory to upgrade to. + * @param connector the connector. + * @param endPoint the endpoint. + */ + protected static void upgradeToConnectionFactory(ConnectionFactory connectionFactory, Connector connector, EndPoint endPoint) throws IllegalStateException + { + if (LOG.isDebugEnabled()) + LOG.debug("Upgrading to connection factory {}", connectionFactory); + if (connectionFactory == null) + throw new IllegalStateException("Cannot upgrade: connection factory must not be null for " + endPoint); + Connection nextConnection = connectionFactory.newConnection(connector, endPoint); + if (!(nextConnection instanceof Connection.UpgradeTo)) + throw new IllegalStateException("Cannot upgrade: " + nextConnection + " does not implement " + Connection.UpgradeTo.class.getName() + " for " + endPoint); + endPoint.upgrade(nextConnection); + if (LOG.isDebugEnabled()) + LOG.debug("Upgraded to connection factory {} and released buffer", connectionFactory); + } + + /** + *

      Callback method called when detection was unsuccessful. + * This implementation upgrades to the protocol returned by {@link #findNextProtocol(Connector)}.

      + * @param connector the connector. + * @param endPoint the endpoint. + * @param buffer the buffer. + */ + protected void nextProtocol(Connector connector, EndPoint endPoint, ByteBuffer buffer) throws IllegalStateException + { + String nextProtocol = findNextProtocol(connector); + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} detection unsuccessful, found '{}' as the next protocol to upgrade to", getProtocol(), nextProtocol); + if (nextProtocol == null) + throw new IllegalStateException("Cannot find protocol following '" + getProtocol() + "' in connector's protocol list " + connector.getProtocols() + " for " + endPoint); + upgradeToConnectionFactory(connector.getConnectionFactory(nextProtocol), connector, endPoint); + } + + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + return configure(new DetectorConnection(endPoint, connector), connector, endPoint); + } + + private class DetectorConnection extends AbstractConnection implements Connection.UpgradeFrom, Connection.UpgradeTo + { + private final Connector _connector; + private final ByteBuffer _buffer; + + private DetectorConnection(EndPoint endp, Connector connector) + { + super(endp, connector.getExecutor()); + _connector = connector; + _buffer = connector.getByteBufferPool().acquire(getInputBufferSize(), true); + } + + @Override + public void onUpgradeTo(ByteBuffer prefilled) + { + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} copying prefilled buffer {}", getProtocol(), BufferUtil.toDetailString(prefilled)); + if (BufferUtil.hasContent(prefilled)) + BufferUtil.append(_buffer, prefilled); + } + + @Override + public ByteBuffer onUpgradeFrom() + { + return _buffer; + } + + @Override + public void onOpen() + { + super.onOpen(); + if (!detectAndUpgrade()) + fillInterested(); + } + + @Override + public void onFillable() + { + try + { + while (BufferUtil.space(_buffer) > 0) + { + // Read data + int fill = getEndPoint().fill(_buffer); + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} filled buffer with {} bytes", getProtocol(), fill); + if (fill < 0) + { + _connector.getByteBufferPool().release(_buffer); + getEndPoint().shutdownOutput(); + return; + } + if (fill == 0) + { + fillInterested(); + return; + } + + if (detectAndUpgrade()) + return; + } + + // all Detecting instances want more bytes than this buffer can store + LOG.warn("Detector {} failed to detect upgrade target on {} for {}", getProtocol(), _detectingConnectionFactories, getEndPoint()); + releaseAndClose(); + } + catch (Throwable x) + { + LOG.warn("Detector {} error for {}", getProtocol(), getEndPoint(), x); + releaseAndClose(); + } + } + + /** + * @return true when upgrade was performed, false otherwise. + */ + private boolean detectAndUpgrade() + { + if (BufferUtil.isEmpty(_buffer)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} skipping detection on an empty buffer", getProtocol()); + return false; + } + + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} performing detection with {} bytes", getProtocol(), _buffer.remaining()); + boolean notRecognized = true; + for (Detecting detectingConnectionFactory : _detectingConnectionFactories) + { + Detecting.Detection detection = detectingConnectionFactory.detect(_buffer); + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} performed detection from {} with {} which returned {}", getProtocol(), BufferUtil.toDetailString(_buffer), detectingConnectionFactory, detection); + if (detection == Detecting.Detection.RECOGNIZED) + { + try + { + // This DetectingConnectionFactory recognized those bytes -> upgrade to the next one. + Connection nextConnection = detectingConnectionFactory.newConnection(_connector, getEndPoint()); + if (!(nextConnection instanceof UpgradeTo)) + throw new IllegalStateException("Cannot upgrade: " + nextConnection + " does not implement " + UpgradeTo.class.getName()); + getEndPoint().upgrade(nextConnection); + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} upgraded to {}", getProtocol(), nextConnection); + return true; + } + catch (DetectionFailureException e) + { + // It's just bubbling up from a nested Detector, so it's already handled, just rethrow it. + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} failed to upgrade, rethrowing", getProtocol(), e); + throw e; + } + catch (Exception e) + { + // Two reasons that can make us end up here: + // 1) detectingConnectionFactory.newConnection() failed? probably because it cannot find the next protocol + // 2) nextConnection is not instanceof UpgradeTo + // -> release the resources before rethrowing as DetectionFailureException + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} failed to upgrade", getProtocol()); + releaseAndClose(); + throw new DetectionFailureException(e); + } + } + notRecognized &= detection == Detecting.Detection.NOT_RECOGNIZED; + } + + if (notRecognized) + { + // No DetectingConnectionFactory recognized those bytes -> call unsuccessful detection callback. + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} failed to detect a known protocol, falling back to nextProtocol()", getProtocol()); + nextProtocol(_connector, getEndPoint(), _buffer); + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} call to nextProtocol() succeeded, assuming upgrade performed", getProtocol()); + return true; + } + + return false; + } + + private void releaseAndClose() + { + if (LOG.isDebugEnabled()) + LOG.debug("Detector {} releasing buffer and closing", getProtocol()); + _connector.getByteBufferPool().release(_buffer); + close(); + } + } + + private static class DetectionFailureException extends RuntimeException + { + public DetectionFailureException(Throwable cause) + { + super(cause); + } + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java index 9d8088b4ef1..6801e9b669f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -27,6 +27,7 @@ import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -35,14 +36,12 @@ import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Dispatcher implements RequestDispatcher { - private static final Logger LOG = Log.getLogger(Dispatcher.class); - - public static final String __ERROR_DISPATCH = "org.eclipse.jetty.server.Dispatcher.ERROR"; + private static final Logger LOG = LoggerFactory.getLogger(Dispatcher.class); /** * Dispatch include attribute names @@ -77,15 +76,7 @@ public class Dispatcher implements RequestDispatcher public void error(ServletRequest request, ServletResponse response) throws ServletException, IOException { - try - { - request.setAttribute(__ERROR_DISPATCH, Boolean.TRUE); - forward(request, response, DispatcherType.ERROR); - } - finally - { - request.setAttribute(__ERROR_DISPATCH, null); - } + forward(request, response, DispatcherType.ERROR); } @Override @@ -118,7 +109,7 @@ public class Dispatcher implements RequestDispatcher attr._servletPath = null; // set by ServletHandler attr._pathInfo = _pathInContext; attr._query = _uri.getQuery(); - + attr._mapping = null; //set by ServletHandler if (attr._query != null) baseRequest.mergeQueryParameters(baseRequest.getQueryString(), attr._query, false); baseRequest.setAttributes(attr); @@ -157,6 +148,7 @@ public class Dispatcher implements RequestDispatcher final String old_context_path = baseRequest.getContextPath(); final String old_servlet_path = baseRequest.getServletPath(); final String old_path_info = baseRequest.getPathInfo(); + final HttpServletMapping old_mapping = baseRequest.getHttpServletMapping(); final MultiMap old_query_params = baseRequest.getQueryParameters(); final Attributes old_attr = baseRequest.getAttributes(); @@ -185,6 +177,7 @@ public class Dispatcher implements RequestDispatcher attr._requestURI = (String)old_attr.getAttribute(FORWARD_REQUEST_URI); attr._contextPath = (String)old_attr.getAttribute(FORWARD_CONTEXT_PATH); attr._servletPath = (String)old_attr.getAttribute(FORWARD_SERVLET_PATH); + attr._mapping = (HttpServletMapping)old_attr.getAttribute(FORWARD_MAPPING); } else { @@ -193,6 +186,7 @@ public class Dispatcher implements RequestDispatcher attr._requestURI = old_uri.getPath(); attr._contextPath = old_context_path; attr._servletPath = old_servlet_path; + attr._mapping = old_mapping; } HttpURI uri = new HttpURI(old_uri.getScheme(), old_uri.getHost(), old_uri.getPort(), @@ -229,8 +223,18 @@ public class Dispatcher implements RequestDispatcher _contextHandler.handle(_pathInContext, baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); - if (!baseRequest.getHttpChannelState().isAsync()) - commitResponse(response, baseRequest); + // If we are not async and not closed already, then close via the possibly wrapped response. + if (!baseRequest.getHttpChannelState().isAsync() && !baseResponse.getHttpOutput().isClosed()) + { + try + { + response.getOutputStream().close(); + } + catch (IllegalStateException e) + { + response.getWriter().close(); + } + } } } finally @@ -252,57 +256,6 @@ public class Dispatcher implements RequestDispatcher return String.format("Dispatcher@0x%x{%s,%s}", hashCode(), _named, _uri); } - @SuppressWarnings("Duplicates") - private void commitResponse(ServletResponse response, Request baseRequest) throws IOException, ServletException - { - if (baseRequest.getResponse().isWriting()) - { - try - { - // Try closing Writer first (based on knowledge in Response obj) - response.getWriter().close(); - } - catch (IllegalStateException ex1) - { - try - { - // Try closing OutputStream as alternate route - // This path is possible due to badly behaving Response wrappers - response.getOutputStream().close(); - } - catch (IllegalStateException ex2) - { - ServletException servletException = new ServletException("Unable to commit the response", ex2); - servletException.addSuppressed(ex1); - throw servletException; - } - } - } - else - { - try - { - // Try closing OutputStream first (based on knowledge in Response obj) - response.getOutputStream().close(); - } - catch (IllegalStateException ex1) - { - try - { - // Try closing Writer as alternate route - // This path is possible due to badly behaving Response wrappers - response.getWriter().close(); - } - catch (IllegalStateException ex2) - { - ServletException servletException = new ServletException("Unable to commit the response", ex2); - servletException.addSuppressed(ex1); - throw servletException; - } - } - } - } - private class ForwardAttributes implements Attributes { final Attributes _attr; @@ -312,6 +265,7 @@ public class Dispatcher implements RequestDispatcher String _servletPath; String _pathInfo; String _query; + HttpServletMapping _mapping; ForwardAttributes(Attributes attributes) { @@ -333,6 +287,8 @@ public class Dispatcher implements RequestDispatcher return _contextPath; if (key.equals(FORWARD_QUERY_STRING)) return _query; + if (key.equals(FORWARD_MAPPING)) + return _mapping; } if (key.startsWith(__INCLUDE_PREFIX)) @@ -363,6 +319,7 @@ public class Dispatcher implements RequestDispatcher set.add(FORWARD_REQUEST_URI); set.add(FORWARD_SERVLET_PATH); set.add(FORWARD_CONTEXT_PATH); + set.add(FORWARD_MAPPING); if (_query != null) set.add(FORWARD_QUERY_STRING); else @@ -387,7 +344,8 @@ public class Dispatcher implements RequestDispatcher _contextPath = (String)value; else if (key.equals(FORWARD_QUERY_STRING)) _query = (String)value; - + else if (key.equals(FORWARD_MAPPING)) + _mapping = (HttpServletMapping)value; else if (value == null) _attr.removeAttribute(key); else @@ -427,6 +385,7 @@ public class Dispatcher implements RequestDispatcher String _servletPath; String _pathInfo; String _query; + HttpServletMapping _mapping; IncludeAttributes(Attributes attributes) { @@ -448,6 +407,8 @@ public class Dispatcher implements RequestDispatcher return _query; if (key.equals(INCLUDE_REQUEST_URI)) return _requestURI; + if (key.equals(INCLUDE_MAPPING)) + return _mapping; } else if (key.startsWith(__INCLUDE_PREFIX)) return null; @@ -476,6 +437,7 @@ public class Dispatcher implements RequestDispatcher set.add(INCLUDE_REQUEST_URI); set.add(INCLUDE_SERVLET_PATH); set.add(INCLUDE_CONTEXT_PATH); + set.add(INCLUDE_MAPPING); if (_query != null) set.add(INCLUDE_QUERY_STRING); else @@ -500,6 +462,8 @@ public class Dispatcher implements RequestDispatcher _contextPath = (String)value; else if (key.equals(INCLUDE_QUERY_STRING)) _query = (String)value; + else if (key.equals(INCLUDE_MAPPING)) + _mapping = (HttpServletMapping)value; else if (value == null) _attr.removeAttribute(key); else diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/EncodingHttpWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/EncodingHttpWriter.java index 23a2413903c..8f9221236ba 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/EncodingHttpWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/EncodingHttpWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -47,16 +47,11 @@ public class EncodingHttpWriter extends HttpWriter public void write(char[] s, int offset, int length) throws IOException { HttpOutput out = _out; - if (length == 0 && out.isAllContentWritten()) - { - out.close(); - return; - } while (length > 0) { _bytes.reset(); - int chars = length > MAX_OUTPUT_CHARS ? MAX_OUTPUT_CHARS : length; + int chars = Math.min(length, MAX_OUTPUT_CHARS); _converter.write(s, offset, chars); _converter.flush(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java index 92e7a1a52fc..41edf1655f7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -24,6 +24,7 @@ import java.lang.invoke.MethodType; import java.net.InetSocketAddress; import javax.servlet.ServletRequest; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; @@ -35,8 +36,6 @@ import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import static java.lang.invoke.MethodType.methodType; @@ -63,8 +62,6 @@ import static java.lang.invoke.MethodType.methodType; */ public class ForwardedRequestCustomizer implements Customizer { - private static final Logger LOG = Log.getLogger(ForwardedRequestCustomizer.class); - private HostPortHttpField _forcedHost; private boolean _proxyAsAuthority = false; private boolean _forwardedPortAsAuthority = true; @@ -236,7 +233,7 @@ public class ForwardedRequestCustomizer implements Customizer public String getForwardedPortHeader() { - return _forwardedHostHeader; + return _forwardedPortHeader; } /** @@ -244,9 +241,9 @@ public class ForwardedRequestCustomizer implements Customizer */ public void setForwardedPortHeader(String forwardedPortHeader) { - if (_forwardedHostHeader == null || !_forwardedHostHeader.equalsIgnoreCase(forwardedPortHeader)) + if (_forwardedPortHeader == null || !_forwardedPortHeader.equalsIgnoreCase(forwardedPortHeader)) { - _forwardedHostHeader = forwardedPortHeader; + _forwardedPortHeader = forwardedPortHeader; updateHandles(); } } @@ -356,7 +353,7 @@ public class ForwardedRequestCustomizer implements Customizer } /** - * @return true if the presence of a SSL session or certificate header is sufficient + * @return true if the presence of an SSL session or certificate header is sufficient * to indicate a secure request (default is true) */ public boolean isSslIsSecure() @@ -365,7 +362,7 @@ public class ForwardedRequestCustomizer implements Customizer } /** - * @param sslIsSecure true if the presence of a SSL session or certificate header is sufficient + * @param sslIsSecure true if the presence of an SSL session or certificate header is sufficient * to indicate a secure request (default is true) */ public void setSslIsSecure(boolean sslIsSecure) @@ -380,18 +377,18 @@ public class ForwardedRequestCustomizer implements Customizer // Do a single pass through the header fields as it is a more efficient single iteration. Forwarded forwarded = new Forwarded(request, config); - try + for (HttpField field : httpFields) { - for (HttpField field : httpFields) + try { MethodHandle handle = _handles.get(field.getName()); if (handle != null) handle.invoke(forwarded, field); } - } - catch (Throwable e) - { - throw new RuntimeException(e); + catch (Throwable t) + { + onError(field, t); + } } if (forwarded._proto != null) @@ -401,11 +398,21 @@ public class ForwardedRequestCustomizer implements Customizer request.setSecure(true); } - if (forwarded._host != null) + if (forwarded._server != null && forwarded._host instanceof PortSetHostPort) + { + httpFields.put(new HostPortHttpField(forwarded._server, forwarded._host.getPort())); + request.setAuthority(forwarded._server, forwarded._host.getPort()); + } + else if (forwarded._host != null) { httpFields.put(new HostPortHttpField(forwarded._host)); request.setAuthority(forwarded._host.getHost(), forwarded._host.getPort()); } + else if (forwarded._server != null) + { + httpFields.put(new HostPortHttpField(forwarded._server)); + request.setAuthority(forwarded._server, 0); + } if (forwarded._for != null) { @@ -414,6 +421,11 @@ public class ForwardedRequestCustomizer implements Customizer } } + protected void onError(HttpField field, Throwable t) + { + throw new BadMessageException("Bad header value for " + field.getName(), t); + } + protected String getLeftMost(String headerValue) { if (headerValue == null) @@ -456,32 +468,32 @@ public class ForwardedRequestCustomizer implements Customizer { int size = 0; MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType type = methodType(Void.TYPE, HttpField.class); + // Loop to grow capacity of ArrayTrie for all headers while (true) { try { - size += 128; + size += 128; // experimented good baseline size _handles = new ArrayTrie<>(size); - if (_forwardedCipherSuiteHeader != null && !_handles.put(_forwardedCipherSuiteHeader, lookup.findVirtual(Forwarded.class, "handleCipherSuite", type))) + if (updateForwardedHandle(lookup, getForwardedCipherSuiteHeader(), "handleCipherSuite")) continue; - if (_forwardedSslSessionIdHeader != null && !_handles.put(_forwardedSslSessionIdHeader, lookup.findVirtual(Forwarded.class, "handleSslSessionId", type))) + if (updateForwardedHandle(lookup, getForwardedSslSessionIdHeader(), "handleSslSessionId")) continue; - if (_forwardedHeader != null && !_handles.put(_forwardedHeader, lookup.findVirtual(Forwarded.class, "handleRFC7239", type))) + if (updateForwardedHandle(lookup, getForwardedHeader(), "handleRFC7239")) continue; - if (_forwardedForHeader != null && !_handles.put(_forwardedForHeader, lookup.findVirtual(Forwarded.class, "handleFor", type))) + if (updateForwardedHandle(lookup, getForwardedForHeader(), "handleFor")) continue; - if (_forwardedPortHeader != null && !_handles.put(_forwardedPortHeader, lookup.findVirtual(Forwarded.class, "handlePort", type))) + if (updateForwardedHandle(lookup, getForwardedPortHeader(), "handlePort")) continue; - if (_forwardedHostHeader != null && !_handles.put(_forwardedHostHeader, lookup.findVirtual(Forwarded.class, "handleHost", type))) + if (updateForwardedHandle(lookup, getForwardedHostHeader(), "handleHost")) continue; - if (_forwardedProtoHeader != null && !_handles.put(_forwardedProtoHeader, lookup.findVirtual(Forwarded.class, "handleProto", type))) + if (updateForwardedHandle(lookup, getForwardedProtoHeader(), "handleProto")) continue; - if (_forwardedHttpsHeader != null && !_handles.put(_forwardedHttpsHeader, lookup.findVirtual(Forwarded.class, "handleHttps", type))) + if (updateForwardedHandle(lookup, getForwardedHttpsHeader(), "handleHttps")) continue; - if (_forwardedServerHeader != null && !_handles.put(_forwardedServerHeader, lookup.findVirtual(Forwarded.class, "handleServer", type))) + if (updateForwardedHandle(lookup, getForwardedServerHeader(), "handleServer")) continue; break; } @@ -492,6 +504,16 @@ public class ForwardedRequestCustomizer implements Customizer } } + private boolean updateForwardedHandle(MethodHandles.Lookup lookup, String headerName, String forwardedMethodName) throws NoSuchMethodException, IllegalAccessException + { + final MethodType type = methodType(void.class, HttpField.class); + + if (StringUtil.isBlank(headerName)) + return false; + + return !_handles.put(headerName, lookup.findVirtual(Forwarded.class, forwardedMethodName, type)); + } + private static class ForcedHostPort extends HostPort { ForcedHostPort(String authority) @@ -538,6 +560,7 @@ public class ForwardedRequestCustomizer implements Customizer String _proto; HostPort _for; HostPort _host; + String _server; public Forwarded(Request request, HttpConfiguration config) { @@ -548,6 +571,7 @@ public class ForwardedRequestCustomizer implements Customizer _host = _forcedHost.getHostPort(); } + @SuppressWarnings("unused") public void handleCipherSuite(HttpField field) { _request.setAttribute("javax.servlet.request.cipher_suite", field.getValue()); @@ -558,6 +582,7 @@ public class ForwardedRequestCustomizer implements Customizer } } + @SuppressWarnings("unused") public void handleSslSessionId(HttpField field) { _request.setAttribute("javax.servlet.request.ssl_session_id", field.getValue()); @@ -568,13 +593,14 @@ public class ForwardedRequestCustomizer implements Customizer } } + @SuppressWarnings("unused") public void handleHost(HttpField field) { - if (_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader)) + if (getForwardedPortAsAuthority() && !StringUtil.isEmpty(getForwardedPortHeader())) { if (_host == null) _host = new PossiblyPartialHostPort(getLeftMost(field.getValue())); - else if (_for instanceof PortSetHostPort) + else if (_host instanceof PortSetHostPort) _host = new HostPort(HostPort.normalizeHost(getLeftMost(field.getValue())), _host.getPort()); } else if (_host == null) @@ -583,58 +609,66 @@ public class ForwardedRequestCustomizer implements Customizer } } + @SuppressWarnings("unused") public void handleServer(HttpField field) { - if (_proxyAsAuthority) + if (getProxyAsAuthority()) return; - handleHost(field); + _server = getLeftMost(field.getValue()); } + @SuppressWarnings("unused") public void handleProto(HttpField field) { if (_proto == null) _proto = getLeftMost(field.getValue()); } + @SuppressWarnings("unused") public void handleFor(HttpField field) { - if (!_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader)) + String authority = getLeftMost(field.getValue()); + if (!getForwardedPortAsAuthority() && !StringUtil.isEmpty(getForwardedPortHeader())) { if (_for == null) - _for = new PossiblyPartialHostPort(getLeftMost(field.getValue())); + _for = new PossiblyPartialHostPort(authority); else if (_for instanceof PortSetHostPort) - _for = new HostPort(HostPort.normalizeHost(getLeftMost(field.getValue())), _for.getPort()); + _for = new HostPort(HostPort.normalizeHost(authority), _for.getPort()); } else if (_for == null) { - _for = new HostPort(getLeftMost(field.getValue())); + _for = new HostPort(authority); } } + @SuppressWarnings("unused") public void handlePort(HttpField field) { - if (!_forwardedPortAsAuthority) + int port = HostPort.parsePort(getLeftMost(field.getValue())); + if (!getForwardedPortAsAuthority()) { if (_for == null) - _for = new PortSetHostPort(_request.getRemoteHost(), field.getIntValue()); + _for = new PortSetHostPort(_request.getRemoteHost(), port); else if (_for instanceof PossiblyPartialHostPort && _for.getPort() <= 0) - _for = new HostPort(HostPort.normalizeHost(_for.getHost()), field.getIntValue()); + _for = new HostPort(HostPort.normalizeHost(_for.getHost()), port); } else { if (_host == null) - _host = new PortSetHostPort(_request.getServerName(), field.getIntValue()); + _host = new PortSetHostPort(_request.getServerName(), port); else if (_host instanceof PossiblyPartialHostPort && _host.getPort() <= 0) - _host = new HostPort(HostPort.normalizeHost(_host.getHost()), field.getIntValue()); + _host = new HostPort(HostPort.normalizeHost(_host.getHost()), port); } } + @SuppressWarnings("unused") public void handleHttps(HttpField field) { if (_proto == null && ("on".equalsIgnoreCase(field.getValue()) || "true".equalsIgnoreCase(field.getValue()))) _proto = HttpScheme.HTTPS.asString(); } + @SuppressWarnings("unused") public void handleRFC7239(HttpField field) { addValue(field.getValue()); @@ -650,11 +684,11 @@ public class ForwardedRequestCustomizer implements Customizer switch (name) { case "by": - if (!_proxyAsAuthority) + if (!getProxyAsAuthority()) break; if (value.startsWith("_") || "unknown".equals(value)) break; - if (_proxyAsAuthority && (_host == null || !(_host instanceof Rfc7239HostPort))) + if (_host == null || !(_host instanceof Rfc7239HostPort)) _host = new Rfc7239HostPort(value); break; case "for": diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java index 2cdb70f5bff..d7ef7fd26b4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java index c04effbffd7..cf9f3d6cf2b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java index d9d50d851d3..0071afbda3e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -24,8 +24,8 @@ import java.nio.file.Files; import java.nio.file.Path; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Display an optional Warning Message if the {jetty.home} and {jetty.base} are the same directory. @@ -34,7 +34,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class HomeBaseWarning { - private static final Logger LOG = Log.getLogger(HomeBaseWarning.class); + private static final Logger LOG = LoggerFactory.getLogger(HomeBaseWarning.class); public HomeBaseWarning() { @@ -59,7 +59,7 @@ public class HomeBaseWarning } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); // Can't definitively determine this state return; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HostHeaderCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HostHeaderCustomizer.java index 7e66004bf19..a18d2d79576 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HostHeaderCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HostHeaderCustomizer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java index bd46a1215a2..7da6a20c4ca 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -22,10 +22,10 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.EventListener; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -33,18 +33,17 @@ import java.util.function.Function; import java.util.function.Supplier; import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.ChannelEndPoint; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.QuietException; @@ -54,13 +53,13 @@ import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.SharedBlockingCallback.Blocker; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * HttpChannel represents a single endpoint for HTTP semantic processing. - * The HttpChannel is both a HttpParser.RequestHandler, where it passively receives events from + * The HttpChannel is both an HttpParser.RequestHandler, where it passively receives events from * an incoming HTTP request, and a Runnable, where it actively takes control of the request/response * life cycle and calls the application (perhaps suspending and resuming with multiple calls to run). * The HttpChannel signals the switch from passive mode to active mode by returning true to one of the @@ -69,10 +68,9 @@ import org.eclipse.jetty.util.thread.Scheduler; */ public class HttpChannel implements Runnable, HttpOutput.Interceptor { - private static final Logger LOG = Log.getLogger(HttpChannel.class); + public static Listener NOOP_LISTENER = new Listener() {}; + private static final Logger LOG = LoggerFactory.getLogger(HttpChannel.class); - private final AtomicBoolean _committed = new AtomicBoolean(); - private final AtomicBoolean _responseCompleted = new AtomicBoolean(); private final AtomicLong _requests = new AtomicLong(); private final Connector _connector; private final Executor _executor; @@ -82,9 +80,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor private final HttpChannelState _state; private final Request _request; private final Response _response; + private final HttpChannel.Listener _combinedListener; + @Deprecated + private final List _transientListeners = new ArrayList<>(); private HttpFields _trailers; private final Supplier _trailerSupplier = () -> _trailers; - private final List _listeners; private MetaData.Response _committedMetaData; private RequestLog _requestLog; private long _oldIdleTimeout; @@ -104,14 +104,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor _state = new HttpChannelState(this); _request = new Request(this, newHttpInput(_state)); _response = new Response(this, newHttpOutput()); - - _executor = connector == null ? null : connector.getServer().getThreadPool(); - _requestLog = connector == null ? null : connector.getServer().getRequestLog(); - - List listeners = new ArrayList<>(); - if (connector != null) - listeners.addAll(connector.getBeans(Listener.class)); - _listeners = listeners; + _executor = connector.getServer().getThreadPool(); + _requestLog = connector.getServer().getRequestLog(); + _combinedListener = (connector instanceof AbstractConnector) + ? ((AbstractConnector)connector).getHttpChannelListeners() + : NOOP_LISTENER; if (LOG.isDebugEnabled()) LOG.debug("new {} -> {},{},{}", @@ -121,6 +118,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor _state); } + public boolean isSendError() + { + return _state.isSendError(); + } + protected HttpInput newHttpInput(HttpChannelState state) { return new HttpInput(state); @@ -136,14 +138,32 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor return _state; } + /** + * Add a transient Listener to the HttpChannel. + *

      Listeners added by this method will only be notified + * if the HttpChannel has been constructed with an instance of + * {@link TransientListeners} as an {@link AbstractConnector} + * provided listener

      + *

      Transient listeners are removed after every request cycle

      + * @param listener + * @return true if the listener was added. + */ + @Deprecated public boolean addListener(Listener listener) { - return _listeners.add(listener); + return _transientListeners.add(listener); } + @Deprecated public boolean removeListener(Listener listener) { - return _listeners.remove(listener); + return _transientListeners.remove(listener); + } + + @Deprecated + public List getTransientListeners() + { + return _transientListeners; } public long getBytesWritten() @@ -228,12 +248,6 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor return _configuration; } - @Override - public boolean isOptimizedForDirectBuffers() - { - return getHttpTransport().isOptimizedForDirectBuffers(); - } - public Server getServer() { return _connector.getServer(); @@ -284,8 +298,6 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public void recycle() { - _committed.set(false); - _responseCompleted.set(false); _request.recycle(); _response.recycle(); _committedMetaData = null; @@ -293,6 +305,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor _written = 0; _trailers = null; _oldIdleTimeout = 0; + _transientListeners.clear(); } public void onAsyncWaitForContent() @@ -320,7 +333,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public boolean handle() { if (LOG.isDebugEnabled()) - LOG.debug("{} handle {} ", this, _request.getHttpURI()); + LOG.debug("handle {} {} ", _request.getHttpURI(), this); HttpChannelState.Action action = _state.handling(); @@ -334,127 +347,92 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor try { if (LOG.isDebugEnabled()) - LOG.debug("{} action {}", this, action); + LOG.debug("action {} {}", action, this); switch (action) { case TERMINATED: + onCompleted(); + break loop; + case WAIT: // break loop without calling unhandle break loop; - case NOOP: - // do nothing other than call unhandle - break; - case DISPATCH: { if (!_request.hasMetaData()) throw new IllegalStateException("state=" + _state); - _request.setHandled(false); - _response.getHttpOutput().reopen(); - try + dispatch(DispatcherType.REQUEST, () -> { - _request.setDispatcherType(DispatcherType.REQUEST); - notifyBeforeDispatch(_request); - - List customizers = _configuration.getCustomizers(); - if (!customizers.isEmpty()) + for (HttpConfiguration.Customizer customizer : _configuration.getCustomizers()) { - for (HttpConfiguration.Customizer customizer : customizers) - { - customizer.customize(getConnector(), _configuration, _request); - if (_request.isHandled()) - break; - } + customizer.customize(getConnector(), _configuration, _request); + if (_request.isHandled()) + return; } + getServer().handle(HttpChannel.this); + }); - if (!_request.isHandled()) - getServer().handle(this); - } - catch (Throwable x) - { - notifyDispatchFailure(_request, x); - throw x; - } - finally - { - notifyAfterDispatch(_request); - _request.setDispatcherType(null); - } break; } case ASYNC_DISPATCH: { - _request.setHandled(false); - _response.getHttpOutput().reopen(); - - try - { - _request.setDispatcherType(DispatcherType.ASYNC); - notifyBeforeDispatch(_request); - getServer().handleAsync(this); - } - catch (Throwable x) - { - notifyDispatchFailure(_request, x); - throw x; - } - finally - { - notifyAfterDispatch(_request); - _request.setDispatcherType(null); - } + dispatch(DispatcherType.ASYNC,() -> getServer().handleAsync(this)); break; } - case ERROR_DISPATCH: + case ASYNC_TIMEOUT: + _state.onTimeout(); + break; + + case SEND_ERROR: { try { - _response.reset(true); - Integer icode = (Integer)_request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); - int code = icode != null ? icode : HttpStatus.INTERNAL_SERVER_ERROR_500; - _response.setStatus(code); - _request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, code); - _request.setHandled(false); - _response.getHttpOutput().reopen(); + // Get ready to send an error response + _response.resetContent(); - try + // the following is needed as you cannot trust the response code and reason + // as those could have been modified after calling sendError + Integer code = (Integer)_request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); + _response.setStatus(code != null ? code : HttpStatus.INTERNAL_SERVER_ERROR_500); + + ContextHandler.Context context = (ContextHandler.Context)_request.getAttribute(ErrorHandler.ERROR_CONTEXT); + ErrorHandler errorHandler = ErrorHandler.getErrorHandler(getServer(), context == null ? null : context.getContextHandler()); + + // If we can't have a body, then create a minimal error response. + if (HttpStatus.hasNoBody(_response.getStatus()) || errorHandler == null || !errorHandler.errorPageForMethod(_request.getMethod())) { - _request.setDispatcherType(DispatcherType.ERROR); - notifyBeforeDispatch(_request); - getServer().handle(this); + sendResponseAndComplete(); + break; } - catch (Throwable x) + + dispatch(DispatcherType.ERROR,() -> { - notifyDispatchFailure(_request, x); - throw x; - } - finally - { - notifyAfterDispatch(_request); - _request.setDispatcherType(null); - } + errorHandler.handle(null, _request, _request, _response); + _request.setHandled(true); + }); } catch (Throwable x) { if (LOG.isDebugEnabled()) LOG.debug("Could not perform ERROR dispatch, aborting", x); - Throwable failure = (Throwable)_request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); - if (failure == null) - { - minimalErrorResponse(x); - } + if (_state.isResponseCommitted()) + abort(x); else { - if (x != failure) - failure.addSuppressed(x); - minimalErrorResponse(failure); + _response.resetContent(); + sendResponseAndComplete(); } } + finally + { + // clean up the context that was set in Response.sendError + _request.removeAttribute(ErrorHandler.ERROR_CONTEXT); + } break; } @@ -463,6 +441,12 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor throw _state.getAsyncContextEvent().getThrowable(); } + case READ_REGISTER: + { + onAsyncWaitForContent(); + break; + } + case READ_PRODUCE: { _request.getHttpInput().asyncReadProduce(); @@ -491,51 +475,44 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor case COMPLETE: { - try + if (!_response.isCommitted() && !_request.isHandled() && !_response.getHttpOutput().isClosed()) { - if (!_response.isCommitted() && !_request.isHandled()) - { - _response.sendError(HttpStatus.NOT_FOUND_404); - } - else - { - // RFC 7230, section 3.3. - int status = _response.getStatus(); - boolean hasContent = !(_request.isHead() || - HttpMethod.CONNECT.is(_request.getMethod()) && status == HttpStatus.OK_200 || - HttpStatus.isInformational(status) || - status == HttpStatus.NO_CONTENT_204 || - status == HttpStatus.NOT_MODIFIED_304); - if (hasContent && !_response.isContentComplete(_response.getHttpOutput().getWritten())) - { - if (isCommitted()) - abort(new IOException("insufficient content written")); - else - _response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500, "insufficient content written"); - } - } - _response.closeOutput(); - } - finally - { - _request.setHandled(true); - _state.onComplete(); - onCompleted(); + _response.sendError(HttpStatus.NOT_FOUND_404); + break; } - break loop; + // RFC 7230, section 3.3. + if (!_request.isHead() && + _response.getStatus() != HttpStatus.NOT_MODIFIED_304 && + !_response.isContentComplete(_response.getHttpOutput().getWritten())) + { + if (sendErrorOrAbort("Insufficient content written")) + break; + } + + // If send error is called we need to break. + if (checkAndPrepareUpgrade()) + break; + + // TODO Currently a blocking/aborting consumeAll is done in the handling of the TERMINATED + // TODO Action triggered by the completed callback below. It would be possible to modify the + // TODO callback to do a non-blocking consumeAll at this point and only call completed when + // TODO that is done. + + // Set a close callback on the HttpOutput to make it an async callback + _response.completeOutput(Callback.from(_state::completed)); + + break; } default: - { - throw new IllegalStateException("state=" + _state); - } + throw new IllegalStateException(this.toString()); } } catch (Throwable failure) { if ("org.eclipse.jetty.continuation.ContinuationThrowable".equals(failure.getClass().getName())) - LOG.ignore(failure); + LOG.trace("IGNORED", failure); else handleException(failure); } @@ -544,26 +521,56 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } if (LOG.isDebugEnabled()) - LOG.debug("{} handle exit, result {}", this, action); + LOG.debug("!handle {} {}", action, this); boolean suspended = action == Action.WAIT; return !suspended; } - protected void sendError(int code, String reason) + /** + * @param message the error message. + * @return true if we have sent an error, false if we have aborted. + */ + public boolean sendErrorOrAbort(String message) { try { - _response.sendError(code, reason); + if (isCommitted()) + { + abort(new IOException(message)); + return false; + } + + _response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500, message); + return true; } catch (Throwable x) { - if (LOG.isDebugEnabled()) - LOG.debug("Could not send error " + code + " " + reason, x); + LOG.trace("IGNORED", x); + abort(x); + } + return false; + } + + private void dispatch(DispatcherType type, Dispatchable dispatchable) throws IOException, ServletException + { + try + { + _request.setHandled(false); + _response.reopen(); + _request.setDispatcherType(type); + _combinedListener.onBeforeDispatch(_request); + dispatchable.dispatch(); + } + catch (Throwable x) + { + _combinedListener.onDispatchFailure(_request, x); + throw x; } finally { - _state.errorComplete(); + _combinedListener.onAfterDispatch(_request); + _request.setDispatcherType(null); } } @@ -591,27 +598,19 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor { // No stack trace unless there is debug turned on if (LOG.isDebugEnabled()) - LOG.debug(_request.getRequestURI(), failure); + LOG.warn("handleException " + _request.getRequestURI(), failure); else - LOG.warn("{} {}", _request.getRequestURI(), noStack.toString()); + LOG.warn("handleException {} {}", _request.getRequestURI(), noStack.toString()); } else { LOG.warn(_request.getRequestURI(), failure); } - try - { + if (isCommitted()) + abort(failure); + else _state.onError(failure); - } - catch (Throwable e) - { - if (e != failure) - failure.addSuppressed(e); - LOG.warn("ERROR dispatch failed", failure); - // Try to send a minimal response. - minimalErrorResponse(failure); - } } /** @@ -635,30 +634,17 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor return null; } - private void minimalErrorResponse(Throwable failure) + public void sendResponseAndComplete() { try { - int code = 500; - Integer status = (Integer)_request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); - if (status != null) - code = status.intValue(); - else - { - Throwable cause = unwrap(failure, BadMessageException.class); - if (cause instanceof BadMessageException) - code = ((BadMessageException)cause).getCode(); - } - - _response.reset(true); - _response.setStatus(code); - _response.flushBuffer(); + _request.setHandled(true); + _state.completing(); + sendResponse(null, _response.getHttpOutput().getBuffer(), true, Callback.from(_state::completed)); } catch (Throwable x) { - if (x != failure) - failure.addSuppressed(x); - abort(failure); + abort(x); } } @@ -676,11 +662,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public String toString() { long timeStamp = _request.getTimeStamp(); - return String.format("%s@%x{r=%s,c=%b,c=%b/%b,a=%s,uri=%s,age=%d}", + return String.format("%s@%x{s=%s,r=%s,c=%b/%b,a=%s,uri=%s,age=%d}", getClass().getSimpleName(), hashCode(), + _state, _requests, - _committed.get(), isRequestCompleted(), isResponseCompleted(), _state.getState(), @@ -706,7 +692,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor _request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme())); - notifyRequestBegin(_request); + _combinedListener.onRequestBegin(_request); if (LOG.isDebugEnabled()) LOG.debug("REQUEST for {} on {}{}{} {} {}{}{}", request.getURIString(), this, System.lineSeparator(), @@ -717,40 +703,54 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public boolean onContent(HttpInput.Content content) { if (LOG.isDebugEnabled()) - LOG.debug("{} onContent {}", this, content); - notifyRequestContent(_request, content.getByteBuffer()); + LOG.debug("onContent {} {}", this, content); + _combinedListener.onRequestContent(_request, content.getByteBuffer()); return _request.getHttpInput().addContent(content); } public boolean onContentComplete() { if (LOG.isDebugEnabled()) - LOG.debug("{} onContentComplete", this); - notifyRequestContentEnd(_request); + LOG.debug("onContentComplete {}", this); + _combinedListener.onRequestContentEnd(_request); return false; } public void onTrailers(HttpFields trailers) { if (LOG.isDebugEnabled()) - LOG.debug("{} onTrailers {}", this, trailers); + LOG.debug("onTrailers {} {}", this, trailers); _trailers = trailers; - notifyRequestTrailers(_request); + _combinedListener.onRequestTrailers(_request); } public boolean onRequestComplete() { if (LOG.isDebugEnabled()) - LOG.debug("{} onRequestComplete", this); + LOG.debug("onRequestComplete {}", this); boolean result = _request.getHttpInput().eof(); - notifyRequestEnd(_request); + _combinedListener.onRequestEnd(_request); return result; } + /** + *

      Checks whether the processing of the request resulted in an upgrade, + * and if so performs upgrade preparation steps before the upgrade + * response is sent back to the client.

      + *

      This avoids a race where the server is unprepared if the client sends + * data immediately after having received the upgrade response.

      + * @return true if the channel is not complete and more processing is required, + * typically because sendError has been called. + */ + protected boolean checkAndPrepareUpgrade() + { + return false; + } + public void onCompleted() { if (LOG.isDebugEnabled()) - LOG.debug("COMPLETE for {} written={}", getRequest().getRequestURI(), getBytesWritten()); + LOG.debug("onCompleted for {} written={}", getRequest().getRequestURI(), getBytesWritten()); if (_requestLog != null) _requestLog.log(_request, _response); @@ -759,8 +759,8 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor if (idleTO >= 0 && getIdleTimeout() != _oldIdleTimeout) setIdleTimeout(_oldIdleTimeout); - notifyComplete(_request); - + _request.onCompleted(); + _combinedListener.onComplete(_request); _transport.onCompleted(); } @@ -772,11 +772,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public void onBadMessage(BadMessageException failure) { int status = failure.getCode(); - String message = failure.getReason(); - if (status < 400 || status > 599) - failure = new BadMessageException(HttpStatus.BAD_REQUEST_400, message, failure); + String reason = failure.getReason(); + if (status < HttpStatus.BAD_REQUEST_400 || status > 599) + failure = new BadMessageException(HttpStatus.BAD_REQUEST_400, reason, failure); - notifyRequestFailure(_request, failure); + _combinedListener.onRequestFailure(_request, failure); Action action; try @@ -800,14 +800,14 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor ErrorHandler handler = getServer().getBean(ErrorHandler.class); if (handler != null) - content = handler.badMessageError(status, message, fields); + content = handler.badMessageError(status, reason, fields); sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1, status, null, fields, BufferUtil.length(content)), content, true); } } catch (IOException e) { - LOG.debug(e); + LOG.debug("Unable to send bad message response", e); } finally { @@ -817,19 +817,19 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } catch (Throwable e) { - LOG.debug(e); + LOG.debug("Unable to complete bad message", e); abort(e); } } } - protected boolean sendResponse(MetaData.Response info, ByteBuffer content, boolean complete, final Callback callback) + protected boolean sendResponse(MetaData.Response response, ByteBuffer content, boolean complete, final Callback callback) { - boolean committing = _committed.compareAndSet(false, true); + boolean committing = _state.commitResponse(); if (LOG.isDebugEnabled()) LOG.debug("sendResponse info={} content={} complete={} committing={} callback={}", - info, + response, BufferUtil.toDetailString(content), complete, committing, @@ -838,23 +838,25 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor if (committing) { // We need an info to commit - if (info == null) - info = _response.newResponseMetaData(); - commit(info); - + if (response == null) + response = _response.newResponseMetaData(); + commit(response); + _combinedListener.onResponseBegin(_request); + _request.onResponseCommit(); + // wrap callback to process 100 responses - final int status = info.getStatus(); - final Callback committed = (status < 200 && status >= 100) ? new Send100Callback(callback) : new SendCallback(callback, content, true, complete); - - notifyResponseBegin(_request); + final int status = response.getStatus(); + final Callback committed = (status < HttpStatus.OK_200 && status >= HttpStatus.CONTINUE_100) + ? new Send100Callback(callback) + : new SendCallback(callback, content, true, complete); // committing write - _transport.send(info, _request.isHead(), content, complete, committed); + _transport.send(_request.getMetaData(), response, content, complete, committed); } - else if (info == null) + else if (response == null) { // This is a normal write - _transport.send(null, _request.isHead(), content, complete, new SendCallback(callback, content, false, complete)); + _transport.send(_request.getMetaData(), null, content, complete, new SendCallback(callback, content, false, complete)); } else { @@ -874,7 +876,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor catch (Throwable failure) { if (LOG.isDebugEnabled()) - LOG.debug(failure); + LOG.debug("Unable to send response", failure); abort(failure); throw failure; } @@ -891,7 +893,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public boolean isCommitted() { - return _committed.get(); + return _state.isResponseCommitted(); } /** @@ -907,7 +909,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor */ public boolean isResponseCompleted() { - return _responseCompleted.get(); + return _state.isResponseCompleted(); } public boolean isPersistent() @@ -952,12 +954,9 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor return _connector.getScheduler(); } - /** - * @return true if the HttpChannel can efficiently use direct buffer (typically this means it is not over SSL or a multiplexed protocol) - */ - public boolean useDirectBuffers() + public boolean isUseOutputDirectByteBuffers() { - return getEndPoint() instanceof ChannelEndPoint; + return getHttpConfiguration().isUseOutputDirectByteBuffers(); } /** @@ -970,88 +969,26 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor */ public void abort(Throwable failure) { - notifyResponseFailure(_request, failure); - _transport.abort(failure); + if (_state.abortResponse()) + { + _combinedListener.onResponseFailure(_request, failure); + _transport.abort(failure); + } } - private void notifyRequestBegin(Request request) + public boolean isTunnellingSupported() { - notifyEvent1(listener -> listener::onRequestBegin, request); + return false; } - private void notifyBeforeDispatch(Request request) + public EndPoint getTunnellingEndPoint() { - notifyEvent1(listener -> listener::onBeforeDispatch, request); - } - - private void notifyDispatchFailure(Request request, Throwable failure) - { - notifyEvent2(listener -> listener::onDispatchFailure, request, failure); - } - - private void notifyAfterDispatch(Request request) - { - notifyEvent1(listener -> listener::onAfterDispatch, request); - } - - private void notifyRequestContent(Request request, ByteBuffer content) - { - notifyEvent2(listener -> listener::onRequestContent, request, content); - } - - private void notifyRequestContentEnd(Request request) - { - notifyEvent1(listener -> listener::onRequestContentEnd, request); - } - - private void notifyRequestTrailers(Request request) - { - notifyEvent1(listener -> listener::onRequestTrailers, request); - } - - private void notifyRequestEnd(Request request) - { - notifyEvent1(listener -> listener::onRequestEnd, request); - } - - private void notifyRequestFailure(Request request, Throwable failure) - { - notifyEvent2(listener -> listener::onRequestFailure, request, failure); - } - - private void notifyResponseBegin(Request request) - { - notifyEvent1(listener -> listener::onResponseBegin, request); - } - - private void notifyResponseCommit(Request request) - { - notifyEvent1(listener -> listener::onResponseCommit, request); - } - - private void notifyResponseContent(Request request, ByteBuffer content) - { - notifyEvent2(listener -> listener::onResponseContent, request, content); - } - - private void notifyResponseEnd(Request request) - { - notifyEvent1(listener -> listener::onResponseEnd, request); - } - - private void notifyResponseFailure(Request request, Throwable failure) - { - notifyEvent2(listener -> listener::onResponseFailure, request, failure); - } - - private void notifyComplete(Request request) - { - notifyEvent1(listener -> listener::onComplete, request); + throw new UnsupportedOperationException("Tunnelling not supported"); } private void notifyEvent1(Function> function, Request request) { - for (Listener listener : _listeners) + for (Listener listener : _transientListeners) { try { @@ -1066,7 +1003,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor private void notifyEvent2(Function> function, Request request, ByteBuffer content) { - for (Listener listener : _listeners) + for (Listener listener : _transientListeners) { ByteBuffer view = content.slice(); try @@ -1082,7 +1019,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor private void notifyEvent2(Function> function, Request request, Throwable failure) { - for (Listener listener : _listeners) + for (Listener listener : _transientListeners) { try { @@ -1095,10 +1032,15 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } } + interface Dispatchable + { + void dispatch() throws IOException, ServletException; + } + /** *

      Listener for {@link HttpChannel} events.

      *

      HttpChannel will emit events for the various phases it goes through while - * processing a HTTP request and response.

      + * processing an HTTP request and response.

      *

      Implementations of this interface may listen to those events to track * timing and/or other values such as request URI, etc.

      *

      The events parameters, especially the {@link Request} object, may be @@ -1113,15 +1055,20 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor *

      Listener methods are invoked synchronously from the thread that is * performing the request processing, and they should not call blocking code * (otherwise the request processing will be blocked as well).

      + *

      Listener instances that are set as a bean on the {@link Connector} are + * efficiently added to {@link HttpChannel}. If additional listeners are added + * using the deprecated {@link HttpChannel#addListener(Listener)}

      method, + * then an instance of {@link TransientListeners} must be added to the connector + * in order for them to be invoked. */ - public interface Listener + public interface Listener extends EventListener { /** * Invoked just after the HTTP request line and headers have been parsed. * * @param request the request object */ - public default void onRequestBegin(Request request) + default void onRequestBegin(Request request) { } @@ -1130,7 +1077,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onBeforeDispatch(Request request) + default void onBeforeDispatch(Request request) { } @@ -1140,7 +1087,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * @param request the request object * @param failure the exception thrown by the application */ - public default void onDispatchFailure(Request request, Throwable failure) + default void onDispatchFailure(Request request, Throwable failure) { } @@ -1149,7 +1096,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onAfterDispatch(Request request) + default void onAfterDispatch(Request request) { } @@ -1160,7 +1107,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * @param request the request object * @param content a {@link ByteBuffer#slice() slice} of the request content chunk */ - public default void onRequestContent(Request request, ByteBuffer content) + default void onRequestContent(Request request, ByteBuffer content) { } @@ -1169,7 +1116,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onRequestContentEnd(Request request) + default void onRequestContentEnd(Request request) { } @@ -1178,7 +1125,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onRequestTrailers(Request request) + default void onRequestTrailers(Request request) { } @@ -1187,7 +1134,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onRequestEnd(Request request) + default void onRequestEnd(Request request) { } @@ -1197,7 +1144,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * @param request the request object * @param failure the request failure */ - public default void onRequestFailure(Request request, Throwable failure) + default void onRequestFailure(Request request, Throwable failure) { } @@ -1206,7 +1153,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onResponseBegin(Request request) + default void onResponseBegin(Request request) { } @@ -1217,7 +1164,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onResponseCommit(Request request) + default void onResponseCommit(Request request) { } @@ -1227,7 +1174,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * @param request the request object * @param content a {@link ByteBuffer#slice() slice} of the response content chunk */ - public default void onResponseContent(Request request, ByteBuffer content) + default void onResponseContent(Request request, ByteBuffer content) { } @@ -1236,7 +1183,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onResponseEnd(Request request) + default void onResponseEnd(Request request) { } @@ -1246,7 +1193,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * @param request the request object * @param failure the response failure */ - public default void onResponseFailure(Request request, Throwable failure) + default void onResponseFailure(Request request, Throwable failure) { } @@ -1255,7 +1202,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor * * @param request the request object */ - public default void onComplete(Request request) + default void onComplete(Request request) { } } @@ -1280,16 +1227,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor public void succeeded() { _written += _length; - super.succeeded(); if (_commit) - notifyResponseCommit(_request); + _combinedListener.onResponseCommit(_request); if (_length > 0) - notifyResponseContent(_request, _content); - if (_complete) - { - _responseCompleted.set(true); - notifyResponseEnd(_request); - } + _combinedListener.onResponseContent(_request, _content); + if (_complete && _state.completeResponse()) + _combinedListener.onResponseEnd(_request); + super.succeeded(); } @Override @@ -1300,13 +1244,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor if (x instanceof BadMessageException) { - _transport.send(HttpGenerator.RESPONSE_500_INFO, false, null, true, new Callback.Nested(this) + _transport.send(_request.getMetaData(), HttpGenerator.RESPONSE_500_INFO, null, true, new Callback.Nested(this) { @Override public void succeeded() { + _response.getHttpOutput().completed(); super.failed(x); - _response.getHttpOutput().closed(); } @Override @@ -1335,10 +1279,108 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor @Override public void succeeded() { - if (_committed.compareAndSet(true, false)) + if (_state.partialResponse()) super.succeeded(); else super.failed(new IllegalStateException()); } } + + /** + * A Listener instance that can be added as a bean to {@link AbstractConnector} so that + * the listeners obtained from HttpChannel{@link #getTransientListeners()} + */ + @Deprecated + public static class TransientListeners implements Listener + { + @Override + public void onRequestBegin(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onRequestBegin, request); + } + + @Override + public void onBeforeDispatch(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onBeforeDispatch, request); + } + + @Override + public void onDispatchFailure(Request request, Throwable failure) + { + request.getHttpChannel().notifyEvent2(listener -> listener::onDispatchFailure, request, failure); + } + + @Override + public void onAfterDispatch(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onAfterDispatch, request); + } + + @Override + public void onRequestContent(Request request, ByteBuffer content) + { + request.getHttpChannel().notifyEvent2(listener -> listener::onRequestContent, request, content); + } + + @Override + public void onRequestContentEnd(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onRequestContentEnd, request); + } + + @Override + public void onRequestTrailers(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onRequestTrailers, request); + } + + @Override + public void onRequestEnd(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onRequestEnd, request); + } + + @Override + public void onRequestFailure(Request request, Throwable failure) + { + request.getHttpChannel().notifyEvent2(listener -> listener::onRequestFailure, request, failure); + } + + @Override + public void onResponseBegin(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onResponseBegin, request); + } + + @Override + public void onResponseCommit(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onResponseCommit, request); + } + + @Override + public void onResponseContent(Request request, ByteBuffer content) + { + request.getHttpChannel().notifyEvent2(listener -> listener::onResponseContent, request, content); + } + + @Override + public void onResponseEnd(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onResponseEnd, request); + } + + @Override + public void onResponseFailure(Request request, Throwable failure) + { + request.getHttpChannel().notifyEvent2(listener -> listener::onResponseFailure, request, failure); + } + + @Override + public void onComplete(Request request) + { + request.getHttpChannel().notifyEvent1(listener -> listener::onComplete, request); + } + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelListeners.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelListeners.java new file mode 100644 index 00000000000..f380ab54e56 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelListeners.java @@ -0,0 +1,286 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import java.nio.ByteBuffer; +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link HttpChannel.Listener} that holds a collection of + * other {@link HttpChannel.Listener} instances that are efficiently + * invoked without iteration. + * @see AbstractConnector + */ +public class HttpChannelListeners implements HttpChannel.Listener +{ + static final Logger LOG = LoggerFactory.getLogger(HttpChannel.class); + public static HttpChannel.Listener NOOP = new HttpChannel.Listener() {}; + + private final NotifyRequest onRequestBegin; + private final NotifyRequest onBeforeDispatch; + private final NotifyFailure onDispatchFailure; + private final NotifyRequest onAfterDispatch; + private final NotifyContent onRequestContent; + private final NotifyRequest onRequestContentEnd; + private final NotifyRequest onRequestTrailers; + private final NotifyRequest onRequestEnd; + private final NotifyFailure onRequestFailure; + private final NotifyRequest onResponseBegin; + private final NotifyRequest onResponseCommit; + private final NotifyContent onResponseContent; + private final NotifyRequest onResponseEnd; + private final NotifyFailure onResponseFailure; + private final NotifyRequest onComplete; + + public HttpChannelListeners(Collection listeners) + { + try + { + NotifyRequest onRequestBegin = NotifyRequest.NOOP; + NotifyRequest onBeforeDispatch = NotifyRequest.NOOP; + NotifyFailure onDispatchFailure = NotifyFailure.NOOP; + NotifyRequest onAfterDispatch = NotifyRequest.NOOP; + NotifyContent onRequestContent = NotifyContent.NOOP; + NotifyRequest onRequestContentEnd = NotifyRequest.NOOP; + NotifyRequest onRequestTrailers = NotifyRequest.NOOP; + NotifyRequest onRequestEnd = NotifyRequest.NOOP; + NotifyFailure onRequestFailure = NotifyFailure.NOOP; + NotifyRequest onResponseBegin = NotifyRequest.NOOP; + NotifyRequest onResponseCommit = NotifyRequest.NOOP; + NotifyContent onResponseContent = NotifyContent.NOOP; + NotifyRequest onResponseEnd = NotifyRequest.NOOP; + NotifyFailure onResponseFailure = NotifyFailure.NOOP; + NotifyRequest onComplete = NotifyRequest.NOOP; + + for (HttpChannel.Listener listener : listeners) + { + if (!listener.getClass().getMethod("onRequestBegin", Request.class).isDefault()) + onRequestBegin = combine(onRequestBegin, listener::onRequestBegin); + if (!listener.getClass().getMethod("onBeforeDispatch", Request.class).isDefault()) + onBeforeDispatch = combine(onBeforeDispatch, listener::onBeforeDispatch); + if (!listener.getClass().getMethod("onDispatchFailure", Request.class, Throwable.class).isDefault()) + onDispatchFailure = combine(onDispatchFailure, listener::onDispatchFailure); + if (!listener.getClass().getMethod("onAfterDispatch", Request.class).isDefault()) + onAfterDispatch = combine(onAfterDispatch, listener::onAfterDispatch); + if (!listener.getClass().getMethod("onRequestContent", Request.class, ByteBuffer.class).isDefault()) + onRequestContent = combine(onRequestContent, listener::onRequestContent); + if (!listener.getClass().getMethod("onRequestContentEnd", Request.class).isDefault()) + onRequestContentEnd = combine(onRequestContentEnd, listener::onRequestContentEnd); + if (!listener.getClass().getMethod("onRequestTrailers", Request.class).isDefault()) + onRequestTrailers = combine(onRequestTrailers, listener::onRequestTrailers); + if (!listener.getClass().getMethod("onRequestEnd", Request.class).isDefault()) + onRequestEnd = combine(onRequestEnd, listener::onRequestEnd); + if (!listener.getClass().getMethod("onRequestFailure", Request.class, Throwable.class).isDefault()) + onRequestFailure = combine(onRequestFailure, listener::onRequestFailure); + if (!listener.getClass().getMethod("onResponseBegin", Request.class).isDefault()) + onResponseBegin = combine(onResponseBegin, listener::onResponseBegin); + if (!listener.getClass().getMethod("onResponseCommit", Request.class).isDefault()) + onResponseCommit = combine(onResponseCommit, listener::onResponseCommit); + if (!listener.getClass().getMethod("onResponseContent", Request.class, ByteBuffer.class).isDefault()) + onResponseContent = combine(onResponseContent, listener::onResponseContent); + if (!listener.getClass().getMethod("onResponseEnd", Request.class).isDefault()) + onResponseEnd = combine(onResponseEnd, listener::onResponseEnd); + if (!listener.getClass().getMethod("onResponseFailure", Request.class, Throwable.class).isDefault()) + onResponseFailure = combine(onResponseFailure, listener::onResponseFailure); + if (!listener.getClass().getMethod("onComplete", Request.class).isDefault()) + onComplete = combine(onComplete, listener::onComplete); + } + + this.onRequestBegin = onRequestBegin; + this.onBeforeDispatch = onBeforeDispatch; + this.onDispatchFailure = onDispatchFailure; + this.onAfterDispatch = onAfterDispatch; + this.onRequestContent = onRequestContent; + this.onRequestContentEnd = onRequestContentEnd; + this.onRequestTrailers = onRequestTrailers; + this.onRequestEnd = onRequestEnd; + this.onRequestFailure = onRequestFailure; + this.onResponseBegin = onResponseBegin; + this.onResponseCommit = onResponseCommit; + this.onResponseContent = onResponseContent; + this.onResponseEnd = onResponseEnd; + this.onResponseFailure = onResponseFailure; + this.onComplete = onComplete; + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + @Override + public void onRequestBegin(Request request) + { + onRequestBegin.onRequest(request); + } + + @Override + public void onBeforeDispatch(Request request) + { + onBeforeDispatch.onRequest(request); + } + + @Override + public void onDispatchFailure(Request request, Throwable failure) + { + onDispatchFailure.onFailure(request, failure); + } + + @Override + public void onAfterDispatch(Request request) + { + onAfterDispatch.onRequest(request); + } + + @Override + public void onRequestContent(Request request, ByteBuffer content) + { + onRequestContent.onContent(request, content); + } + + @Override + public void onRequestContentEnd(Request request) + { + onRequestContentEnd.onRequest(request); + } + + @Override + public void onRequestTrailers(Request request) + { + onRequestTrailers.onRequest(request); + } + + @Override + public void onRequestEnd(Request request) + { + onRequestEnd.onRequest(request); + } + + @Override + public void onRequestFailure(Request request, Throwable failure) + { + onRequestFailure.onFailure(request, failure); + } + + @Override + public void onResponseBegin(Request request) + { + onResponseBegin.onRequest(request); + } + + @Override + public void onResponseCommit(Request request) + { + onResponseCommit.onRequest(request); + } + + @Override + public void onResponseContent(Request request, ByteBuffer content) + { + onResponseContent.onContent(request, content); + } + + @Override + public void onResponseEnd(Request request) + { + onResponseEnd.onRequest(request); + } + + @Override + public void onResponseFailure(Request request, Throwable failure) + { + onResponseFailure.onFailure(request, failure); + } + + @Override + public void onComplete(Request request) + { + onComplete.onRequest(request); + } + + private interface NotifyRequest + { + void onRequest(Request request); + + NotifyRequest NOOP = request -> + { + }; + } + + private interface NotifyFailure + { + void onFailure(Request request, Throwable failure); + + NotifyFailure NOOP = (request, failure) -> + { + }; + } + + private interface NotifyContent + { + void onContent(Request request, ByteBuffer content); + + NotifyContent NOOP = (request, content) -> + { + }; + } + + private static NotifyRequest combine(NotifyRequest first, NotifyRequest second) + { + if (first == NotifyRequest.NOOP) + return second; + if (second == NotifyRequest.NOOP) + return first; + return request -> + { + first.onRequest(request); + second.onRequest(request); + }; + } + + private static NotifyFailure combine(NotifyFailure first, NotifyFailure second) + { + if (first == NotifyFailure.NOOP) + return second; + if (second == NotifyFailure.NOOP) + return first; + return (request, throwable) -> + { + first.onFailure(request, throwable); + second.onFailure(request, throwable); + }; + } + + private static NotifyContent combine(NotifyContent first, NotifyContent second) + { + if (first == NotifyContent.NOOP) + return (request, content) -> second.onContent(request, content.slice()); + if (second == NotifyContent.NOOP) + return (request, content) -> first.onContent(request, content.slice()); + return (request, content) -> + { + content = content.slice(); + first.onContent(request, content); + second.onContent(request, content); + }; + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index 24d3d94328d..1994f27288b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -40,15 +40,15 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * A HttpChannel customized to be transported over the HTTP/1 protocol + * An HttpChannel customized to be transported over the HTTP/1 protocol */ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandler, ComplianceViolation.Listener { - private static final Logger LOG = Log.getLogger(HttpChannelOverHttp.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpChannelOverHttp.class); private static final HttpField PREAMBLE_UPGRADE_H2C = new HttpField(HttpHeader.UPGRADE, "h2c"); private final HttpFields _fields = new HttpFields(); private final MetaData.Request _metadata = new MetaData.Request(_fields); @@ -69,6 +69,12 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque _metadata.setURI(new HttpURI()); } + @Override + public boolean isUseOutputDirectByteBuffers() + { + return _httpConnection.isUseOutputDirectByteBuffers(); + } + @Override protected HttpInput newHttpInput(HttpChannelState state) { @@ -102,7 +108,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque } @Override - public boolean startRequest(String method, String uri, HttpVersion version) + public void startRequest(String method, String uri, HttpVersion version) { _metadata.setMethod(method); _metadata.getURI().parseRequestTarget(method, uri); @@ -110,7 +116,6 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque _unknownExpectation = false; _expect100Continue = false; _expect102Processing = false; - return false; } @Override @@ -229,7 +234,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque if (_metadata.getMethod() == null) _httpConnection.close(); else if (onEarlyEOF() || _delayedForContent) - { + { _delayedForContent = false; handle(); } @@ -274,7 +279,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } onBadMessage(failure); @@ -283,6 +288,8 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque @Override public boolean headerComplete() { + onRequest(_metadata); + if (_complianceViolations != null && !_complianceViolations.isEmpty()) { this.getRequest().setAttribute(HttpCompliance.VIOLATIONS_ATTR, _complianceViolations); @@ -363,9 +370,9 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque _upgrade = PREAMBLE_UPGRADE_H2C; if (HttpMethod.PRI.is(_metadata.getMethod()) && - "*".equals(_metadata.getURI().toString()) && - _fields.size() == 0 && - upgrade()) + "*".equals(_metadata.getURI().getPath()) && + _fields.size() == 0 && + upgrade()) return true; badMessage(new BadMessageException(HttpStatus.UPGRADE_REQUIRED_426)); @@ -382,8 +389,6 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque if (!persistent) _httpConnection.getGenerator().setPersistent(false); - onRequest(_metadata); - // Should we delay dispatch until we have some content? // We should not delay if there is no content expect or client is expecting 100 or the response is already committed or the request buffer already has something in it to parse _delayedForContent = (getHttpConfiguration().isDelayDispatchUntilContent() && @@ -407,8 +412,15 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque return true; } + @Override + protected boolean checkAndPrepareUpgrade() + { + // TODO: move the code from HttpConnection.upgrade() here? + return false; + } + /** - *

      Attempts to perform a HTTP/1.1 upgrade.

      + *

      Attempts to perform an HTTP/1.1 upgrade.

      *

      The upgrade looks up a {@link ConnectionFactory.Upgrading} from the connector * matching the protocol specified in the {@code Upgrade} header.

      *

      The upgrade may succeed, be ignored (which can allow a later handler to implement) @@ -429,18 +441,12 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque throw new BadMessageException(HttpStatus.BAD_REQUEST_400); // Find the upgrade factory - ConnectionFactory.Upgrading factory = null; - for (ConnectionFactory f : getConnector().getConnectionFactories()) - { - if (f instanceof ConnectionFactory.Upgrading) - { - if (f.getProtocols().contains(_upgrade.getValue())) - { - factory = (ConnectionFactory.Upgrading)f; - break; - } - } - } + ConnectionFactory.Upgrading factory = getConnector().getConnectionFactories().stream() + .filter(f -> f instanceof ConnectionFactory.Upgrading) + .map(ConnectionFactory.Upgrading.class::cast) + .filter(f -> f.getProtocols().contains(_upgrade.getValue())) + .findAny() + .orElse(null); if (factory == null) { @@ -472,8 +478,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque if (LOG.isDebugEnabled()) LOG.debug("Upgrade from {} to {}", getEndPoint().getConnection(), upgradeConnection); - getRequest().setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, upgradeConnection); - getResponse().setStatus(101); + getRequest().setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, upgradeConnection); getHttpTransport().onCompleted(); return true; } @@ -508,18 +513,6 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque return onRequestComplete(); } - @Override - public int getHeaderCacheSize() - { - return getHttpConfiguration().getHeaderCacheSize(); - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - return getHttpConfiguration().isHeaderCacheCaseSensitive(); - } - @Override public void onComplianceViolation(ComplianceViolation.Mode mode, ComplianceViolation violation, String details) { @@ -530,10 +523,22 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque _complianceViolations = new ArrayList<>(); } String record = String.format("%s (see %s) in mode %s for %s in %s", - violation.getDescription(), violation.getURL(), mode, details, getHttpTransport()); + violation.getDescription(), violation.getURL(), mode, details, getHttpTransport()); _complianceViolations.add(record); if (LOG.isDebugEnabled()) LOG.debug(record); } } + + @Override + public boolean isTunnellingSupported() + { + return true; + } + + @Override + public EndPoint getTunnellingEndPoint() + { + return getEndPoint(); + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index 75e37a8763a..0871e53b14b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -21,25 +21,26 @@ package org.eclipse.jetty.server; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import javax.servlet.AsyncListener; -import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletResponse; import javax.servlet.UnavailableException; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.QuietException; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Locker; +import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static javax.servlet.RequestDispatcher.ERROR_EXCEPTION; import static javax.servlet.RequestDispatcher.ERROR_EXCEPTION_TYPE; import static javax.servlet.RequestDispatcher.ERROR_MESSAGE; +import static javax.servlet.RequestDispatcher.ERROR_REQUEST_URI; +import static javax.servlet.RequestDispatcher.ERROR_SERVLET_NAME; import static javax.servlet.RequestDispatcher.ERROR_STATUS_CODE; /** @@ -47,25 +48,81 @@ import static javax.servlet.RequestDispatcher.ERROR_STATUS_CODE; */ public class HttpChannelState { - private static final Logger LOG = Log.getLogger(HttpChannelState.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpChannelState.class); private static final long DEFAULT_TIMEOUT = Long.getLong("org.eclipse.jetty.server.HttpChannelState.DEFAULT_TIMEOUT", 30000L); - /** + /* * The state of the HttpChannel,used to control the overall lifecycle. + *

      +     *     IDLE <-----> HANDLING ----> WAITING
      +     *       |                 ^       /
      +     *       |                  \     /
      +     *       v                   \   v
      +     *    UPGRADED               WOKEN
      +     * 
      */ public enum State { - IDLE, // Idle request - DISPATCHED, // Request dispatched to filter/servlet - THROWN, // Exception thrown while DISPATCHED - ASYNC_WAIT, // Suspended and waiting - ASYNC_WOKEN, // Dispatch to handle from ASYNC_WAIT - ASYNC_IO, // Dispatched for async IO - ASYNC_ERROR, // Async error from ASYNC_WAIT - COMPLETING, // Response is completable - COMPLETED, // Response is completed - UPGRADED // Request upgraded the connection + IDLE, // Idle request + HANDLING, // Request dispatched to filter/servlet or Async IO callback + WAITING, // Suspended and waiting + WOKEN, // Dispatch to handle from ASYNC_WAIT + UPGRADED // Request upgraded the connection + } + + /* + * The state of the request processing lifecycle. + *
      +     *       BLOCKING <----> COMPLETING ---> COMPLETED
      +     *       ^  |  ^            ^
      +     *      /   |   \           |
      +     *     |    |    DISPATCH   |
      +     *     |    |    ^  ^       |
      +     *     |    v   /   |       |
      +     *     |  ASYNC -------> COMPLETE
      +     *     |    |       |       ^
      +     *     |    v       |       |
      +     *     |  EXPIRE    |       |
      +     *      \   |      /        |
      +     *       \  v     /         |
      +     *       EXPIRING ----------+
      +     * 
      + */ + private enum RequestState + { + BLOCKING, // Blocking request dispatched + ASYNC, // AsyncContext.startAsync() has been called + DISPATCH, // AsyncContext.dispatch() has been called + EXPIRE, // AsyncContext timeout has happened + EXPIRING, // AsyncListeners are being called + COMPLETE, // AsyncContext.complete() has been called + COMPLETING, // Request is being closed (maybe asynchronously) + COMPLETED // Response is completed + } + + /* + * The input readiness state, which works together with {@link HttpInput.State} + */ + private enum InputState + { + IDLE, // No isReady; No data + REGISTER, // isReady()==false handling; No data + REGISTERED, // isReady()==false !handling; No data + POSSIBLE, // isReady()==false async read callback called (http/1 only) + PRODUCING, // isReady()==false READ_PRODUCE action is being handled (http/1 only) + READY // isReady() was false, onContentAdded has been called + } + + /* + * The output committed state, which works together with {@link HttpOutput.State} + */ + private enum OutputState + { + OPEN, + COMMITTED, + COMPLETED, + ABORTED, } /** @@ -73,51 +130,28 @@ public class HttpChannelState */ public enum Action { - NOOP, // No action DISPATCH, // handle a normal request dispatch ASYNC_DISPATCH, // handle an async request dispatch - ERROR_DISPATCH, // handle a normal error + SEND_ERROR, // Generate an error page or error dispatch ASYNC_ERROR, // handle an async error + ASYNC_TIMEOUT, // call asyncContext onTimeout WRITE_CALLBACK, // handle an IO write callback + READ_REGISTER, // Register for fill interest READ_PRODUCE, // Check is a read is possible by parsing/filling READ_CALLBACK, // handle an IO read callback - COMPLETE, // Complete the response + COMPLETE, // Complete the response by closing output TERMINATED, // No further actions WAIT, // Wait for further events } - /** - * The state of the servlet async API. - */ - private enum Async - { - NOT_ASYNC, - STARTED, // AsyncContext.startAsync() has been called - DISPATCH, // AsyncContext.dispatch() has been called - COMPLETE, // AsyncContext.complete() has been called - EXPIRING, // AsyncContext timeout just happened - EXPIRED, // AsyncContext timeout has been processed - ERRORING, // An error just happened - ERRORED // The error has been processed - } - - private enum AsyncRead - { - IDLE, // No isReady; No data - REGISTER, // isReady()==false handling; No data - REGISTERED, // isReady()==false !handling; No data - POSSIBLE, // isReady()==false async read callback called (http/1 only) - PRODUCING, // isReady()==false READ_PRODUCE action is being handled (http/1 only) - READY // isReady() was false, onContentAdded has been called - } - - private final Locker _locker = new Locker(); private final HttpChannel _channel; private List _asyncListeners; - private State _state; - private Async _async; - private boolean _initial; - private AsyncRead _asyncRead = AsyncRead.IDLE; + private State _state = State.IDLE; + private RequestState _requestState = RequestState.BLOCKING; + private OutputState _outputState = OutputState.OPEN; + private InputState _inputState = InputState.IDLE; + private boolean _initial = true; + private boolean _sendError; private boolean _asyncWritePossible; private long _timeoutMs = DEFAULT_TIMEOUT; private AsyncContextEvent _event; @@ -125,14 +159,11 @@ public class HttpChannelState protected HttpChannelState(HttpChannel channel) { _channel = channel; - _state = State.IDLE; - _async = Async.NOT_ASYNC; - _initial = true; } public State getState() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return _state; } @@ -140,7 +171,7 @@ public class HttpChannelState public void addListener(AsyncListener listener) { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (_asyncListeners == null) _asyncListeners = new ArrayList<>(); @@ -150,7 +181,7 @@ public class HttpChannelState public boolean hasListener(AsyncListener listener) { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (_asyncListeners == null) return false; @@ -167,9 +198,17 @@ public class HttpChannelState } } + public boolean isSendError() + { + synchronized (this) + { + return _sendError; + } + } + public void setTimeout(long ms) { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { _timeoutMs = ms; } @@ -177,7 +216,7 @@ public class HttpChannelState public long getTimeout() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return _timeoutMs; } @@ -185,7 +224,7 @@ public class HttpChannelState public AsyncContextEvent getAsyncContextEvent() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return _event; } @@ -194,43 +233,139 @@ public class HttpChannelState @Override public String toString() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return toStringLocked(); } } - public String toStringLocked() + private String toStringLocked() { - return String.format("%s@%x{s=%s a=%s i=%b r=%s w=%b}", + return String.format("%s@%x{%s}", getClass().getSimpleName(), hashCode(), - _state, - _async, - _initial, - _asyncRead, - _asyncWritePossible); + getStatusStringLocked()); } private String getStatusStringLocked() { - return String.format("s=%s i=%b a=%s", _state, _initial, _async); + return String.format("s=%s rs=%s os=%s is=%s awp=%b se=%b i=%b al=%d", + _state, + _requestState, + _outputState, + _inputState, + _asyncWritePossible, + _sendError, + _initial, + _asyncListeners == null ? 0 : _asyncListeners.size()); } public String getStatusString() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return getStatusStringLocked(); } } + public boolean commitResponse() + { + synchronized (this) + { + switch (_outputState) + { + case OPEN: + _outputState = OutputState.COMMITTED; + return true; + + default: + return false; + } + } + } + + public boolean partialResponse() + { + synchronized (this) + { + switch (_outputState) + { + case COMMITTED: + _outputState = OutputState.OPEN; + return true; + + default: + return false; + } + } + } + + public boolean completeResponse() + { + synchronized (this) + { + switch (_outputState) + { + case OPEN: + case COMMITTED: + _outputState = OutputState.COMPLETED; + return true; + + default: + return false; + } + } + } + + public boolean isResponseCommitted() + { + synchronized (this) + { + switch (_outputState) + { + case OPEN: + return false; + default: + return true; + } + } + } + + public boolean isResponseCompleted() + { + synchronized (this) + { + return _outputState == OutputState.COMPLETED; + } + } + + public boolean abortResponse() + { + synchronized (this) + { + switch (_outputState) + { + case ABORTED: + return false; + + case OPEN: + _channel.getResponse().setStatus(500); + _outputState = OutputState.ABORTED; + return true; + + default: + _outputState = OutputState.ABORTED; + return true; + } + } + } + /** * @return Next handling of the request should proceed */ - protected Action handling() + public Action handling() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("handling {}", toStringLocked()); @@ -238,90 +373,167 @@ public class HttpChannelState switch (_state) { case IDLE: + if (_requestState != RequestState.BLOCKING) + throw new IllegalStateException(getStatusStringLocked()); _initial = true; - _state = State.DISPATCHED; + _state = State.HANDLING; return Action.DISPATCH; - case COMPLETING: - case COMPLETED: - return Action.TERMINATED; - - case ASYNC_WOKEN: - switch (_asyncRead) + case WOKEN: + if (_event != null && _event.getThrowable() != null && !_sendError) { - case POSSIBLE: - _state = State.ASYNC_IO; - _asyncRead = AsyncRead.PRODUCING; - return Action.READ_PRODUCE; - case READY: - _state = State.ASYNC_IO; - _asyncRead = AsyncRead.IDLE; - return Action.READ_CALLBACK; - case REGISTER: - case PRODUCING: - case IDLE: - case REGISTERED: - break; - default: - throw new IllegalStateException(getStatusStringLocked()); + _state = State.HANDLING; + return Action.ASYNC_ERROR; } - if (_asyncWritePossible) - { - _state = State.ASYNC_IO; - _asyncWritePossible = false; - return Action.WRITE_CALLBACK; - } + Action action = nextAction(true); + if (LOG.isDebugEnabled()) + LOG.debug("nextAction(true) {} {}", action, toStringLocked()); + return action; - switch (_async) - { - case COMPLETE: - _state = State.COMPLETING; - return Action.COMPLETE; - case DISPATCH: - _state = State.DISPATCHED; - _async = Async.NOT_ASYNC; - return Action.ASYNC_DISPATCH; - case EXPIRED: - case ERRORED: - _state = State.DISPATCHED; - _async = Async.NOT_ASYNC; - return Action.ERROR_DISPATCH; - case STARTED: - case EXPIRING: - case ERRORING: - _state = State.ASYNC_WAIT; - return Action.NOOP; - case NOT_ASYNC: - default: - throw new IllegalStateException(getStatusStringLocked()); - } - - case ASYNC_ERROR: - return Action.ASYNC_ERROR; - - case ASYNC_IO: - case ASYNC_WAIT: - case DISPATCHED: - case UPGRADED: default: throw new IllegalStateException(getStatusStringLocked()); } } } + /** + * Signal that the HttpConnection has finished handling the request. + * For blocking connectors, this call may block if the request has + * been suspended (startAsync called). + * + * @return next actions + * be handled again (eg because of a resume that happened before unhandle was called) + */ + protected Action unhandle() + { + synchronized (this) + { + if (LOG.isDebugEnabled()) + LOG.debug("unhandle {}", toStringLocked()); + + if (_state != State.HANDLING) + throw new IllegalStateException(this.getStatusStringLocked()); + + _initial = false; + + Action action = nextAction(false); + if (LOG.isDebugEnabled()) + LOG.debug("nextAction(false) {} {}", action, toStringLocked()); + return action; + } + } + + private Action nextAction(boolean handling) + { + // Assume we can keep going, but exceptions are below + _state = State.HANDLING; + + if (_sendError) + { + switch (_requestState) + { + case BLOCKING: + case ASYNC: + case COMPLETE: + case DISPATCH: + case COMPLETING: + _requestState = RequestState.BLOCKING; + _sendError = false; + return Action.SEND_ERROR; + + default: + break; + } + } + + switch (_requestState) + { + case BLOCKING: + if (handling) + throw new IllegalStateException(getStatusStringLocked()); + _requestState = RequestState.COMPLETING; + return Action.COMPLETE; + + case ASYNC: + switch (_inputState) + { + case POSSIBLE: + _inputState = InputState.PRODUCING; + return Action.READ_PRODUCE; + case READY: + _inputState = InputState.IDLE; + return Action.READ_CALLBACK; + case REGISTER: + case PRODUCING: + _inputState = InputState.REGISTERED; + return Action.READ_REGISTER; + case IDLE: + case REGISTERED: + break; + + default: + throw new IllegalStateException(getStatusStringLocked()); + } + + if (_asyncWritePossible) + { + _asyncWritePossible = false; + return Action.WRITE_CALLBACK; + } + + Scheduler scheduler = _channel.getScheduler(); + if (scheduler != null && _timeoutMs > 0 && !_event.hasTimeoutTask()) + _event.setTimeoutTask(scheduler.schedule(_event, _timeoutMs, TimeUnit.MILLISECONDS)); + _state = State.WAITING; + return Action.WAIT; + + case DISPATCH: + _requestState = RequestState.BLOCKING; + return Action.ASYNC_DISPATCH; + + case EXPIRE: + _requestState = RequestState.EXPIRING; + return Action.ASYNC_TIMEOUT; + + case EXPIRING: + if (handling) + throw new IllegalStateException(getStatusStringLocked()); + sendError(HttpStatus.INTERNAL_SERVER_ERROR_500, "AsyncContext timeout"); + // handle sendError immediately + _requestState = RequestState.BLOCKING; + _sendError = false; + return Action.SEND_ERROR; + + case COMPLETE: + _requestState = RequestState.COMPLETING; + return Action.COMPLETE; + + case COMPLETING: + _state = State.WAITING; + return Action.WAIT; + + case COMPLETED: + _state = State.IDLE; + return Action.TERMINATED; + + default: + throw new IllegalStateException(getStatusStringLocked()); + } + } + public void startAsync(AsyncContextEvent event) { final List lastAsyncListeners; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("startAsync {}", toStringLocked()); - if (_state != State.DISPATCHED || _async != Async.NOT_ASYNC) + if (_state != State.HANDLING || _requestState != RequestState.BLOCKING) throw new IllegalStateException(this.getStatusStringLocked()); - _async = Async.STARTED; + _requestState = RequestState.ASYNC; _event = event; lastAsyncListeners = _asyncListeners; _asyncListeners = null; @@ -343,7 +555,7 @@ public class HttpChannelState catch (Throwable e) { // TODO Async Dispatch Error - LOG.warn(e); + LOG.warn("Async dispatch error", e); } } } @@ -359,219 +571,36 @@ public class HttpChannelState } } - public void asyncError(Throwable failure) - { - AsyncContextEvent event = null; - try (Locker.Lock lock = _locker.lock()) - { - switch (_state) - { - case IDLE: - case DISPATCHED: - case COMPLETING: - case COMPLETED: - case UPGRADED: - case ASYNC_IO: - case ASYNC_WOKEN: - case ASYNC_ERROR: - { - break; - } - case ASYNC_WAIT: - { - _event.addThrowable(failure); - _state = State.ASYNC_ERROR; - event = _event; - break; - } - default: - { - throw new IllegalStateException(getStatusStringLocked()); - } - } - } - - if (event != null) - { - cancelTimeout(event); - runInContext(event, _channel); - } - } - - /** - * Signal that the HttpConnection has finished handling the request. - * For blocking connectors, this call may block if the request has - * been suspended (startAsync called). - * - * @return next actions - * be handled again (eg because of a resume that happened before unhandle was called) - */ - protected Action unhandle() - { - boolean readInterested = false; - - try (Locker.Lock lock = _locker.lock()) - { - if (LOG.isDebugEnabled()) - LOG.debug("unhandle {}", toStringLocked()); - - switch (_state) - { - case COMPLETING: - case COMPLETED: - return Action.TERMINATED; - - case THROWN: - _state = State.DISPATCHED; - return Action.ERROR_DISPATCH; - - case DISPATCHED: - case ASYNC_IO: - case ASYNC_ERROR: - case ASYNC_WAIT: - break; - - default: - throw new IllegalStateException(this.getStatusStringLocked()); - } - - _initial = false; - switch (_async) - { - case COMPLETE: - _state = State.COMPLETING; - _async = Async.NOT_ASYNC; - return Action.COMPLETE; - - case DISPATCH: - _state = State.DISPATCHED; - _async = Async.NOT_ASYNC; - return Action.ASYNC_DISPATCH; - - case STARTED: - switch (_asyncRead) - { - case READY: - _state = State.ASYNC_IO; - _asyncRead = AsyncRead.IDLE; - return Action.READ_CALLBACK; - - case POSSIBLE: - _state = State.ASYNC_IO; - _asyncRead = AsyncRead.PRODUCING; - return Action.READ_PRODUCE; - - case REGISTER: - case PRODUCING: - _asyncRead = AsyncRead.REGISTERED; - readInterested = true; - break; - - case IDLE: - case REGISTERED: - break; - - default: - throw new IllegalStateException(_asyncRead.toString()); - } - - if (_asyncWritePossible) - { - _state = State.ASYNC_IO; - _asyncWritePossible = false; - return Action.WRITE_CALLBACK; - } - else - { - _state = State.ASYNC_WAIT; - - Scheduler scheduler = _channel.getScheduler(); - if (scheduler != null && _timeoutMs > 0 && !_event.hasTimeoutTask()) - _event.setTimeoutTask(scheduler.schedule(_event, _timeoutMs, TimeUnit.MILLISECONDS)); - - return Action.WAIT; - } - - case EXPIRING: - // onTimeout callbacks still being called, so just WAIT - _state = State.ASYNC_WAIT; - return Action.WAIT; - - case EXPIRED: - // onTimeout handling is complete, but did not dispatch as - // we were handling. So do the error dispatch here - _state = State.DISPATCHED; - _async = Async.NOT_ASYNC; - return Action.ERROR_DISPATCH; - - case ERRORED: - _state = State.DISPATCHED; - _async = Async.NOT_ASYNC; - return Action.ERROR_DISPATCH; - - case NOT_ASYNC: - _state = State.COMPLETING; - return Action.COMPLETE; - - default: - _state = State.COMPLETING; - return Action.COMPLETE; - } - } - finally - { - if (readInterested) - _channel.onAsyncWaitForContent(); - } - } - public void dispatch(ServletContext context, String path) { boolean dispatch = false; AsyncContextEvent event; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("dispatch {} -> {}", toStringLocked(), path); - boolean started = false; - event = _event; - switch (_async) + switch (_requestState) { - case STARTED: - started = true; - break; + case ASYNC: case EXPIRING: - case ERRORING: - case ERRORED: break; default: throw new IllegalStateException(this.getStatusStringLocked()); } - _async = Async.DISPATCH; if (context != null) _event.setDispatchContext(context); if (path != null) _event.setDispatchPath(path); - if (started) + if (_requestState == RequestState.ASYNC && _state == State.WAITING) { - switch (_state) - { - case DISPATCHED: - case ASYNC_IO: - case ASYNC_WOKEN: - break; - case ASYNC_WAIT: - _state = State.ASYNC_WOKEN; - dispatch = true; - break; - default: - LOG.warn("async dispatched when complete {}", this); - break; - } + _state = State.WOKEN; + dispatch = true; } + _requestState = RequestState.DISPATCH; + event = _event; } cancelTimeout(event); @@ -579,23 +608,47 @@ public class HttpChannelState scheduleDispatch(); } + protected void timeout() + { + boolean dispatch = false; + synchronized (this) + { + if (LOG.isDebugEnabled()) + LOG.debug("Timeout {}", toStringLocked()); + + if (_requestState != RequestState.ASYNC) + return; + _requestState = RequestState.EXPIRE; + + if (_state == State.WAITING) + { + _state = State.WOKEN; + dispatch = true; + } + } + + if (dispatch) + { + if (LOG.isDebugEnabled()) + LOG.debug("Dispatch after async timeout {}", this); + scheduleDispatch(); + } + } + protected void onTimeout() { final List listeners; AsyncContextEvent event; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onTimeout {}", toStringLocked()); - - if (_async != Async.STARTED) - return; - _async = Async.EXPIRING; + if (_requestState != RequestState.EXPIRING || _state != State.HANDLING) + throw new IllegalStateException(toStringLocked()); event = _event; listeners = _asyncListeners; } - final AtomicReference error = new AtomicReference<>(); if (listeners != null) { Runnable task = new Runnable() @@ -611,13 +664,10 @@ public class HttpChannelState } catch (Throwable x) { - LOG.warn(x + " while invoking onTimeout listener " + listener); - LOG.debug(x); - Throwable failure = error.get(); - if (failure == null) - error.set(x); - else if (x != failure) - failure.addSuppressed(x); + if (LOG.isDebugEnabled()) + LOG.warn("{} while invoking onTimeout listener {}", x.toString(), listener, x); + else + LOG.warn("{} while invoking onTimeout listener {}", x.toString(), listener); } } } @@ -631,86 +681,34 @@ public class HttpChannelState runInContext(event, task); } - - Throwable th = error.get(); - boolean dispatch = false; - try (Locker.Lock lock = _locker.lock()) - { - switch (_async) - { - case EXPIRING: - _async = th == null ? Async.EXPIRED : Async.ERRORING; - break; - - case COMPLETE: - case DISPATCH: - if (th != null) - { - LOG.ignore(th); - th = null; - } - break; - - default: - throw new IllegalStateException(); - } - - if (_state == State.ASYNC_WAIT) - { - _state = State.ASYNC_WOKEN; - dispatch = true; - } - } - - if (th != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("Error after async timeout {}", this, th); - onError(th); - } - - if (dispatch) - { - if (LOG.isDebugEnabled()) - LOG.debug("Dispatch after async timeout {}", this); - scheduleDispatch(); - } } public void complete() { - - // just like resume, except don't set _dispatched=true; boolean handle = false; AsyncContextEvent event; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("complete {}", toStringLocked()); - boolean started = false; event = _event; - - switch (_async) + switch (_requestState) { - case STARTED: - started = true; - break; case EXPIRING: - case ERRORING: - case ERRORED: + case ASYNC: + _requestState = _sendError ? RequestState.BLOCKING : RequestState.COMPLETE; break; + case COMPLETE: return; default: throw new IllegalStateException(this.getStatusStringLocked()); } - _async = Async.COMPLETE; - - if (started && _state == State.ASYNC_WAIT) + if (_state == State.WAITING) { handle = true; - _state = State.ASYNC_WOKEN; + _state = State.WOKEN; } } @@ -719,31 +717,136 @@ public class HttpChannelState runInContext(event, _channel); } - public void errorComplete() + public void asyncError(Throwable failure) { - try (Locker.Lock lock = _locker.lock()) + // This method is called when an failure occurs asynchronously to + // normal handling. If the request is async, we arrange for the + // exception to be thrown from the normal handling loop and then + // actually handled by #thrownException + + AsyncContextEvent event = null; + synchronized (this) { if (LOG.isDebugEnabled()) - LOG.debug("error complete {}", toStringLocked()); + LOG.debug("asyncError " + toStringLocked(), failure); - _async = Async.COMPLETE; - _event.setDispatchContext(null); - _event.setDispatchPath(null); + if (_state == State.WAITING && _requestState == RequestState.ASYNC) + { + _state = State.WOKEN; + _event.addThrowable(failure); + event = _event; + } + else + { + if (!(failure instanceof QuietException)) + LOG.warn(failure.toString()); + if (LOG.isDebugEnabled()) + LOG.debug("Async error", failure); + } } - cancelTimeout(); + if (event != null) + { + cancelTimeout(event); + runInContext(event, _channel); + } } protected void onError(Throwable th) { - final List listeners; - final AsyncContextEvent event; - final Request baseRequest = _channel.getRequest(); + final AsyncContextEvent asyncEvent; + final List asyncListeners; + synchronized (this) + { + if (LOG.isDebugEnabled()) + LOG.debug("thrownException " + getStatusStringLocked(), th); - int code = HttpStatus.INTERNAL_SERVER_ERROR_500; - String message = null; + // This can only be called from within the handle loop + if (_state != State.HANDLING) + throw new IllegalStateException(getStatusStringLocked()); + + // If sendError has already been called, we can only handle one failure at a time! + if (_sendError) + { + LOG.warn("unhandled due to prior sendError", th); + return; + } + + // Check async state to determine type of handling + switch (_requestState) + { + case BLOCKING: + // handle the exception with a sendError + sendError(th); + return; + + case DISPATCH: // Dispatch has already been called but we ignore and handle exception below + case COMPLETE: // Complete has already been called but we ignore and handle exception below + case ASYNC: + if (_asyncListeners == null || _asyncListeners.isEmpty()) + { + sendError(th); + return; + } + asyncEvent = _event; + asyncEvent.addThrowable(th); + asyncListeners = _asyncListeners; + break; + + default: + LOG.warn("unhandled in state " + _requestState, new IllegalStateException(th)); + return; + } + } + + // If we are async and have async listeners + // call onError + runInContext(asyncEvent, () -> + { + for (AsyncListener listener : asyncListeners) + { + try + { + listener.onError(asyncEvent); + } + catch (Throwable x) + { + if (LOG.isDebugEnabled()) + LOG.warn("{} while invoking onError listener {}", x.toString(), listener, x); + else + LOG.warn("{} while invoking onError listener {}", x.toString(), listener); + } + } + }); + + // check the actions of the listeners + synchronized (this) + { + // If we are still async and nobody has called sendError + if (_requestState == RequestState.ASYNC && !_sendError) + // Then the listeners did not invoke API methods + // and the container must provide a default error dispatch. + sendError(th); + else + LOG.warn("unhandled in state " + _requestState, new IllegalStateException(th)); + } + } + + private void sendError(Throwable th) + { + // No sync as this is always called with lock held + + // Determine the actual details of the exception + final Request request = _channel.getRequest(); + final int code; + final String message; Throwable cause = _channel.unwrap(th, BadMessageException.class, UnavailableException.class); - if (cause instanceof BadMessageException) + if (cause == null) + { + code = HttpStatus.INTERNAL_SERVER_ERROR_500; + message = th.toString(); + } + else if (cause instanceof BadMessageException) { BadMessageException bme = (BadMessageException)cause; code = bme.getCode(); @@ -751,196 +854,183 @@ public class HttpChannelState } else if (cause instanceof UnavailableException) { + message = cause.toString(); if (((UnavailableException)cause).isPermanent()) code = HttpStatus.NOT_FOUND_404; else code = HttpStatus.SERVICE_UNAVAILABLE_503; } - - try (Locker.Lock lock = _locker.lock()) + else { - if (LOG.isDebugEnabled()) - LOG.debug("onError {} {}", toStringLocked(), th); - - // Set error on request. - if (_event != null) - { - _event.addThrowable(th); - _event.getSuppliedRequest().setAttribute(ERROR_STATUS_CODE, code); - _event.getSuppliedRequest().setAttribute(ERROR_EXCEPTION, th); - _event.getSuppliedRequest().setAttribute(ERROR_EXCEPTION_TYPE, th == null ? null : th.getClass()); - _event.getSuppliedRequest().setAttribute(ERROR_MESSAGE, message); - } - else - { - Throwable error = (Throwable)baseRequest.getAttribute(ERROR_EXCEPTION); - if (error != null) - throw new IllegalStateException("Error already set", error); - baseRequest.setAttribute(ERROR_STATUS_CODE, code); - baseRequest.setAttribute(ERROR_EXCEPTION, th); - baseRequest.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, th == null ? null : th.getClass()); - baseRequest.setAttribute(ERROR_MESSAGE, message); - } - - // Are we blocking? - if (_async == Async.NOT_ASYNC) - { - // Only called from within HttpChannel Handling, so much be dispatched, let's stay dispatched! - if (_state == State.DISPATCHED) - { - _state = State.THROWN; - return; - } - throw new IllegalStateException(this.getStatusStringLocked()); - } - - // We are Async - _async = Async.ERRORING; - listeners = _asyncListeners; - event = _event; + code = HttpStatus.INTERNAL_SERVER_ERROR_500; + message = null; } - if (listeners != null) - { - Runnable task = new Runnable() - { - @Override - public void run() - { - for (AsyncListener listener : listeners) - { - try - { - listener.onError(event); - } - catch (Throwable x) - { - LOG.warn(x + " while invoking onError listener " + listener); - LOG.debug(x); - } - } - } + sendError(code, message); - @Override - public String toString() - { - return "onError"; - } - }; - runInContext(event, task); - } - - boolean dispatch = false; - try (Locker.Lock lock = _locker.lock()) - { - switch (_async) - { - case ERRORING: - { - // Still in this state ? The listeners did not invoke API methods - // and the container must provide a default error dispatch. - _async = Async.ERRORED; - break; - } - case DISPATCH: - case COMPLETE: - { - // The listeners called dispatch() or complete(). - break; - } - default: - { - throw new IllegalStateException(toString()); - } - } - - if (_state == State.ASYNC_WAIT) - { - _state = State.ASYNC_WOKEN; - dispatch = true; - } - } - - if (dispatch) - { - if (LOG.isDebugEnabled()) - LOG.debug("Dispatch after error {}", this); - scheduleDispatch(); - } + // No ISE, so good to modify request/state + request.setAttribute(ERROR_EXCEPTION, th); + request.setAttribute(ERROR_EXCEPTION_TYPE, th.getClass()); + // Ensure any async lifecycle is ended! + _requestState = RequestState.BLOCKING; } - protected void onComplete() + public void sendError(int code, String message) { - final List aListeners; - final AsyncContextEvent event; + // This method is called by Response.sendError to organise for an error page to be generated when it is possible: + // + The response is reset and temporarily closed. + // + The details of the error are saved as request attributes + // + The _sendError boolean is set to true so that an ERROR_DISPATCH action will be generated: + // - after unhandle for sync + // - after both unhandle and complete for async - try (Locker.Lock lock = _locker.lock()) + final Request request = _channel.getRequest(); + final Response response = _channel.getResponse(); + if (message == null) + message = HttpStatus.getMessage(code); + + synchronized (this) { if (LOG.isDebugEnabled()) - LOG.debug("onComplete {}", toStringLocked()); + LOG.debug("sendError {}", toStringLocked()); + + if (_outputState != OutputState.OPEN) + throw new IllegalStateException(_outputState.toString()); switch (_state) { - case COMPLETING: - aListeners = _asyncListeners; - event = _event; - _state = State.COMPLETED; - _async = Async.NOT_ASYNC; + case HANDLING: + case WOKEN: + case WAITING: break; - default: - throw new IllegalStateException(this.getStatusStringLocked()); + throw new IllegalStateException(getStatusStringLocked()); + } + if (_outputState != OutputState.OPEN) + throw new IllegalStateException("Response is " + _outputState); + + response.setStatus(code); + response.errorClose(); + + request.setAttribute(ErrorHandler.ERROR_CONTEXT, request.getErrorContext()); + request.setAttribute(ERROR_REQUEST_URI, request.getRequestURI()); + request.setAttribute(ERROR_SERVLET_NAME, request.getServletName()); + request.setAttribute(ERROR_STATUS_CODE, code); + request.setAttribute(ERROR_MESSAGE, message); + + _sendError = true; + if (_event != null) + { + Throwable cause = (Throwable)request.getAttribute(ERROR_EXCEPTION); + if (cause != null) + _event.addThrowable(cause); } } + } + + protected void completing() + { + synchronized (this) + { + if (LOG.isDebugEnabled()) + LOG.debug("completing {}", toStringLocked()); + + switch (_requestState) + { + case COMPLETED: + throw new IllegalStateException(getStatusStringLocked()); + default: + _requestState = RequestState.COMPLETING; + } + } + } + + protected void completed() + { + final List aListeners; + final AsyncContextEvent event; + boolean handle = false; + + synchronized (this) + { + if (LOG.isDebugEnabled()) + LOG.debug("completed {}", toStringLocked()); + + if (_requestState != RequestState.COMPLETING) + throw new IllegalStateException(this.getStatusStringLocked()); + + if (_event == null) + { + _requestState = RequestState.COMPLETED; + aListeners = null; + event = null; + if (_state == State.WAITING) + { + _state = State.WOKEN; + handle = true; + } + } + else + { + aListeners = _asyncListeners; + event = _event; + } + } + + // release any aggregate buffer from a closing flush + _channel.getResponse().getHttpOutput().completed(); if (event != null) { + cancelTimeout(event); if (aListeners != null) { - Runnable callback = new Runnable() + runInContext(event, () -> { - @Override - public void run() + for (AsyncListener listener : aListeners) { - for (AsyncListener listener : aListeners) + try { - try - { - listener.onComplete(event); - } - catch (Throwable e) - { - LOG.warn(e + " while invoking onComplete listener " + listener); - LOG.debug(e); - } + listener.onComplete(event); + } + catch (Throwable x) + { + if (LOG.isDebugEnabled()) + LOG.warn("{} while invoking onComplete listener {}", x.toString(), listener, x); + else + LOG.warn("{} while invoking onComplete listener {}", x.toString(), listener); } } - - @Override - public String toString() - { - return "onComplete"; - } - }; - - runInContext(event, callback); + }); } event.completed(); + + synchronized (this) + { + _requestState = RequestState.COMPLETED; + if (_state == State.WAITING) + { + _state = State.WOKEN; + handle = true; + } + } } + + if (handle) + _channel.handle(); } protected void recycle() { cancelTimeout(); - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("recycle {}", toStringLocked()); switch (_state) { - case DISPATCHED: - case ASYNC_IO: + case HANDLING: throw new IllegalStateException(getStatusStringLocked()); case UPGRADED: return; @@ -949,9 +1039,10 @@ public class HttpChannelState } _asyncListeners = null; _state = State.IDLE; - _async = Async.NOT_ASYNC; + _requestState = RequestState.BLOCKING; + _outputState = OutputState.OPEN; _initial = true; - _asyncRead = AsyncRead.IDLE; + _inputState = InputState.IDLE; _asyncWritePossible = false; _timeoutMs = DEFAULT_TIMEOUT; _event = null; @@ -961,7 +1052,7 @@ public class HttpChannelState public void upgrade() { cancelTimeout(); - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("upgrade {}", toStringLocked()); @@ -969,16 +1060,15 @@ public class HttpChannelState switch (_state) { case IDLE: - case COMPLETED: break; default: throw new IllegalStateException(getStatusStringLocked()); } _asyncListeners = null; _state = State.UPGRADED; - _async = Async.NOT_ASYNC; + _requestState = RequestState.BLOCKING; _initial = true; - _asyncRead = AsyncRead.IDLE; + _inputState = InputState.IDLE; _asyncWritePossible = false; _timeoutMs = DEFAULT_TIMEOUT; _event = null; @@ -993,7 +1083,7 @@ public class HttpChannelState protected void cancelTimeout() { final AsyncContextEvent event; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { event = _event; } @@ -1008,7 +1098,7 @@ public class HttpChannelState public boolean isIdle() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return _state == State.IDLE; } @@ -1016,15 +1106,16 @@ public class HttpChannelState public boolean isExpired() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { - return _async == Async.EXPIRED; + // TODO review + return _requestState == RequestState.EXPIRE || _requestState == RequestState.EXPIRING; } } public boolean isInitial() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { return _initial; } @@ -1032,51 +1123,35 @@ public class HttpChannelState public boolean isSuspended() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { - return _state == State.ASYNC_WAIT || _state == State.DISPATCHED && _async == Async.STARTED; - } - } - - boolean isCompleting() - { - try (Locker.Lock lock = _locker.lock()) - { - return _state == State.COMPLETING; + return _state == State.WAITING || _state == State.HANDLING && _requestState == RequestState.ASYNC; } } boolean isCompleted() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { - return _state == State.COMPLETED; + return _requestState == RequestState.COMPLETED; } } public boolean isAsyncStarted() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { - if (_state == State.DISPATCHED) - return _async != Async.NOT_ASYNC; - return _async == Async.STARTED || _async == Async.EXPIRING; - } - } - - public boolean isAsyncComplete() - { - try (Locker.Lock lock = _locker.lock()) - { - return _async == Async.COMPLETE; + if (_state == State.HANDLING) + return _requestState != RequestState.BLOCKING; + return _requestState == RequestState.ASYNC || _requestState == RequestState.EXPIRING; } } public boolean isAsync() { - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { - return !_initial || _async != Async.NOT_ASYNC; + return !_initial || _requestState != RequestState.BLOCKING; } } @@ -1093,7 +1168,7 @@ public class HttpChannelState public ContextHandler getContextHandler() { final AsyncContextEvent event; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { event = _event; } @@ -1114,7 +1189,7 @@ public class HttpChannelState public ServletResponse getServletResponse() { final AsyncContextEvent event; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { event = _event; } @@ -1162,23 +1237,23 @@ public class HttpChannelState public void onReadUnready() { boolean interested = false; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onReadUnready {}", toStringLocked()); - switch (_asyncRead) + switch (_inputState) { case IDLE: case READY: - if (_state == State.ASYNC_WAIT) + if (_state == State.WAITING) { interested = true; - _asyncRead = AsyncRead.REGISTERED; + _inputState = InputState.REGISTERED; } else { - _asyncRead = AsyncRead.REGISTER; + _inputState = InputState.REGISTER; } break; @@ -1187,8 +1262,9 @@ public class HttpChannelState case POSSIBLE: case PRODUCING: break; + default: - throw new IllegalStateException(_asyncRead.toString()); + throw new IllegalStateException(toStringLocked()); } } @@ -1207,28 +1283,28 @@ public class HttpChannelState public boolean onContentAdded() { boolean woken = false; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onContentAdded {}", toStringLocked()); - switch (_asyncRead) + switch (_inputState) { case IDLE: case READY: break; case PRODUCING: - _asyncRead = AsyncRead.READY; + _inputState = InputState.READY; break; case REGISTER: case REGISTERED: - _asyncRead = AsyncRead.READY; - if (_state == State.ASYNC_WAIT) + _inputState = InputState.READY; + if (_state == State.WAITING) { woken = true; - _state = State.ASYNC_WOKEN; + _state = State.WOKEN; } break; @@ -1250,19 +1326,19 @@ public class HttpChannelState public boolean onReadReady() { boolean woken = false; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onReadReady {}", toStringLocked()); - switch (_asyncRead) + switch (_inputState) { case IDLE: - _asyncRead = AsyncRead.READY; - if (_state == State.ASYNC_WAIT) + _inputState = InputState.READY; + if (_state == State.WAITING) { woken = true; - _state = State.ASYNC_WOKEN; + _state = State.WOKEN; } break; @@ -1278,24 +1354,24 @@ public class HttpChannelState * but that a handling thread may need to produce (fill/parse) * it. Typically called by the async read success callback. * - * @return true if more content may be available + * @return {@code true} if more content may be available */ public boolean onReadPossible() { boolean woken = false; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onReadPossible {}", toStringLocked()); - switch (_asyncRead) + switch (_inputState) { case REGISTERED: - _asyncRead = AsyncRead.POSSIBLE; - if (_state == State.ASYNC_WAIT) + _inputState = InputState.POSSIBLE; + if (_state == State.WAITING) { woken = true; - _state = State.ASYNC_WOKEN; + _state = State.WOKEN; } break; @@ -1310,22 +1386,22 @@ public class HttpChannelState * Called to signal that a read has read -1. * Will wake if the read was called while in ASYNC_WAIT state * - * @return true if woken + * @return {@code true} if woken */ public boolean onReadEof() { boolean woken = false; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onEof {}", toStringLocked()); // Force read ready so onAllDataRead can be called - _asyncRead = AsyncRead.READY; - if (_state == State.ASYNC_WAIT) + _inputState = InputState.READY; + if (_state == State.WAITING) { woken = true; - _state = State.ASYNC_WOKEN; + _state = State.WOKEN; } } return woken; @@ -1335,15 +1411,15 @@ public class HttpChannelState { boolean wake = false; - try (Locker.Lock lock = _locker.lock()) + synchronized (this) { if (LOG.isDebugEnabled()) LOG.debug("onWritePossible {}", toStringLocked()); _asyncWritePossible = true; - if (_state == State.ASYNC_WAIT) + if (_state == State.WAITING) { - _state = State.ASYNC_WOKEN; + _state = State.WOKEN; wake = true; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java index 26276476b4c..997364544a9 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -34,13 +34,11 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; /** * HTTP Configuration. *

      This class is a holder of HTTP configuration for use by the - * {@link HttpChannel} class. Typically a HTTPConfiguration instance + * {@link HttpChannel} class. Typically an HTTPConfiguration instance * is instantiated and passed to a {@link ConnectionFactory} that can * create HTTP channels (e.g. HTTP, AJP or FCGI).

      *

      The configuration held by this class is not for the wire protocol, @@ -51,8 +49,6 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject("HTTP Configuration") public class HttpConfiguration implements Dumpable { - private static final Logger LOG = Log.getLogger(HttpConfiguration.class); - public static final String SERVER_VERSION = "Jetty(" + Jetty.VERSION + ")"; private final List _customizers = new CopyOnWriteArrayList<>(); private final Trie _formEncodedMethods = new TreeTrie<>(); @@ -60,7 +56,7 @@ public class HttpConfiguration implements Dumpable private int _outputAggregationSize = _outputBufferSize / 4; private int _requestHeaderSize = 8 * 1024; private int _responseHeaderSize = 8 * 1024; - private int _headerCacheSize = 4 * 1024; + private int _headerCacheSize = 1024; private boolean _headerCacheCaseSensitive = false; private int _securePort; private long _idleTimeout = -1; @@ -71,7 +67,8 @@ public class HttpConfiguration implements Dumpable private boolean _delayDispatchUntilContent = true; private boolean _persistentConnectionsEnabled = true; private int _maxErrorDispatches = 10; - private boolean _useDirectByteBuffers = false; + private boolean _useInputDirectByteBuffers = true; + private boolean _useOutputDirectByteBuffers = true; private long _minRequestDataRate; private long _minResponseDataRate; private HttpCompliance _httpCompliance = HttpCompliance.RFC7230; @@ -128,6 +125,7 @@ public class HttpConfiguration implements Dumpable _requestHeaderSize = config._requestHeaderSize; _responseHeaderSize = config._responseHeaderSize; _headerCacheSize = config._headerCacheSize; + _headerCacheCaseSensitive = config._headerCacheCaseSensitive; _secureScheme = config._secureScheme; _securePort = config._securePort; _idleTimeout = config._idleTimeout; @@ -137,9 +135,11 @@ public class HttpConfiguration implements Dumpable _delayDispatchUntilContent = config._delayDispatchUntilContent; _persistentConnectionsEnabled = config._persistentConnectionsEnabled; _maxErrorDispatches = config._maxErrorDispatches; - _useDirectByteBuffers = config._useDirectByteBuffers; + _useInputDirectByteBuffers = config._useInputDirectByteBuffers; + _useOutputDirectByteBuffers = config._useOutputDirectByteBuffers; _minRequestDataRate = config._minRequestDataRate; _minResponseDataRate = config._minResponseDataRate; + _httpCompliance = config._httpCompliance; _requestCookieCompliance = config._requestCookieCompliance; _responseCookieCompliance = config._responseCookieCompliance; _notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors; @@ -185,19 +185,19 @@ public class HttpConfiguration implements Dumpable return _outputAggregationSize; } - @ManagedAttribute("The maximum allowed size in bytes for a HTTP request header") + @ManagedAttribute("The maximum allowed size in bytes for an HTTP request header") public int getRequestHeaderSize() { return _requestHeaderSize; } - @ManagedAttribute("The maximum allowed size in bytes for a HTTP response header") + @ManagedAttribute("The maximum allowed size in bytes for an HTTP response header") public int getResponseHeaderSize() { return _responseHeaderSize; } - @ManagedAttribute("The maximum allowed size in bytes for a HTTP header field cache") + @ManagedAttribute("The maximum allowed size in bytes for an HTTP header field cache") public int getHeaderCacheSize() { return _headerCacheSize; @@ -228,20 +228,20 @@ public class HttpConfiguration implements Dumpable } /** - *

      The max idle time is applied to a HTTP request for IO operations and + *

      The max idle time is applied to an HTTP request for IO operations and * delayed dispatch.

      * * @return the max idle time in ms or if == 0 implies an infinite timeout, <0 * implies no HTTP channel timeout and the connection timeout is used instead. */ - @ManagedAttribute("The idle timeout in ms for I/O operations during the handling of a HTTP request") + @ManagedAttribute("The idle timeout in ms for I/O operations during the handling of an HTTP request") public long getIdleTimeout() { return _idleTimeout; } /** - *

      The max idle time is applied to a HTTP request for IO operations and + *

      The max idle time is applied to an HTTP request for IO operations and * delayed dispatch.

      * * @param timeoutMs the max idle time in ms or if == 0 implies an infinite timeout, <0 @@ -315,7 +315,7 @@ public class HttpConfiguration implements Dumpable } /** - * @param delay if true, delay the application dispatch until content is available (default false) + * @param delay if true, delays the application dispatch until content is available (defaults to true) */ public void setDelayDispatchUntilContent(boolean delay) { @@ -329,17 +329,31 @@ public class HttpConfiguration implements Dumpable } /** - * @param useDirectByteBuffers if true, use direct byte buffers for requests + * @param useInputDirectByteBuffers whether to use direct ByteBuffers for reading */ - public void setUseDirectByteBuffers(boolean useDirectByteBuffers) + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) { - _useDirectByteBuffers = useDirectByteBuffers; + _useInputDirectByteBuffers = useInputDirectByteBuffers; } - @ManagedAttribute("Whether to use direct byte buffers for requests") - public boolean isUseDirectByteBuffers() + @ManagedAttribute("Whether to use direct ByteBuffers for reading") + public boolean isUseInputDirectByteBuffers() { - return _useDirectByteBuffers; + return _useInputDirectByteBuffers; + } + + /** + * @param useOutputDirectByteBuffers whether to use direct ByteBuffers for writing + */ + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + _useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + + @ManagedAttribute("Whether to use direct ByteBuffers for writing") + public boolean isUseOutputDirectByteBuffers() + { + return _useOutputDirectByteBuffers; } /** @@ -557,7 +571,7 @@ public class HttpConfiguration implements Dumpable } /** - * @return The CookieCompliance used for parsing request Cookie headers. + * @return The CookieCompliance used for parsing request {@code Cookie} headers. * @see #getResponseCookieCompliance() */ public CookieCompliance getRequestCookieCompliance() @@ -566,7 +580,7 @@ public class HttpConfiguration implements Dumpable } /** - * @return The CookieCompliance used for generating response Set-Cookie headers + * @return The CookieCompliance used for generating response {@code Set-Cookie} headers * @see #getRequestCookieCompliance() */ public CookieCompliance getResponseCookieCompliance() @@ -575,8 +589,7 @@ public class HttpConfiguration implements Dumpable } /** - * @param cookieCompliance The CookieCompliance to use for parsing request Cookie headers. - * @see #setRequestCookieCompliance(CookieCompliance) + * @param cookieCompliance The CookieCompliance to use for parsing request {@code Cookie} headers. */ public void setRequestCookieCompliance(CookieCompliance cookieCompliance) { @@ -584,8 +597,7 @@ public class HttpConfiguration implements Dumpable } /** - * @param cookieCompliance The CookieCompliance to use for generating response Set-Cookie headers - * @see #setResponseCookieCompliance(CookieCompliance) + * @param cookieCompliance The CookieCompliance to use for generating response {@code Set-Cookie} headers */ public void setResponseCookieCompliance(CookieCompliance cookieCompliance) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index 3d717ca4497..d54aeaf2d47 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -25,11 +25,13 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.LongAdder; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpCompliance; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser.RequestHandler; import org.eclipse.jetty.http.HttpStatus; @@ -44,17 +46,16 @@ import org.eclipse.jetty.io.WriteFlusher; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A {@link Connection} that handles the HTTP protocol.

      */ public class HttpConnection extends AbstractConnection implements Runnable, HttpTransport, WriteFlusher.Listener, Connection.UpgradeFrom, Connection.UpgradeTo { - private static final Logger LOG = Log.getLogger(HttpConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpConnection.class); public static final HttpField CONNECTION_CLOSE = new PreEncodedHttpField(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); - public static final String UPGRADE_CONNECTION_ATTRIBUTE = "org.eclipse.jetty.server.HttpConnection.UPGRADE"; private static final ThreadLocal __currentConnection = new ThreadLocal<>(); private final HttpConfiguration _config; @@ -73,6 +74,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http private final boolean _recordHttpComplianceViolations; private final LongAdder bytesIn = new LongAdder(); private final LongAdder bytesOut = new LongAdder(); + private boolean _useInputDirectByteBuffers; + private boolean _useOutputDirectByteBuffers; /** * Get the current connection that this thread is dispatched to. @@ -131,7 +134,10 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http protected HttpParser newHttpParser(HttpCompliance compliance) { - return new HttpParser(newRequestHandler(), getHttpConfiguration().getRequestHeaderSize(), compliance); + HttpParser parser = new HttpParser(newRequestHandler(), getHttpConfiguration().getRequestHeaderSize(), compliance); + parser.setHeaderCacheSize(getHttpConfiguration().getHeaderCacheSize()); + parser.setHeaderCacheCaseSensitive(getHttpConfiguration().isHeaderCacheCaseSensitive()); + return parser; } protected HttpParser.RequestHandler newRequestHandler() @@ -164,12 +170,6 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http return _generator; } - @Override - public boolean isOptimizedForDirectBuffers() - { - return getEndPoint().isOptimizedForDirectBuffers(); - } - @Override public long getMessagesIn() { @@ -182,6 +182,26 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http return getHttpChannel().getRequests(); } + public boolean isUseInputDirectByteBuffers() + { + return _useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + _useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + public boolean isUseOutputDirectByteBuffers() + { + return _useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + _useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + @Override public ByteBuffer onUpgradeFrom() { @@ -224,7 +244,10 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http public ByteBuffer getRequestBuffer() { if (_requestBuffer == null) - _requestBuffer = _bufferPool.acquire(getInputBufferSize(), _config.isUseDirectByteBuffers()); + { + boolean useDirectByteBuffers = isUseInputDirectByteBuffers(); + _requestBuffer = _bufferPool.acquire(getInputBufferSize(), useDirectByteBuffers); + } return _requestBuffer; } @@ -254,6 +277,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http // Parse the request buffer. boolean handle = parseRequestBuffer(); + // There could be a connection upgrade before handling + // the HTTP/1.1 request, for example PRI * HTTP/2. // If there was a connection upgrade, the other // connection took over, nothing more to do here. if (getEndPoint().getConnection() != this) @@ -264,7 +289,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http { boolean suspended = !_channel.handle(); - // We should break iteration if we have suspended or changed connection or this is not the handling thread. + // We should break iteration if we have suspended or upgraded the connection. if (suspended || getEndPoint().getConnection() != this) break; } @@ -275,18 +300,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } else if (filled < 0) { - switch (_channel.getState().getState()) - { - case COMPLETING: - case COMPLETED: - case IDLE: - case THROWN: - case ASYNC_ERROR: - getEndPoint().shutdownOutput(); - break; - default: - break; - } + if (_channel.getState().isIdle()) + getEndPoint().shutdownOutput(); break; } } @@ -350,7 +365,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } catch (IOException e) { - LOG.debug(e); + LOG.debug("Unable to fill from endpoint {}", getEndPoint(), e); _parser.atEOF(); return -1; } @@ -361,7 +376,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http private boolean parseRequestBuffer() { if (LOG.isDebugEnabled()) - LOG.debug("{} parse {} {}", this, BufferUtil.toDetailString(_requestBuffer)); + LOG.debug("{} parse {}", this, BufferUtil.toDetailString(_requestBuffer)); boolean handle = _parser.parseNext(_requestBuffer == null ? BufferUtil.EMPTY_BUFFER : _requestBuffer); @@ -375,33 +390,38 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http return handle; } + private boolean upgrade() + { + Connection connection = (Connection)_channel.getRequest().getAttribute(UPGRADE_CONNECTION_ATTRIBUTE); + if (connection == null) + return false; + + if (LOG.isDebugEnabled()) + LOG.debug("Upgrade from {} to {}", this, connection); + _channel.getState().upgrade(); + getEndPoint().upgrade(connection); + _channel.recycle(); + _parser.reset(); + _generator.reset(); + if (_contentBufferReferences.get() == 0) + { + releaseRequestBuffer(); + } + else + { + LOG.warn("{} lingering content references?!?!", this); + _requestBuffer = null; // Not returned to pool! + _contentBufferReferences.set(0); + } + return true; + } + @Override public void onCompleted() { - // Handle connection upgrades - if (_channel.getResponse().getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) - { - Connection connection = (Connection)_channel.getRequest().getAttribute(UPGRADE_CONNECTION_ATTRIBUTE); - if (connection != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("Upgrade from {} to {}", this, connection); - _channel.getState().upgrade(); - getEndPoint().upgrade(connection); - _channel.recycle(); - _parser.reset(); - _generator.reset(); - if (_contentBufferReferences.get() == 0) - releaseRequestBuffer(); - else - { - LOG.warn("{} lingering content references?!?!", this); - _requestBuffer = null; // Not returned to pool! - _contentBufferReferences.set(0); - } - return; - } - } + // Handle connection upgrades. + if (upgrade()) + return; // Finish consuming the request // If we are still expecting @@ -412,20 +432,25 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } else if (_parser.inContentState() && _generator.isPersistent()) { - // If we are async, then we have problems to complete neatly - if (_input.isAsync()) + // Try to progress without filling. + parseRequestBuffer(); + if (_parser.inContentState()) { - if (LOG.isDebugEnabled()) - LOG.debug("{}unconsumed input {}", _parser.isChunking() ? "Possible " : "", this); - _channel.abort(new IOException("unconsumed input")); - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("{}unconsumed input {}", _parser.isChunking() ? "Possible " : "", this); - // Complete reading the request - if (!_input.consumeAll()) + // If we are async, then we have problems to complete neatly + if (_input.isAsync()) + { + if (LOG.isDebugEnabled()) + LOG.debug("{}unconsumed input while async {}", _parser.isChunking() ? "Possible " : "", this); _channel.abort(new IOException("unconsumed input")); + } + else + { + if (LOG.isDebugEnabled()) + LOG.debug("{}unconsumed input {}", _parser.isChunking() ? "Possible " : "", this); + // Complete reading the request + if (!_input.consumeAll()) + _channel.abort(new IOException("unconsumed input")); + } } } @@ -469,9 +494,9 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http catch (RejectedExecutionException e) { if (getConnector().isRunning()) - LOG.warn(e); + LOG.warn("Failed dispatch of {}", this, e); else - LOG.ignore(e); + LOG.trace("IGNORED", e); getEndPoint().close(); } } @@ -526,9 +551,9 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } @Override - public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) + public void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback) { - if (info == null) + if (response == null) { if (!lastContent && BufferUtil.isEmpty(content)) { @@ -544,7 +569,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http _generator.setPersistent(false); } - if (_sendCallback.reset(info, head, content, lastContent, callback)) + if (_sendCallback.reset(request, response, content, lastContent, callback)) { _sendCallback.iterate(); } @@ -706,12 +731,12 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http return _callback.getInvocationType(); } - private boolean reset(MetaData.Response info, boolean head, ByteBuffer content, boolean last, Callback callback) + private boolean reset(MetaData.Request request, MetaData.Response info, ByteBuffer content, boolean last, Callback callback) { if (reset()) { _info = info; - _head = head; + _head = HttpMethod.HEAD.is(request.getMethod()); _content = content; _lastContent = last; _callback = callback; @@ -737,14 +762,15 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http if (_callback == null) throw new IllegalStateException(); + boolean useDirectByteBuffers = isUseOutputDirectByteBuffers(); ByteBuffer chunk = _chunk; while (true) { HttpGenerator.Result result = _generator.generateResponse(_info, _head, _header, chunk, _content, _lastContent); if (LOG.isDebugEnabled()) - LOG.debug("{} generate: {} ({},{},{})@{}", - this, + LOG.debug("generate: {} for {} ({},{},{})@{}", result, + this, BufferUtil.toSummaryString(_header), BufferUtil.toSummaryString(_content), _lastContent, @@ -757,19 +783,28 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http case NEED_HEADER: { - _header = _bufferPool.acquire(_config.getResponseHeaderSize(), _config.isUseDirectByteBuffers()); + _header = _bufferPool.acquire(Math.min(_config.getResponseHeaderSize(), _config.getOutputBufferSize()), useDirectByteBuffers); + continue; + } + case HEADER_OVERFLOW: + { + int capacity = _header.capacity(); + _bufferPool.release(_header); + if (capacity >= _config.getResponseHeaderSize()) + throw new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, "Response header too large"); + _header = _bufferPool.acquire(_config.getResponseHeaderSize(), useDirectByteBuffers); continue; } case NEED_CHUNK: { - chunk = _chunk = _bufferPool.acquire(HttpGenerator.CHUNK_SIZE, _config.isUseDirectByteBuffers()); + chunk = _chunk = _bufferPool.acquire(HttpGenerator.CHUNK_SIZE, useDirectByteBuffers); continue; } case NEED_CHUNK_TRAILER: { if (_chunk != null) _bufferPool.release(_chunk); - chunk = _chunk = _bufferPool.acquire(_config.getResponseHeaderSize(), _config.isUseDirectByteBuffers()); + chunk = _chunk = _bufferPool.acquire(_config.getResponseHeaderSize(), useDirectByteBuffers); continue; } case FLUSH: @@ -835,8 +870,10 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } case DONE: { - // If shutdown after commit, we can still close here. - if (getConnector().isShutdown()) + // If this is the end of the response and the connector was shutdown after response was committed, + // we can't add the Connection:close header, but we are still allowed to close the connection + // by shutting down the output. + if (getConnector().isShutdown() && _generator.isEnd() && _generator.isPersistent()) _shutdownOut = true; return Action.SUCCEEDED; @@ -853,19 +890,22 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } } - private void releaseHeader() + private Callback release() { - ByteBuffer h = _header; + Callback complete = _callback; + _callback = null; + _info = null; + _content = null; + if (_header != null) + _bufferPool.release(_header); _header = null; - if (h != null) - _bufferPool.release(h); + return complete; } @Override protected void onCompleteSuccess() { - releaseHeader(); - _callback.succeeded(); + release().succeeded(); if (_shutdownOut) getEndPoint().shutdownOutput(); } @@ -873,8 +913,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http @Override public void onCompleteFailure(final Throwable x) { - releaseHeader(); - failedCallback(_callback, x); + failedCallback(release(), x); if (_shutdownOut) getEndPoint().shutdownOutput(); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java index beee4fbe7a5..a3731805157 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java @@ -1,23 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; +import java.util.Objects; + import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; @@ -32,7 +34,9 @@ import org.eclipse.jetty.util.annotation.Name; public class HttpConnectionFactory extends AbstractConnectionFactory implements HttpConfiguration.ConnectionFactory { private final HttpConfiguration _config; - private boolean _recordHttpComplianceViolations = false; + private boolean _recordHttpComplianceViolations; + private boolean _useInputDirectByteBuffers; + private boolean _useOutputDirectByteBuffers; public HttpConnectionFactory() { @@ -42,10 +46,10 @@ public class HttpConnectionFactory extends AbstractConnectionFactory implements public HttpConnectionFactory(@Name("config") HttpConfiguration config) { super(HttpVersion.HTTP_1_1.asString()); - _config = config; - if (config == null) - throw new IllegalArgumentException("Null HttpConfiguration"); + _config = Objects.requireNonNull(config); addBean(_config); + setUseInputDirectByteBuffers(_config.isUseInputDirectByteBuffers()); + setUseOutputDirectByteBuffers(_config.isUseOutputDirectByteBuffers()); } @Override @@ -59,15 +63,37 @@ public class HttpConnectionFactory extends AbstractConnectionFactory implements return _recordHttpComplianceViolations; } - @Override - public Connection newConnection(Connector connector, EndPoint endPoint) - { - HttpConnection conn = new HttpConnection(_config, connector, endPoint, isRecordHttpComplianceViolations()); - return configure(conn, connector, endPoint); - } - public void setRecordHttpComplianceViolations(boolean recordHttpComplianceViolations) { this._recordHttpComplianceViolations = recordHttpComplianceViolations; } + + public boolean isUseInputDirectByteBuffers() + { + return _useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + _useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + public boolean isUseOutputDirectByteBuffers() + { + return _useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + _useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + HttpConnection connection = new HttpConnection(_config, connector, endPoint, isRecordHttpComplianceViolations()); + connection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers()); + connection.setUseOutputDirectByteBuffers(isUseOutputDirectByteBuffers()); + return configure(connection, connector, endPoint); + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java index 0b6a450d01c..4d5e142b15b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -36,8 +36,8 @@ import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * {@link HttpInput} provides an implementation of {@link ServletInputStream} for {@link HttpChannel}. @@ -121,7 +121,7 @@ public class HttpInput extends ServletInputStream implements Runnable } } - private static final Logger LOG = Log.getLogger(HttpInput.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpInput.class); static final Content EOF_CONTENT = new EofContent("EOF"); static final Content EARLY_EOF_CONTENT = new EofContent("EARLY_EOF"); @@ -274,7 +274,8 @@ public class HttpInput extends ServletInputStream implements Runnable { BadMessageException bad = new BadMessageException(HttpStatus.REQUEST_TIMEOUT_408, String.format("Request content data rate < %d B/s", minRequestDataRate)); - _channelState.getHttpChannel().abort(bad); + if (_channelState.isResponseCommitted()) + _channelState.getHttpChannel().abort(bad); throw bad; } } @@ -659,7 +660,7 @@ public class HttpInput extends ServletInputStream implements Runnable } catch (Throwable e) { - LOG.debug(e); + LOG.debug("Unable to consume all input", e); _state = new ErrorState(e); return false; } @@ -713,7 +714,7 @@ public class HttpInput extends ServletInputStream implements Runnable } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return true; } } @@ -731,22 +732,29 @@ public class HttpInput extends ServletInputStream implements Runnable _listener = Objects.requireNonNull(readListener); - Content content = produceNextContext(); - if (content != null) + if (isError()) { - _state = ASYNC; woken = _channelState.onReadReady(); } - else if (_state == EOF) - { - _state = AEOF; - woken = _channelState.onReadEof(); - } else { - _state = ASYNC; - _channelState.onReadUnready(); - _waitingForContent = true; + Content content = produceNextContext(); + if (content != null) + { + _state = ASYNC; + woken = _channelState.onReadReady(); + } + else if (_state == EOF) + { + _state = AEOF; + woken = _channelState.onReadEof(); + } + else + { + _state = ASYNC; + _channelState.onReadUnready(); + _waitingForContent = true; + } } } } @@ -788,7 +796,7 @@ public class HttpInput extends ServletInputStream implements Runnable // without modifying the original failure. Throwable failure = new Throwable(_state.getError()); failure.addSuppressed(x); - LOG.debug(failure); + LOG.debug("HttpInput failure", failure); } } else @@ -879,8 +887,10 @@ public class HttpInput extends ServletInputStream implements Runnable } catch (Throwable e) { - LOG.warn(e.toString()); - LOG.debug(e); + if (LOG.isDebugEnabled()) + LOG.warn("Unable to notify listener", e); + else + LOG.warn("Unable to notify listener: {}", e.toString()); try { if (aeof || error == null) @@ -891,9 +901,12 @@ public class HttpInput extends ServletInputStream implements Runnable } catch (Throwable e2) { - LOG.warn(e2.toString()); - LOG.debug(e2); - throw new RuntimeIOException(e2); + String msg = "Unable to notify error to listener"; + if (LOG.isDebugEnabled()) + LOG.warn(msg, e2); + else + LOG.warn(msg + ": {}", e2.toString()); + throw new RuntimeIOException(msg, e2); } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInputOverHTTP.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInputOverHTTP.java index c8766ff3169..6f646c4ce61 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInputOverHTTP.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInputOverHTTP.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java index a010a69e9a7..cf16784070e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -28,9 +28,7 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; -import java.util.ResourceBundle; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import javax.servlet.RequestDispatcher; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; @@ -43,11 +41,10 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.IteratingNestedCallback; import org.eclipse.jetty.util.SharedBlockingCallback; import org.eclipse.jetty.util.SharedBlockingCallback.Blocker; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      {@link HttpOutput} implements {@link ServletOutputStream} @@ -61,8 +58,67 @@ import org.eclipse.jetty.util.log.Logger; */ public class HttpOutput extends ServletOutputStream implements Runnable { - private static final String LSTRING_FILE = "javax.servlet.LocalStrings"; - private static ResourceBundle lStrings = ResourceBundle.getBundle(LSTRING_FILE); + /** + * The output state + */ + enum State + { + OPEN, // Open + CLOSE, // Close needed from onWriteCompletion + CLOSING, // Close in progress after close API called + CLOSED // Closed + } + + /** + * The API State which combines with the output State: + *

      +              OPEN/BLOCKING---last----------------------------+                      CLOSED/BLOCKING
      +             /   |    ^                                        \                         ^  ^
      +            /    w    |                                         \                       /   |
      +           /     |   owc   +--owcL------------------->--owcL-----\---------------------+    |
      +          |      v    |   /                         /             V                         |
      +         swl  OPEN/BLOCKED----last---->CLOSE/BLOCKED----owc----->CLOSING/BLOCKED--owcL------+
      +          |
      +           \
      +            \
      +             V
      +          +-->OPEN/READY------last---------------------------+
      +         /    ^    |                                          \
      +        /    /     w                                           \
      +       |    /      |       +--owcL------------------->--owcL----\---------------------------+
      +       |   /       v      /                         /            V                          |
      +       | irt  OPEN/PENDING----last---->CLOSE/PENDING----owc---->CLOSING/PENDING--owcL----+  |
      +       |   \  /    |                        |                    ^     |                 |  |
      +      owc   \/    owc                      irf                  /     irf                |  |
      +       |    /\     |                        |                  /       |                 |  |
      +       |   /  \    V                        |                 /        |                 V  V
      +       | irf  OPEN/ASYNC------last----------|----------------+         |             CLOSED/ASYNC
      +       |   \                                |                          |                 ^  ^
      +        \   \                               |                          |                 |  |
      +         \   \                              |                          |                 |  |
      +          \   v                             v                          v                 |  |
      +           +--OPEN/UNREADY----last---->CLOSE/UNREADY----owc----->CLOSING/UNREADY--owcL---+  |
      +                          \                         \                                       |
      +                           +--owcL------------------->--owcL--------------------------------+
      +
      +      swl  : setWriteListener
      +      w    : write
      +      owc  : onWriteComplete last == false
      +      owcL : onWriteComplete last == true
      +      irf  : isReady() == false
      +      irt  : isReady() == true
      +      last : close() or complete(Callback) or write of known last content
      +     
      + */ + enum ApiState + { + BLOCKING, // Open in blocking mode + BLOCKED, // Blocked in blocking operation + ASYNC, // Open in async mode + READY, // isReady() has returned true + PENDING, // write operating in progress + UNREADY, // write operating in progress, isReady has returned false + } /** * The HttpOutput.Interceptor is a single intercept point for all @@ -103,14 +159,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable */ Interceptor getNextInterceptor(); - /** - * @return True if the Interceptor is optimized to receive direct - * {@link ByteBuffer}s in the {@link #write(ByteBuffer, boolean, Callback)} - * method. If false is returned, then passing direct buffers may cause - * inefficiencies. - */ - boolean isOptimizedForDirectBuffers(); - /** * Reset the buffers. *

      If the Interceptor contains buffers then reset them. @@ -126,11 +174,15 @@ public class HttpOutput extends ServletOutputStream implements Runnable } } - private static Logger LOG = Log.getLogger(HttpOutput.class); + private static Logger LOG = LoggerFactory.getLogger(HttpOutput.class); private static final ThreadLocal _encoder = new ThreadLocal<>(); private final HttpChannel _channel; + private final HttpChannelState _channelState; private final SharedBlockingCallback _writeBlocker; + private ApiState _apiState = ApiState.BLOCKING; + private State _state = State.OPEN; + private boolean _softClose = false; private Interceptor _interceptor; private long _written; private long _flushed; @@ -140,27 +192,12 @@ public class HttpOutput extends ServletOutputStream implements Runnable private int _commitSize; private WriteListener _writeListener; private volatile Throwable _onError; - - /* - ACTION OPEN ASYNC READY PENDING UNREADY CLOSED - ------------------------------------------------------------------------------------------- - setWriteListener() READY->owp ise ise ise ise ise - write() OPEN ise PENDING wpe wpe eof - flush() OPEN ise PENDING wpe wpe eof - close() CLOSED CLOSED CLOSED CLOSED CLOSED CLOSED - isReady() OPEN:true READY:true READY:true UNREADY:false UNREADY:false CLOSED:true - write completed - - - ASYNC READY->owp - - */ - private enum OutputState - { - OPEN, ASYNC, READY, PENDING, UNREADY, ERROR, CLOSED - } - - private final AtomicReference _state = new AtomicReference<>(OutputState.OPEN); + private Callback _closedCallback; public HttpOutput(HttpChannel channel) { _channel = channel; + _channelState = channel.getState(); _interceptor = channel; _writeBlocker = new WriteBlocker(channel); HttpConfiguration config = channel.getHttpConfiguration(); @@ -200,18 +237,10 @@ public class HttpOutput extends ServletOutputStream implements Runnable public void reopen() { - _state.set(OutputState.OPEN); - } - - private boolean isLastContentToWrite(int len) - { - _written += len; - return _channel.getResponse().isAllContentWritten(_written); - } - - public boolean isAllContentWritten() - { - return _channel.getResponse().isAllContentWritten(_written); + synchronized (_channelState) + { + _softClose = false; + } } protected Blocker acquireWriteBlockingCallback() throws IOException @@ -219,125 +248,369 @@ public class HttpOutput extends ServletOutputStream implements Runnable return _writeBlocker.acquire(); } - private void abort(Throwable failure) + private void channelWrite(ByteBuffer content, boolean complete) throws IOException { - closed(); - _channel.abort(failure); + try (Blocker blocker = _writeBlocker.acquire()) + { + channelWrite(content, complete, blocker); + blocker.block(); + } } - @Override - public void close() + private void channelWrite(ByteBuffer content, boolean last, Callback callback) { - while (true) + if (_firstByteTimeStamp == -1) { - OutputState state = _state.get(); - switch (state) - { - case CLOSED: - { - return; - } - case ASYNC: - { - // A close call implies a write operation, thus in asynchronous mode - // a call to isReady() that returned true should have been made. - // However it is desirable to allow a close at any time, specially if - // complete is called. Thus we simulate a call to isReady here, assuming - // that we can transition to READY. - if (!_state.compareAndSet(state, OutputState.READY)) - continue; - break; - } - case UNREADY: - case PENDING: - { - // A close call implies a write operation, thus in asynchronous mode - // a call to isReady() that returned true should have been made. - // However it is desirable to allow a close at any time, specially if - // complete is called. Because the prior write has not yet completed - // and/or isReady has not been called, this close is allowed, but will - // abort the response. - if (!_state.compareAndSet(state, OutputState.CLOSED)) - continue; - IOException ex = new IOException("Closed while Pending/Unready"); - LOG.warn(ex.toString()); - LOG.debug(ex); - abort(ex); - return; - } - default: - { - if (!_state.compareAndSet(state, OutputState.CLOSED)) - continue; + long minDataRate = getHttpChannel().getHttpConfiguration().getMinResponseDataRate(); + if (minDataRate > 0) + _firstByteTimeStamp = System.nanoTime(); + else + _firstByteTimeStamp = Long.MAX_VALUE; + } - // Do a normal close by writing the aggregate buffer or an empty buffer. If we are - // not including, then indicate this is the last write. - try - { - write(BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER, !_channel.getResponse().isIncluding()); - } - catch (IOException x) - { - LOG.ignore(x); // Ignore it, it's been already logged in write(). - } - finally - { - releaseBuffer(); - } - // Return even if an exception is thrown by write(). - return; - } + _interceptor.write(content, last, callback); + } + + private void onWriteComplete(boolean last, Throwable failure) + { + String state = null; + boolean wake = false; + Callback closedCallback = null; + ByteBuffer closeContent = null; + synchronized (_channelState) + { + if (LOG.isDebugEnabled()) + state = stateString(); + + // Transition to CLOSED state if we were the last write or we have failed + if (last || failure != null) + { + _state = State.CLOSED; + closedCallback = _closedCallback; + _closedCallback = null; + releaseBuffer(); + wake = updateApiState(failure); + } + else if (_state == State.CLOSE) + { + // Somebody called close or complete while we were writing. + // We can now send a (probably empty) last buffer and then when it completes + // onWriteCompletion will be called again to actually execute the _completeCallback + _state = State.CLOSING; + closeContent = BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER; + } + else + { + wake = updateApiState(null); } } + + if (LOG.isDebugEnabled()) + LOG.debug("onWriteComplete({},{}) {}->{} c={} cb={} w={}", + last, failure, state, stateString(), BufferUtil.toDetailString(closeContent), closedCallback, wake); + + try + { + if (failure != null) + _channel.abort(failure); + + if (closedCallback != null) + { + if (failure == null) + closedCallback.succeeded(); + else + closedCallback.failed(failure); + } + else if (closeContent != null) + { + channelWrite(closeContent, true, new WriteCompleteCB()); + } + } + finally + { + if (wake) + _channel.execute(_channel); // TODO review in jetty-10 if execute is needed + } + } + + private boolean updateApiState(Throwable failure) + { + boolean wake = false; + switch (_apiState) + { + case BLOCKED: + _apiState = ApiState.BLOCKING; + break; + + case PENDING: + _apiState = ApiState.ASYNC; + if (failure != null) + { + _onError = failure; + wake = _channelState.onWritePossible(); + } + break; + + case UNREADY: + _apiState = ApiState.READY; + if (failure != null) + _onError = failure; + wake = _channelState.onWritePossible(); + break; + + default: + if (_state == State.CLOSED) + break; + throw new IllegalStateException(stateString()); + } + return wake; + } + + private int maximizeAggregateSpace() + { + // If no aggregate, we can allocate one of bufferSize + if (_aggregate == null) + return getBufferSize(); + + // compact to maximize space + BufferUtil.compact(_aggregate); + + return BufferUtil.space(_aggregate); + } + + public void softClose() + { + synchronized (_channelState) + { + _softClose = true; + } + } + + public void complete(Callback callback) + { + // This method is invoked for the COMPLETE action handling in + // HttpChannel.handle. The callback passed typically will call completed + // to finish the request cycle and so may need to asynchronously wait for: + // a pending/blocked operation to finish and then either an async close or + // wait for an application close to complete. + boolean succeeded = false; + Throwable error = null; + ByteBuffer content = null; + synchronized (_channelState) + { + switch (_state) + { + case CLOSED: + succeeded = true; + break; + + case CLOSE: + case CLOSING: + _closedCallback = Callback.combine(_closedCallback, callback); + break; + + case OPEN: + if (_onError != null) + { + error = _onError; + break; + } + + _closedCallback = Callback.combine(_closedCallback, callback); + + switch (_apiState) + { + case BLOCKING: + // Output is idle blocking state, but we still do an async close + _apiState = ApiState.BLOCKED; + _state = State.CLOSING; + content = BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER; + break; + + case ASYNC: + case READY: + // Output is idle in async state, so we can do an async close + _apiState = ApiState.PENDING; + _state = State.CLOSING; + content = BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER; + break; + + case BLOCKED: + case UNREADY: + case PENDING: + // An operation is in progress, so we soft close now + _softClose = true; + // then trigger a close from onWriteComplete + _state = State.CLOSE; + break; + } + break; + } + } + + if (LOG.isDebugEnabled()) + LOG.debug("complete({}) {} s={} e={}, c={}", callback, stateString(), succeeded, error, BufferUtil.toDetailString(content)); + + if (succeeded) + { + callback.succeeded(); + return; + } + + if (error != null) + { + callback.failed(error); + return; + } + + if (content != null) + channelWrite(content, true, new WriteCompleteCB()); } /** - * Called to indicate that the last write has been performed. - * It updates the state and performs cleanup operations. + * Called to indicate that the request cycle has been completed. */ - void closed() + public void completed() { - while (true) + synchronized (_channelState) { - OutputState state = _state.get(); - switch (state) + _state = State.CLOSED; + } + releaseBuffer(); + } + + @Override + public void close() throws IOException + { + ByteBuffer content = null; + Blocker blocker = null; + synchronized (_channelState) + { + if (_onError != null) + { + if (_onError instanceof IOException) + throw (IOException)_onError; + if (_onError instanceof RuntimeException) + throw (RuntimeException)_onError; + if (_onError instanceof Error) + throw (Error)_onError; + throw new IOException(_onError); + } + + switch (_state) { case CLOSED: - { - return; - } - case UNREADY: - { - if (_state.compareAndSet(state, OutputState.ERROR)) - _writeListener.onError(_onError == null ? new EofException("Async closed") : _onError); break; - } - default: - { - if (!_state.compareAndSet(state, OutputState.CLOSED)) - break; - try + case CLOSE: + case CLOSING: + switch (_apiState) { - _channel.getResponse().closeOutput(); + case BLOCKING: + case BLOCKED: + // block until CLOSED state reached. + blocker = _writeBlocker.acquire(); + _closedCallback = Callback.combine(_closedCallback, blocker); + break; + + default: + // async close with no callback, so nothing to do + break; } - catch (Throwable x) + break; + + case OPEN: + switch (_apiState) { - if (LOG.isDebugEnabled()) - LOG.debug(x); - abort(x); + case BLOCKING: + // Output is idle blocking state, but we still do an async close + _apiState = ApiState.BLOCKED; + _state = State.CLOSING; + blocker = _writeBlocker.acquire(); + content = BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER; + break; + + case BLOCKED: + // An blocking operation is in progress, so we soft close now + _softClose = true; + // then trigger a close from onWriteComplete + _state = State.CLOSE; + // and block until it is complete + blocker = _writeBlocker.acquire(); + _closedCallback = Callback.combine(_closedCallback, blocker); + break; + + case ASYNC: + case READY: + // Output is idle in async state, so we can do an async close + _apiState = ApiState.PENDING; + _state = State.CLOSING; + content = BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER; + break; + + case UNREADY: + case PENDING: + // An async operation is in progress, so we soft close now + _softClose = true; + // then trigger a close from onWriteComplete + _state = State.CLOSE; + break; } - finally - { - releaseBuffer(); - } - // Return even if an exception is thrown by closeOutput(). - return; + break; + } + } + + if (LOG.isDebugEnabled()) + LOG.debug("close() {} c={} b={}", stateString(), BufferUtil.toDetailString(content), blocker); + + if (content == null) + { + if (blocker == null) + // nothing to do or block for. + return; + + // Just wait for some other close to finish. + try (Blocker b = blocker) + { + b.block(); + } + } + else + { + if (blocker == null) + { + // Do an async close + channelWrite(content, true, new WriteCompleteCB()); + } + else + { + // Do a blocking close + try (Blocker b = blocker) + { + channelWrite(content, true, blocker); + b.block(); + onWriteComplete(true, null); + } + catch (Throwable t) + { + onWriteComplete(true, t); } } } } + public ByteBuffer getBuffer() + { + return _aggregate; + } + + public ByteBuffer acquireBuffer() + { + if (_aggregate == null) + _aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), _channel.isUseOutputDirectByteBuffers()); + return _aggregate; + } + private void releaseBuffer() { if (_aggregate != null) @@ -349,337 +622,379 @@ public class HttpOutput extends ServletOutputStream implements Runnable public boolean isClosed() { - return _state.get() == OutputState.CLOSED; + synchronized (_channelState) + { + return _softClose || (_state != State.OPEN); + } } public boolean isAsync() { - switch (_state.get()) + synchronized (_channelState) { - case ASYNC: - case READY: - case PENDING: - case UNREADY: - return true; - default: - return false; + switch (_apiState) + { + case ASYNC: + case READY: + case PENDING: + case UNREADY: + return true; + default: + return false; + } } } @Override public void flush() throws IOException { - while (true) + ByteBuffer content = null; + synchronized (_channelState) { - switch (_state.get()) + switch (_state) { - case OPEN: - write(BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER, false); - return; - - case ASYNC: - throw new IllegalStateException("isReady() not called"); - - case READY: - if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) - continue; - new AsyncFlush().iterate(); - return; - - case PENDING: - return; - - case UNREADY: - throw new WritePendingException(); - - case ERROR: - throw new EofException(_onError); - case CLOSED: + case CLOSING: return; default: - throw new IllegalStateException(); + { + switch (_apiState) + { + case BLOCKING: + _apiState = ApiState.BLOCKED; + content = BufferUtil.hasContent(_aggregate) ? _aggregate : BufferUtil.EMPTY_BUFFER; + break; + + case ASYNC: + case PENDING: + throw new IllegalStateException("isReady() not called: " + stateString()); + + case READY: + _apiState = ApiState.PENDING; + break; + + case UNREADY: + throw new WritePendingException(); + + default: + throw new IllegalStateException(stateString()); + } + } + } + } + + if (content == null) + new AsyncFlush(false).iterate(); + else + { + try + { + channelWrite(content, false); + onWriteComplete(false, null); + } + catch (Throwable t) + { + onWriteComplete(false, t); + throw t; } } } - private void write(ByteBuffer content, boolean complete) throws IOException + private void checkWritable() throws EofException { - try (Blocker blocker = _writeBlocker.acquire()) - { - write(content, complete, blocker); - blocker.block(); - } - catch (Exception failure) - { - if (LOG.isDebugEnabled()) - LOG.debug(failure); - abort(failure); - if (failure instanceof IOException) - throw failure; - throw new IOException(failure); - } - } + if (_softClose) + throw new EofException("Closed"); - protected void write(ByteBuffer content, boolean complete, Callback callback) - { - if (_firstByteTimeStamp == -1) + switch (_state) { - long minDataRate = getHttpChannel().getHttpConfiguration().getMinResponseDataRate(); - if (minDataRate > 0) - _firstByteTimeStamp = System.nanoTime(); - else - _firstByteTimeStamp = Long.MAX_VALUE; + case CLOSED: + case CLOSING: + throw new EofException("Closed"); + + default: + break; } - _interceptor.write(content, complete, callback); + + if (_onError != null) + throw new EofException(_onError); } @Override public void write(byte[] b, int off, int len) throws IOException { + if (LOG.isDebugEnabled()) + LOG.debug("write(array {})", BufferUtil.toDetailString(ByteBuffer.wrap(b, off, len))); + + boolean last; + boolean aggregate; + boolean flush; + // Async or Blocking ? - while (true) + boolean async; + synchronized (_channelState) { - switch (_state.get()) + checkWritable(); + long written = _written + len; + int space = maximizeAggregateSpace(); + last = _channel.getResponse().isAllContentWritten(written); + // Write will be aggregated if: + // + it is smaller than the commitSize + // + is not the last one, or is last but will fit in an already allocated aggregate buffer. + aggregate = len <= _commitSize && (!last || BufferUtil.hasContent(_aggregate) && len <= space); + flush = last || !aggregate || len >= space; + + if (last && _state == State.OPEN) + _state = State.CLOSING; + + switch (_apiState) { - case OPEN: - // process blocking below + case BLOCKING: + _apiState = flush ? ApiState.BLOCKED : ApiState.BLOCKING; + async = false; break; case ASYNC: - throw new IllegalStateException("isReady() not called"); + throw new IllegalStateException("isReady() not called: " + stateString()); case READY: - if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) - continue; - - // Should we aggregate? - boolean last = isLastContentToWrite(len); - if (!last && len <= _commitSize) - { - if (_aggregate == null) - _aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers()); - - // YES - fill the aggregate with content from the buffer - int filled = BufferUtil.fill(_aggregate, b, off, len); - - // return if we are not complete, not full and filled all the content - if (filled == len && !BufferUtil.isFull(_aggregate)) - { - if (!_state.compareAndSet(OutputState.PENDING, OutputState.ASYNC)) - throw new IllegalStateException(); - return; - } - - // adjust offset/length - off += filled; - len -= filled; - } - - // Do the asynchronous writing from the callback - new AsyncWrite(b, off, len, last).iterate(); - return; + async = true; + _apiState = flush ? ApiState.PENDING : ApiState.ASYNC; + break; case PENDING: case UNREADY: throw new WritePendingException(); - case ERROR: - throw new EofException(_onError); - - case CLOSED: - throw new EofException("Closed"); - default: - throw new IllegalStateException(); + throw new IllegalStateException(stateString()); } - break; - } - // handle blocking write + _written = written; - // Should we aggregate? - int capacity = getBufferSize(); - boolean last = isLastContentToWrite(len); - if (!last && len <= _commitSize) - { - if (_aggregate == null) - _aggregate = _channel.getByteBufferPool().acquire(capacity, _interceptor.isOptimizedForDirectBuffers()); - - // YES - fill the aggregate with content from the buffer - int filled = BufferUtil.fill(_aggregate, b, off, len); - - // return if we are not complete, not full and filled all the content - if (filled == len && !BufferUtil.isFull(_aggregate)) - return; - - // adjust offset/length - off += filled; - len -= filled; - } - - // flush any content from the aggregate - if (BufferUtil.hasContent(_aggregate)) - { - write(_aggregate, last && len == 0); - - // should we fill aggregate again from the buffer? - if (len > 0 && !last && len <= _commitSize && len <= BufferUtil.space(_aggregate)) + // Should we aggregate? + if (aggregate) { - BufferUtil.append(_aggregate, b, off, len); - return; + acquireBuffer(); + int filled = BufferUtil.fill(_aggregate, b, off, len); + + // return if we are not complete, not full and filled all the content + if (!flush) + { + if (LOG.isDebugEnabled()) + LOG.debug("write(array) {} aggregated !flush {}", + stateString(), BufferUtil.toDetailString(_aggregate)); + return; + } + + // adjust offset/length + off += filled; + len -= filled; } } - // write any remaining content in the buffer directly - if (len > 0) + if (LOG.isDebugEnabled()) + LOG.debug("write(array) {} last={} agg={} flush=true async={}, len={} {}", + stateString(), last, aggregate, async, len, BufferUtil.toDetailString(_aggregate)); + + if (async) { - // write a buffer capacity at a time to avoid JVM pooling large direct buffers - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6210541 - ByteBuffer view = ByteBuffer.wrap(b, off, len); - while (len > getBufferSize()) + // Do the asynchronous writing from the callback + new AsyncWrite(b, off, len, last).iterate(); + return; + } + + // Blocking write + try + { + // flush any content from the aggregate + if (BufferUtil.hasContent(_aggregate)) { - final int p = view.position(); - final int l = p + getBufferSize(); - view.limit(p + getBufferSize()); - write(view, false); - len -= getBufferSize(); - view.limit(l + Math.min(len, getBufferSize())); - view.position(l); - } - write(view, last); - } - else if (last) - { - write(BufferUtil.EMPTY_BUFFER, true); - } + channelWrite(_aggregate, last && len == 0); - if (last) - closed(); + // should we fill aggregate again from the buffer? + if (len > 0 && !last && len <= _commitSize && len <= maximizeAggregateSpace()) + { + BufferUtil.append(_aggregate, b, off, len); + onWriteComplete(false, null); + return; + } + } + + // write any remaining content in the buffer directly + if (len > 0) + { + // write a buffer capacity at a time to avoid JVM pooling large direct buffers + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6210541 + ByteBuffer view = ByteBuffer.wrap(b, off, len); + + while (len > getBufferSize()) + { + int p = view.position(); + int l = p + getBufferSize(); + view.limit(l); + channelWrite(view, false); + view.limit(p + len); + view.position(l); + len -= getBufferSize(); + } + channelWrite(view, last); + } + else if (last) + { + channelWrite(BufferUtil.EMPTY_BUFFER, true); + } + + onWriteComplete(last, null); + } + catch (Throwable t) + { + onWriteComplete(last, t); + throw t; + } } public void write(ByteBuffer buffer) throws IOException { // This write always bypasses aggregate buffer + int len = BufferUtil.length(buffer); + boolean flush; + boolean last; // Async or Blocking ? - while (true) + boolean async; + synchronized (_channelState) { - switch (_state.get()) + checkWritable(); + long written = _written + len; + last = _channel.getResponse().isAllContentWritten(_written); + flush = last || len > 0 || BufferUtil.hasContent(_aggregate); + + if (last && _state == State.OPEN) + _state = State.CLOSING; + + switch (_apiState) { - case OPEN: - // process blocking below + case BLOCKING: + async = false; + _apiState = flush ? ApiState.BLOCKED : ApiState.BLOCKING; break; case ASYNC: - throw new IllegalStateException("isReady() not called"); + throw new IllegalStateException("isReady() not called: " + stateString()); case READY: - if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) - continue; - - // Do the asynchronous writing from the callback - boolean last = isLastContentToWrite(buffer.remaining()); - new AsyncWrite(buffer, last).iterate(); - return; + async = true; + _apiState = flush ? ApiState.PENDING : ApiState.ASYNC; + break; case PENDING: case UNREADY: throw new WritePendingException(); - case ERROR: - throw new EofException(_onError); - - case CLOSED: - throw new EofException("Closed"); - default: - throw new IllegalStateException(); + throw new IllegalStateException(stateString()); } - break; + _written = written; } - // handle blocking write - int len = BufferUtil.length(buffer); - boolean last = isLastContentToWrite(len); + if (!flush) + return; - // flush any content from the aggregate - if (BufferUtil.hasContent(_aggregate)) - write(_aggregate, last && len == 0); + if (async) + { + new AsyncWrite(buffer, last).iterate(); + } + else + { + try + { + // Blocking write + // flush any content from the aggregate + if (BufferUtil.hasContent(_aggregate)) + channelWrite(_aggregate, last && len == 0); - // write any remaining content in the buffer directly - if (len > 0) - write(buffer, last); - else if (last) - write(BufferUtil.EMPTY_BUFFER, true); + // write any remaining content in the buffer directly + if (len > 0) + channelWrite(buffer, last); + else if (last) + channelWrite(BufferUtil.EMPTY_BUFFER, true); - if (last) - closed(); + onWriteComplete(last, null); + } + catch (Throwable t) + { + onWriteComplete(last, t); + throw t; + } + } } @Override public void write(int b) throws IOException { - _written += 1; - boolean complete = _channel.getResponse().isAllContentWritten(_written); - + boolean flush; + boolean last; // Async or Blocking ? - while (true) - { - switch (_state.get()) - { - case OPEN: - if (_aggregate == null) - _aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers()); - BufferUtil.append(_aggregate, (byte)b); - // Check if all written or full - if (complete || BufferUtil.isFull(_aggregate)) - { - write(_aggregate, complete); - if (complete) - closed(); - } + boolean async = false; + synchronized (_channelState) + { + checkWritable(); + long written = _written + 1; + int space = maximizeAggregateSpace(); + last = _channel.getResponse().isAllContentWritten(written); + flush = last || space == 1; + + if (last && _state == State.OPEN) + _state = State.CLOSING; + + switch (_apiState) + { + case BLOCKING: + _apiState = flush ? ApiState.BLOCKED : ApiState.BLOCKING; break; case ASYNC: - throw new IllegalStateException("isReady() not called"); + throw new IllegalStateException("isReady() not called: " + stateString()); case READY: - if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) - continue; - - if (_aggregate == null) - _aggregate = _channel.getByteBufferPool().acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers()); - BufferUtil.append(_aggregate, (byte)b); - - // Check if all written or full - if (!complete && !BufferUtil.isFull(_aggregate)) - { - if (!_state.compareAndSet(OutputState.PENDING, OutputState.ASYNC)) - throw new IllegalStateException(); - return; - } - - // Do the asynchronous writing from the callback - new AsyncFlush().iterate(); - return; + async = true; + _apiState = flush ? ApiState.PENDING : ApiState.ASYNC; + break; case PENDING: case UNREADY: throw new WritePendingException(); - case ERROR: - throw new EofException(_onError); - - case CLOSED: - throw new EofException("Closed"); - default: - throw new IllegalStateException(); + throw new IllegalStateException(stateString()); + } + _written = written; + + acquireBuffer(); + BufferUtil.append(_aggregate, (byte)b); + } + + // Check if all written or full + if (!flush) + return; + + if (async) + // Do the asynchronous writing from the callback + new AsyncFlush(last).iterate(); + else + { + try + { + channelWrite(_aggregate, last); + onWriteComplete(last, null); + } + catch (Throwable t) + { + onWriteComplete(last, t); + throw t; } - break; } } @@ -689,6 +1004,12 @@ public class HttpOutput extends ServletOutputStream implements Runnable print(s, false); } + @Override + public void println(String s) throws IOException + { + print(s, true); + } + private void print(String s, boolean eoln) throws IOException { if (isClosed()) @@ -713,7 +1034,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable ByteBuffer out = getHttpChannel().getByteBufferPool().acquire((int)(1 + (s.length() + 2) * encoder.averageBytesPerChar()), false); BufferUtil.flipToFill(out); - for (; ; ) + while (true) { CoderResult result; if (in.hasRemaining()) @@ -755,48 +1076,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable getHttpChannel().getByteBufferPool().release(out); } - @Override - public void println(String s) throws IOException - { - print(s, true); - } - - @Override - public void println(boolean b) throws IOException - { - println(lStrings.getString(b ? "value.true" : "value.false")); - } - - @Override - public void println(char c) throws IOException - { - println(String.valueOf(c)); - } - - @Override - public void println(int i) throws IOException - { - println(String.valueOf(i)); - } - - @Override - public void println(long l) throws IOException - { - println(String.valueOf(l)); - } - - @Override - public void println(float f) throws IOException - { - println(String.valueOf(f)); - } - - @Override - public void println(double d) throws IOException - { - println(String.valueOf(d)); - } - /** * Blocking send of whole content. * @@ -809,8 +1088,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable LOG.debug("sendContent({})", BufferUtil.toDetailString(content)); _written += content.remaining(); - write(content, true); - closed(); + channelWrite(content, true); } /** @@ -826,13 +1104,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable new InputStreamWritingCB(in, blocker).iterate(); blocker.block(); } - catch (Throwable failure) - { - if (LOG.isDebugEnabled()) - LOG.debug(failure); - abort(failure); - throw failure; - } } /** @@ -848,13 +1119,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable new ReadableByteChannelWritingCB(in, blocker).iterate(); blocker.block(); } - catch (Throwable failure) - { - if (LOG.isDebugEnabled()) - LOG.debug(failure); - abort(failure); - throw failure; - } } /** @@ -870,13 +1134,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable sendContent(content, blocker); blocker.block(); } - catch (Throwable failure) - { - if (LOG.isDebugEnabled()) - LOG.debug(failure); - abort(failure); - throw failure; - } } /** @@ -890,23 +1147,24 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (LOG.isDebugEnabled()) LOG.debug("sendContent(buffer={},{})", BufferUtil.toDetailString(content), callback); - _written += content.remaining(); - write(content, true, new Callback.Nested(callback) - { - @Override - public void succeeded() - { - closed(); - super.succeeded(); - } + if (prepareSendContent(content.remaining(), callback)) + channelWrite(content, true, + new Callback.Nested(callback) + { + @Override + public void succeeded() + { + onWriteComplete(true, null); + super.succeeded(); + } - @Override - public void failed(Throwable x) - { - abort(x); - super.failed(x); - } - }); + @Override + public void failed(Throwable x) + { + onWriteComplete(true, x); + super.failed(x); + } + }); } /** @@ -921,7 +1179,8 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (LOG.isDebugEnabled()) LOG.debug("sendContent(stream={},{})", in, callback); - new InputStreamWritingCB(in, callback).iterate(); + if (prepareSendContent(0, callback)) + new InputStreamWritingCB(in, callback).iterate(); } /** @@ -936,7 +1195,50 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (LOG.isDebugEnabled()) LOG.debug("sendContent(channel={},{})", in, callback); - new ReadableByteChannelWritingCB(in, callback).iterate(); + if (prepareSendContent(0, callback)) + new ReadableByteChannelWritingCB(in, callback).iterate(); + } + + private boolean prepareSendContent(int len, Callback callback) + { + synchronized (_channelState) + { + if (BufferUtil.hasContent(_aggregate)) + { + callback.failed(new IOException("cannot sendContent() after write()")); + return false; + } + if (_channel.isCommitted()) + { + callback.failed(new IOException("cannot sendContent(), output already committed")); + return false; + } + + switch (_state) + { + case CLOSED: + case CLOSING: + callback.failed(new EofException("Closed")); + return false; + + default: + _state = State.CLOSING; + break; + } + + if (_onError != null) + { + callback.failed(_onError); + return false; + } + + if (_apiState != ApiState.BLOCKING) + throw new IllegalStateException(stateString()); + _apiState = ApiState.PENDING; + if (len > 0) + _written += len; + return true; + } } /** @@ -950,41 +1252,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (LOG.isDebugEnabled()) LOG.debug("sendContent(http={},{})", httpContent, callback); - if (BufferUtil.hasContent(_aggregate)) - { - callback.failed(new IOException("cannot sendContent() after write()")); - return; - } - if (_channel.isCommitted()) - { - callback.failed(new IOException("cannot sendContent(), output already committed")); - return; - } - - while (true) - { - switch (_state.get()) - { - case OPEN: - if (!_state.compareAndSet(OutputState.OPEN, OutputState.PENDING)) - continue; - break; - - case ERROR: - callback.failed(new EofException(_onError)); - return; - - case CLOSED: - callback.failed(new EofException("Closed")); - return; - - default: - throw new IllegalStateException(); - } - break; - } - - ByteBuffer buffer = _channel.useDirectBuffers() ? httpContent.getDirectBuffer() : null; + ByteBuffer buffer = _channel.isUseOutputDirectByteBuffers() ? httpContent.getDirectBuffer() : null; if (buffer == null) buffer = httpContent.getIndirectBuffer(); @@ -994,30 +1262,40 @@ public class HttpOutput extends ServletOutputStream implements Runnable return; } + ReadableByteChannel rbc = null; try { - ReadableByteChannel rbc = httpContent.getReadableByteChannel(); - if (rbc != null) - { - // Close of the rbc is done by the async sendContent - sendContent(rbc, callback); - return; - } - - InputStream in = httpContent.getInputStream(); - if (in != null) - { - sendContent(in, callback); - return; - } - - throw new IllegalArgumentException("unknown content for " + httpContent); + rbc = httpContent.getReadableByteChannel(); } - catch (Throwable th) + catch (Throwable x) { - abort(th); - callback.failed(th); + LOG.debug("Unable to access ReadableByteChannel for content {}", httpContent, x); } + if (rbc != null) + { + // Close of the rbc is done by the async sendContent + sendContent(rbc, callback); + return; + } + + InputStream in = null; + try + { + in = httpContent.getInputStream(); + } + catch (Throwable x) + { + LOG.debug("Unable to access InputStream for content {}", httpContent, x); + } + if (in != null) + { + sendContent(in, callback); + return; + } + + Throwable cause = new IllegalArgumentException("unknown content for " + httpContent); + _channel.abort(cause); + callback.failed(cause); } public int getBufferSize() @@ -1061,19 +1339,25 @@ public class HttpOutput extends ServletOutputStream implements Runnable public void recycle() { - _interceptor = _channel; - HttpConfiguration config = _channel.getHttpConfiguration(); - _bufferSize = config.getOutputBufferSize(); - _commitSize = config.getOutputAggregationSize(); - if (_commitSize > _bufferSize) - _commitSize = _bufferSize; - releaseBuffer(); - _written = 0; - _writeListener = null; - _onError = null; - _firstByteTimeStamp = -1; - _flushed = 0; - reopen(); + synchronized (_channelState) + { + _state = State.OPEN; + _apiState = ApiState.BLOCKING; + _softClose = false; + _interceptor = _channel; + HttpConfiguration config = _channel.getHttpConfiguration(); + _bufferSize = config.getOutputBufferSize(); + _commitSize = config.getOutputAggregationSize(); + if (_commitSize > _bufferSize) + _commitSize = _bufferSize; + releaseBuffer(); + _written = 0; + _writeListener = null; + _onError = null; + _firstByteTimeStamp = -1; + _flushed = 0; + _closedCallback = null; + } } public void resetBuffer() @@ -1082,59 +1366,51 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (BufferUtil.hasContent(_aggregate)) BufferUtil.clear(_aggregate); _written = 0; - reopen(); } @Override public void setWriteListener(WriteListener writeListener) { if (!_channel.getState().isAsync()) - throw new IllegalStateException("!ASYNC"); - - if (_state.compareAndSet(OutputState.OPEN, OutputState.READY)) + throw new IllegalStateException("!ASYNC: " + stateString()); + boolean wake; + synchronized (_channelState) { + if (_apiState != ApiState.BLOCKING) + throw new IllegalStateException("!OPEN" + stateString()); + _apiState = ApiState.READY; _writeListener = writeListener; - if (_channel.getState().onWritePossible()) - _channel.execute(_channel); + wake = _channel.getState().onWritePossible(); } - else - throw new IllegalStateException(); + if (wake) + _channel.execute(_channel); } @Override public boolean isReady() { - while (true) + synchronized (_channelState) { - switch (_state.get()) + switch (_apiState) { - case OPEN: - return true; - - case ASYNC: - if (!_state.compareAndSet(OutputState.ASYNC, OutputState.READY)) - continue; - return true; - + case BLOCKING: case READY: return true; + case ASYNC: + _apiState = ApiState.READY; + return true; + case PENDING: - if (!_state.compareAndSet(OutputState.PENDING, OutputState.UNREADY)) - continue; + _apiState = ApiState.UNREADY; return false; + case BLOCKED: case UNREADY: return false; - case ERROR: - return true; - - case CLOSED: - return true; - default: - throw new IllegalStateException(); + throw new IllegalStateException(stateString()); } } } @@ -1142,83 +1418,70 @@ public class HttpOutput extends ServletOutputStream implements Runnable @Override public void run() { - while (true) - { - OutputState state = _state.get(); + Throwable error = null; + synchronized (_channelState) + { if (_onError != null) { - switch (state) - { - case CLOSED: - case ERROR: - { - _onError = null; - return; - } - default: - { - if (_state.compareAndSet(state, OutputState.ERROR)) - { - Throwable th = _onError; - _onError = null; - if (LOG.isDebugEnabled()) - LOG.debug("onError", th); - - try - { - _writeListener.onError(th); - } - finally - { - IO.close(this); - } - - return; - } - } - } - continue; - } - - // We do not check the state here. Strictly speaking the state should - // always be READY when run is called. However, other async threads or - // a prior call by this thread to onDataAvailable may have called write - // after onWritePossible was called, so the state could be any of the - // write states. - // - // Even if the state is CLOSED, we need to call onWritePossible to tell - // async producer that the last write completed. - // - // We have to trust the scheduling of this run was done - // for good reason, that is protected correctly by HttpChannelState and - // that implementations of onWritePossible will - // themselves check isReady(). If multiple threads are calling write, - // then they must either rely on only a single container thread being - // dispatched or perform their own mutual exclusion. - try - { - _writeListener.onWritePossible(); - break; - } - catch (Throwable e) - { - _onError = e; + error = _onError; + _onError = null; } } + + try + { + if (error == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("onWritePossible"); + _writeListener.onWritePossible(); + return; + } + } + catch (Throwable t) + { + error = t; + } + try + { + if (LOG.isDebugEnabled()) + LOG.debug("onError", error); + _writeListener.onError(error); + } + catch (Throwable t) + { + if (LOG.isDebugEnabled()) + { + t.addSuppressed(error); + LOG.debug("Failed in call onError on {}", _writeListener, t); + } + } + finally + { + IO.close(this); + } + } + + private String stateString() + { + return String.format("s=%s,api=%s,sc=%b,e=%s", _state, _apiState, _softClose, _onError); } @Override public String toString() { - return String.format("%s@%x{%s}", this.getClass().getSimpleName(), hashCode(), _state.get()); + synchronized (_channelState) + { + return String.format("%s@%x{%s}", this.getClass().getSimpleName(), hashCode(), stateString()); + } } - private abstract class AsyncICB extends IteratingCallback + private abstract class ChannelWriteCB extends IteratingCallback { final boolean _last; - AsyncICB(boolean last) + ChannelWriteCB(boolean last) { _last = last; } @@ -1232,67 +1495,81 @@ public class HttpOutput extends ServletOutputStream implements Runnable @Override protected void onCompleteSuccess() { - while (true) + onWriteComplete(_last, null); + } + + @Override + public void onCompleteFailure(Throwable e) + { + onWriteComplete(_last, e); + } + } + + private abstract class NestedChannelWriteCB extends ChannelWriteCB + { + final Callback _callback; + + NestedChannelWriteCB(Callback callback, boolean last) + { + super(last); + _callback = callback; + } + + @Override + protected void onCompleteSuccess() + { + try { - OutputState last = _state.get(); - switch (last) - { - case PENDING: - if (!_state.compareAndSet(OutputState.PENDING, OutputState.ASYNC)) - continue; - break; - - case UNREADY: - if (!_state.compareAndSet(OutputState.UNREADY, OutputState.READY)) - continue; - if (_last) - closed(); - if (_channel.getState().onWritePossible()) - _channel.execute(_channel); - break; - - case CLOSED: - break; - - default: - throw new IllegalStateException(); - } - break; + super.onCompleteSuccess(); + } + finally + { + _callback.succeeded(); } } @Override public void onCompleteFailure(Throwable e) { - _onError = e == null ? new IOException() : e; - if (_channel.getState().onWritePossible()) - _channel.execute(_channel); + try + { + super.onCompleteFailure(e); + } + catch (Throwable t) + { + if (t != e) + e.addSuppressed(t); + } + finally + { + _callback.failed(e); + } } } - private class AsyncFlush extends AsyncICB + private class AsyncFlush extends ChannelWriteCB { - protected volatile boolean _flushed; + volatile boolean _flushed; - public AsyncFlush() + AsyncFlush(boolean last) { - super(false); + super(last); } @Override - protected Action process() + protected Action process() throws Exception { if (BufferUtil.hasContent(_aggregate)) { _flushed = true; - write(_aggregate, false, this); + channelWrite(_aggregate, false, this); return Action.SCHEDULED; } if (!_flushed) { _flushed = true; - write(BufferUtil.EMPTY_BUFFER, false, this); + channelWrite(BufferUtil.EMPTY_BUFFER, false, this); return Action.SCHEDULED; } @@ -1300,14 +1577,14 @@ public class HttpOutput extends ServletOutputStream implements Runnable } } - private class AsyncWrite extends AsyncICB + private class AsyncWrite extends ChannelWriteCB { private final ByteBuffer _buffer; private final ByteBuffer _slice; private final int _len; - protected volatile boolean _completed; + private boolean _completed; - public AsyncWrite(byte[] b, int off, int len, boolean last) + AsyncWrite(byte[] b, int off, int len, boolean last) { super(last); _buffer = ByteBuffer.wrap(b, off, len); @@ -1316,7 +1593,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable _slice = _len < getBufferSize() ? null : _buffer.duplicate(); } - public AsyncWrite(ByteBuffer buffer, boolean last) + AsyncWrite(ByteBuffer buffer, boolean last) { super(last); _buffer = buffer; @@ -1331,18 +1608,18 @@ public class HttpOutput extends ServletOutputStream implements Runnable } @Override - protected Action process() + protected Action process() throws Exception { // flush any content from the aggregate if (BufferUtil.hasContent(_aggregate)) { _completed = _len == 0; - write(_aggregate, _last && _completed, this); + channelWrite(_aggregate, _last && _completed, this); return Action.SCHEDULED; } // Can we just aggregate the remainder? - if (!_last && _len < BufferUtil.space(_aggregate) && _len < _commitSize) + if (!_last && _aggregate != null && _len < maximizeAggregateSpace() && _len < _commitSize) { int position = BufferUtil.flipToFill(_aggregate); BufferUtil.put(_buffer, _aggregate); @@ -1357,7 +1634,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (_slice == null) { _completed = true; - write(_buffer, _last, this); + channelWrite(_buffer, _last, this); return Action.SCHEDULED; } @@ -1369,7 +1646,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable _buffer.position(pl); _slice.position(p); _completed = !_buffer.hasRemaining(); - write(_slice, _last && _completed, this); + channelWrite(_slice, _last && _completed, this); return Action.SCHEDULED; } @@ -1378,12 +1655,13 @@ public class HttpOutput extends ServletOutputStream implements Runnable if (_last && !_completed) { _completed = true; - write(BufferUtil.EMPTY_BUFFER, true, this); + channelWrite(BufferUtil.EMPTY_BUFFER, true, this); return Action.SCHEDULED; } if (LOG.isDebugEnabled() && _completed) LOG.debug("EOF of {}", this); + return Action.SUCCEEDED; } } @@ -1396,16 +1674,18 @@ public class HttpOutput extends ServletOutputStream implements Runnable * be notified as each buffer is written and only once all the input is consumed will the * wrapped {@link Callback#succeeded()} method be called. */ - private class InputStreamWritingCB extends IteratingNestedCallback + private class InputStreamWritingCB extends NestedChannelWriteCB { private final InputStream _in; private final ByteBuffer _buffer; private boolean _eof; + private boolean _closed; - public InputStreamWritingCB(InputStream in, Callback callback) + InputStreamWritingCB(InputStream in, Callback callback) { - super(callback); + super(callback, true); _in = in; + // Reading from InputStream requires byte[], don't use direct buffers. _buffer = _channel.getByteBufferPool().acquire(getBufferSize(), false); } @@ -1418,10 +1698,13 @@ public class HttpOutput extends ServletOutputStream implements Runnable { if (LOG.isDebugEnabled()) LOG.debug("EOF of {}", this); - // Handle EOF - _in.close(); - closed(); - _channel.getByteBufferPool().release(_buffer); + if (!_closed) + { + _closed = true; + _channel.getByteBufferPool().release(_buffer); + IO.close(_in); + } + return Action.SUCCEEDED; } @@ -1440,17 +1723,21 @@ public class HttpOutput extends ServletOutputStream implements Runnable _buffer.position(0); _buffer.limit(len); _written += len; - write(_buffer, _eof, this); + channelWrite(_buffer, _eof, this); return Action.SCHEDULED; } @Override public void onCompleteFailure(Throwable x) { - abort(x); - _channel.getByteBufferPool().release(_buffer); - IO.close(_in); - super.onCompleteFailure(x); + try + { + _channel.getByteBufferPool().release(_buffer); + } + finally + { + super.onCompleteFailure(x); + } } } @@ -1458,22 +1745,23 @@ public class HttpOutput extends ServletOutputStream implements Runnable * An iterating callback that will take content from a * ReadableByteChannel and write it to the {@link HttpChannel}. * A {@link ByteBuffer} of size {@link HttpOutput#getBufferSize()} is used that will be direct if - * {@link HttpChannel#useDirectBuffers()} is true. + * {@link HttpChannel#isUseOutputDirectByteBuffers()} is true. * This callback is passed to the {@link HttpChannel#write(ByteBuffer, boolean, Callback)} to * be notified as each buffer is written and only once all the input is consumed will the * wrapped {@link Callback#succeeded()} method be called. */ - private class ReadableByteChannelWritingCB extends IteratingNestedCallback + private class ReadableByteChannelWritingCB extends NestedChannelWriteCB { private final ReadableByteChannel _in; private final ByteBuffer _buffer; private boolean _eof; + private boolean _closed; - public ReadableByteChannelWritingCB(ReadableByteChannel in, Callback callback) + ReadableByteChannelWritingCB(ReadableByteChannel in, Callback callback) { - super(callback); + super(callback, true); _in = in; - _buffer = _channel.getByteBufferPool().acquire(getBufferSize(), _channel.useDirectBuffers()); + _buffer = _channel.getByteBufferPool().acquire(getBufferSize(), _channel.isUseOutputDirectByteBuffers()); } @Override @@ -1485,9 +1773,12 @@ public class HttpOutput extends ServletOutputStream implements Runnable { if (LOG.isDebugEnabled()) LOG.debug("EOF of {}", this); - _in.close(); - closed(); - _channel.getByteBufferPool().release(_buffer); + if (!_closed) + { + _closed = true; + _channel.getByteBufferPool().release(_buffer); + IO.close(_in); + } return Action.SUCCEEDED; } @@ -1501,7 +1792,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable // write what we have BufferUtil.flipToFlush(_buffer, 0); _written += _buffer.remaining(); - write(_buffer, _eof, this); + channelWrite(_buffer, _eof, this); return Action.SCHEDULED; } @@ -1509,7 +1800,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable @Override public void onCompleteFailure(Throwable x) { - abort(x); _channel.getByteBufferPool().release(_buffer); IO.close(_in); super.onCompleteFailure(x); @@ -1525,4 +1815,19 @@ public class HttpOutput extends ServletOutputStream implements Runnable _channel = channel; } } + + private class WriteCompleteCB implements Callback + { + @Override + public void succeeded() + { + onWriteComplete(true, null); + } + + @Override + public void failed(Throwable x) + { + onWriteComplete(true, x); + } + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java index 2d6faeaa447..99a50aebd1b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -28,17 +28,19 @@ import org.eclipse.jetty.util.Callback; */ public interface HttpTransport { + String UPGRADE_CONNECTION_ATTRIBUTE = HttpTransport.class.getName() + ".UPGRADE"; + /** * Asynchronous call to send a response (or part) over the transport * - * @param info The header info to send, or null if just sending more data. - * The first call to send for a response must have a non null info. - * @param head True if the response if for a HEAD request (and the data should not be sent). + * @param request True if the response if for a HEAD request (and the data should not be sent). + * @param response The header info to send, or null if just sending more data. + * The first call to send for a response must have a non null info. * @param content A buffer of content to be sent. * @param lastContent True if the content is the last content for the current response. * @param callback The Callback instance that success or failure of the send is notified on */ - void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback); + void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback); /** * @return true if responses can be pushed over this transport @@ -55,7 +57,7 @@ public interface HttpTransport * some time after the last content is sent). */ void onCompleted(); - + /** * Aborts this transport. *

      @@ -71,11 +73,4 @@ public interface HttpTransport * @param failure the failure that caused the abort. */ void abort(Throwable failure); - - /** - * Is the underlying transport optimized for DirectBuffer usage - * - * @return True if direct buffers can be used optimally. - */ - boolean isOptimizedForDirectBuffers(); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpWriter.java index 20b42e20760..ee89d1e1eea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -22,13 +22,14 @@ import java.io.IOException; import java.io.Writer; import org.eclipse.jetty.util.ByteArrayOutputStream2; +import org.eclipse.jetty.util.Callback; /** * */ public abstract class HttpWriter extends Writer { - public static final int MAX_OUTPUT_CHARS = 512; + public static final int MAX_OUTPUT_CHARS = 512; // TODO should this be configurable? super size is 1024 final HttpOutput _out; final ByteArrayOutputStream2 _bytes; @@ -38,7 +39,7 @@ public abstract class HttpWriter extends Writer { _out = out; _chars = new char[MAX_OUTPUT_CHARS]; - _bytes = new ByteArrayOutputStream2(MAX_OUTPUT_CHARS); + _bytes = new ByteArrayOutputStream2(MAX_OUTPUT_CHARS); // TODO should this be pooled - or do we just recycle the writer? } @Override @@ -47,6 +48,11 @@ public abstract class HttpWriter extends Writer _out.close(); } + public void complete(Callback callback) + { + _out.complete(callback); + } + @Override public void flush() throws IOException { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/InclusiveByteRange.java b/jetty-server/src/main/java/org/eclipse/jetty/server/InclusiveByteRange.java index ac2e362f089..931538af2d1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/InclusiveByteRange.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/InclusiveByteRange.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -24,8 +24,8 @@ import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Byte range inclusive of end points. @@ -52,7 +52,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class InclusiveByteRange { - private static final Logger LOG = Log.getLogger(InclusiveByteRange.class); + private static final Logger LOG = LoggerFactory.getLogger(InclusiveByteRange.class); private long first; private long last; @@ -237,14 +237,14 @@ public class InclusiveByteRange catch (NumberFormatException e) { LOG.warn("Bad range format: {}", t); - LOG.ignore(e); + LOG.trace("IGNORED", e); } } } catch (Exception e) { LOG.warn("Bad range format: {}", t); - LOG.ignore(e); + LOG.trace("IGNORED", e); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Iso88591HttpWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Iso88591HttpWriter.java index 1c8c9b444df..db284303706 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Iso88591HttpWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Iso88591HttpWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -35,11 +35,6 @@ public class Iso88591HttpWriter extends HttpWriter public void write(char[] s, int offset, int length) throws IOException { HttpOutput out = _out; - if (length == 0 && out.isAllContentWritten()) - { - close(); - return; - } if (length == 1) { @@ -51,7 +46,7 @@ public class Iso88591HttpWriter extends HttpWriter while (length > 0) { _bytes.reset(); - int chars = length > MAX_OUTPUT_CHARS ? MAX_OUTPUT_CHARS : length; + int chars = Math.min(length, MAX_OUTPUT_CHARS); byte[] buffer = _bytes.getBuf(); int bytes = _bytes.getCount(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java index d1c353cfd97..93de8472028 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -98,6 +98,8 @@ public class LocalConnector extends AbstractConnector { if (!isStarted()) throw new IllegalStateException("!STARTED"); + if (isShutdown()) + throw new IllegalStateException("Shutdown"); LocalEndPoint endp = new LocalEndPoint(); endp.addInput(rawRequest); _connects.add(endp); @@ -276,7 +278,7 @@ public class LocalConnector extends AbstractConnector } catch (Exception e) { - LOG.warn(e); + LOG.warn("Close wait failed", e); } } } @@ -302,7 +304,7 @@ public class LocalConnector extends AbstractConnector } catch (Exception e) { - LOG.warn(e); + LOG.warn("Close wait failed", e); } } } @@ -381,18 +383,6 @@ public class LocalConnector extends AbstractConnector return false; } - @Override - public int getHeaderCacheSize() - { - return 0; - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - return false; - } - @Override public void earlyEOF() { @@ -405,9 +395,8 @@ public class LocalConnector extends AbstractConnector } @Override - public boolean startResponse(HttpVersion version, int status, String reason) + public void startResponse(HttpVersion version, int status, String reason) { - return false; } }; @@ -425,7 +414,7 @@ public class LocalConnector extends AbstractConnector else { chunk = waitForOutput(time, unit); - if (BufferUtil.isEmpty(chunk) && (!isOpen() || isOutputShutdown())) + if (BufferUtil.isEmpty(chunk) && (!isOpen() || isOutputShutdown() || isShutdown())) { parser.atEOF(); parser.parseNext(BufferUtil.EMPTY_BUFFER); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java index 7d888082d2e..aea31be30a6 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -32,11 +32,11 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.ThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A monitor for low resources, low resources can be detected by: @@ -51,7 +51,7 @@ import org.eclipse.jetty.util.thread.ThreadPool; @ManagedObject("Monitor for low resource conditions and activate a low resource mode if detected") public class LowResourceMonitor extends ContainerLifeCycle { - private static final Logger LOG = Log.getLogger(LowResourceMonitor.class); + private static final Logger LOG = LoggerFactory.getLogger(LowResourceMonitor.class); protected final Server _server; private Scheduler _scheduler; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java deleted file mode 100644 index 4340ffbc842..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; - -import org.eclipse.jetty.server.handler.ContextHandler; - -public class MultiPartCleanerListener implements ServletRequestListener -{ - public static final MultiPartCleanerListener INSTANCE = new MultiPartCleanerListener(); - - protected MultiPartCleanerListener() - { - } - - @Override - public void requestDestroyed(ServletRequestEvent sre) - { - //Clean up any tmp files created by MultiPartInputStream - MultiParts parts = (MultiParts)sre.getServletRequest().getAttribute(Request.__MULTIPARTS); - if (parts != null) - { - ContextHandler.Context context = parts.getContext(); - - //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files - if (context == sre.getServletContext()) - { - try - { - parts.close(); - } - catch (Throwable e) - { - sre.getServletContext().log("Errors deleting multipart tmp files", e); - } - } - } - } - - @Override - public void requestInitialized(ServletRequestEvent sre) - { - //nothing to do, multipart config set up by ServletHolder.handle() - } -} diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartFormInputStream.java similarity index 79% rename from jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java rename to jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartFormInputStream.java index 2494522e190..12b9555fbad 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormInputStream.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartFormInputStream.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.http; +package org.eclipse.jetty.server; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -31,46 +31,76 @@ import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletInputStream; import javax.servlet.http.Part; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.ByteArrayOutputStream2; -import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MultiPartInputStream *

      * Handle a MultiPart Mime input stream, breaking it up on the boundary into files and strings. + *

      + *

      + * Deleting the parts can be done from a different thread if the parts are parsed asynchronously. + * Because of this we use the state to fail the parsing and coordinate which thread will delete any remaining parts. + * The deletion of parts is done by the cleanup thread in all cases except the transition from DELETING->DELETED which + * is done by the parsing thread. + *

      + *
      {@code
      + * UNPARSED - Parsing has not started, there are no parts which need to be cleaned up.
      + * PARSING  - The parsing thread is reading from the InputStream and generating parts.
      + * PARSED   - Parsing has complete and no more parts will be generated.
      + * DELETING - deleteParts() has been called while we were in PARSING state, parsing thread will do the delete.
      + * DELETED  - The parts have been deleted, this is the terminal state.
        *
      + *                              deleteParts()
      + *     +--------------------------------------------------------------+
      + *     |                                                              |
      + *     |                                          deleteParts()       v
      + *  UNPARSED -------> PARSING --------> PARSED  ------------------>DELETED
      + *                      |                                             ^
      + *                      |                                             |
      + *                      +---------------> DELETING -------------------+
      + *                        deleteParts()               parsing thread
      + * }
      * @see https://tools.ietf.org/html/rfc7578 */ public class MultiPartFormInputStream { - private static final Logger LOG = Log.getLogger(MultiPartFormInputStream.class); - private static final MultiMap EMPTY_MAP = new MultiMap<>(Collections.emptyMap()); - private InputStream _in; - private MultipartConfigElement _config; - private String _contentType; - private MultiMap _parts; - private Throwable _err; - private File _tmpDir; - private File _contextTmpDir; - private boolean _deleteOnExit; - private boolean _writeFilesWithFilenames; - private boolean _parsed; - private int _bufferSize = 16 * 1024; + private enum State + { + UNPARSED, + PARSING, + PARSED, + DELETING, + DELETED + } + + private static final Logger LOG = LoggerFactory.getLogger(MultiPartFormInputStream.class); + private final MultiMap _parts = new MultiMap<>(); + private final InputStream _in; + private final MultipartConfigElement _config; + private final File _contextTmpDir; + private final String _contentType; + private volatile Throwable _err; + private volatile File _tmpDir; + private volatile boolean _deleteOnExit; + private volatile boolean _writeFilesWithFilenames; + private volatile int _bufferSize = 16 * 1024; + private State state = State.UNPARSED; public class MultiPart implements Part { @@ -237,7 +267,8 @@ public class MultiPartFormInputStream @Override public Collection getHeaders(String name) { - return _headers.getValues(name); + Collection headers = _headers.getValues(name); + return headers == null ? Collections.emptyList() : headers; } @Override @@ -331,37 +362,38 @@ public class MultiPartFormInputStream */ public MultiPartFormInputStream(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir) { + // Must be a multipart request. _contentType = contentType; - _config = config; - _contextTmpDir = contextTmpDir; - if (_contextTmpDir == null) - _contextTmpDir = new File(System.getProperty("java.io.tmpdir")); + if (_contentType == null || !_contentType.startsWith("multipart/form-data")) + throw new IllegalArgumentException("content type is not multipart/form-data"); - if (_config == null) - _config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath()); + _contextTmpDir = (contextTmpDir != null) ? contextTmpDir : new File(System.getProperty("java.io.tmpdir")); + _config = (config != null) ? config : new MultipartConfigElement(_contextTmpDir.getAbsolutePath()); if (in instanceof ServletInputStream) { if (((ServletInputStream)in).isFinished()) { - _parts = EMPTY_MAP; - _parsed = true; + _in = null; + state = State.PARSED; return; } } + _in = new BufferedInputStream(in); } /** * @return whether the list of parsed parts is empty + * @deprecated use getParts().isEmpty() */ + @Deprecated public boolean isEmpty() { - if (_parts == null) + if (_parts.isEmpty()) return true; - Collection> values = _parts.values(); - for (List partList : values) + for (List partList : _parts.values()) { if (!partList.isEmpty()) return false; @@ -374,6 +406,33 @@ public class MultiPartFormInputStream * Delete any tmp storage for parts, and clear out the parts list. */ public void deleteParts() + { + synchronized (this) + { + switch (state) + { + case DELETED: + case DELETING: + return; + + case PARSING: + state = State.DELETING; + return; + + case UNPARSED: + state = State.DELETED; + return; + + case PARSED: + state = State.DELETED; + break; + } + } + + delete(); + } + + private void delete() { MultiException err = null; for (List parts : _parts.values()) @@ -406,18 +465,9 @@ public class MultiPartFormInputStream */ public Collection getParts() throws IOException { - if (!_parsed) - parse(); + parse(); throwIfError(); - - Collection> values = _parts.values(); - List parts = new ArrayList<>(); - for (List o : values) - { - List asList = LazyList.getList(o, false); - parts.addAll(asList); - } - return parts; + return _parts.values().stream().flatMap(List::stream).collect(Collectors.toList()); } /** @@ -429,8 +479,7 @@ public class MultiPartFormInputStream */ public Part getPart(String name) throws IOException { - if (!_parsed) - parse(); + parse(); throwIfError(); return _parts.getValue(name, 0); } @@ -461,22 +510,26 @@ public class MultiPartFormInputStream */ protected void parse() { - // have we already parsed the input? - if (_parsed) - return; - _parsed = true; + synchronized (this) + { + switch (state) + { + case UNPARSED: + state = State.PARSING; + break; + + case PARSED: + return; + + default: + _err = new IOException(state.name()); + return; + } + } MultiPartParser parser = null; - Handler handler = new Handler(); try { - // initialize - _parts = new MultiMap<>(); - - // if its not a multipart request, don't parse it - if (_contentType == null || !_contentType.startsWith("multipart/form-data")) - return; - // sort out the location to which to write the files if (_config.getLocation() == null) _tmpDir = _contextTmpDir; @@ -503,16 +556,23 @@ public class MultiPartFormInputStream contentTypeBoundary = QuotedStringTokenizer.unquote(value(_contentType.substring(bstart, bend)).trim()); } - parser = new MultiPartParser(handler, contentTypeBoundary); + parser = new MultiPartParser(new Handler(), contentTypeBoundary); byte[] data = new byte[_bufferSize]; int len; long total = 0; while (true) { + synchronized (this) + { + if (state != State.PARSING) + { + _err = new IOException(state.name()); + return; + } + } len = _in.read(data); - if (len > 0) { // keep running total of size of bytes read from input and throw an exception if exceeds MultipartConfigElement._maxRequestSize @@ -566,6 +626,30 @@ public class MultiPartFormInputStream if (parser != null) parser.parse(BufferUtil.EMPTY_BUFFER, true); } + finally + { + boolean cleanup = false; + synchronized (this) + { + switch (state) + { + case PARSING: + state = State.PARSED; + break; + + case DELETING: + state = State.DELETED; + cleanup = true; + break; + + default: + _err = new IllegalStateException(state.name()); + } + } + + if (cleanup) + delete(); + } } class Handler implements MultiPartParser.Handler diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartParser.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartParser.java similarity index 95% rename from jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartParser.java rename to jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartParser.java index 286ee58be62..ae548530b7c 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartParser.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartParser.java @@ -1,33 +1,35 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.http; +package org.eclipse.jetty.server; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.EnumSet; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpParser.RequestHandler; +import org.eclipse.jetty.http.HttpTokens; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.SearchPattern; import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A parser for MultiPart content type. @@ -37,7 +39,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class MultiPartParser { - public static final Logger LOG = Log.getLogger(MultiPartParser.class); + public static final Logger LOG = LoggerFactory.getLogger(MultiPartParser.class); // States public enum FieldState diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java deleted file mode 100644 index a4ca332a11d..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import javax.servlet.MultipartConfigElement; -import javax.servlet.http.Part; - -import org.eclipse.jetty.http.MultiPartFormInputStream; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandler.Context; - -/* - * Used to switch between the old and new implementation of MultiPart Form InputStream Parsing. - * The new implementation is preferred will be used as default unless specified otherwise constructor. - */ -public interface MultiParts extends Closeable -{ - Collection getParts() throws IOException; - - Part getPart(String name) throws IOException; - - boolean isEmpty(); - - ContextHandler.Context getContext(); - - class MultiPartsHttpParser implements MultiParts - { - private final MultiPartFormInputStream _httpParser; - private final ContextHandler.Context _context; - - public MultiPartsHttpParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) throws IOException - { - _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir); - _context = request.getContext(); - } - - @Override - public Collection getParts() throws IOException - { - return _httpParser.getParts(); - } - - @Override - public Part getPart(String name) throws IOException - { - return _httpParser.getPart(name); - } - - @Override - public void close() - { - _httpParser.deleteParts(); - } - - @Override - public boolean isEmpty() - { - return _httpParser.isEmpty(); - } - - @Override - public Context getContext() - { - return _context; - } - } -} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnection.java index 02a6d305e85..41cb9ec42a3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -27,12 +27,12 @@ import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class NegotiatingServerConnection extends AbstractConnection { - private static final Logger LOG = Log.getLogger(NegotiatingServerConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(NegotiatingServerConnection.class); public interface CipherDiscriminator { @@ -153,7 +153,7 @@ public abstract class NegotiatingServerConnection extends AbstractConnection } catch (IOException x) { - LOG.debug(x); + LOG.debug("Unable to fill from endpoint {}", getEndPoint(), x); close(); return -1; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnectionFactory.java index 251c7d00ca0..3de2b182659 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java index 27a224e36fe..3c508427c23 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkTrafficServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkTrafficServerConnector.java index e0d95212f53..970f9dc38b8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkTrafficServerConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkTrafficServerConnector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/OptionalSslConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/OptionalSslConnectionFactory.java index 71b40c0fa82..120dccc7854 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/OptionalSslConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/OptionalSslConnectionFactory.java @@ -1,101 +1,105 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; -import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      A ConnectionFactory whose connections detect whether the first bytes are * TLS bytes and upgrades to either a TLS connection or to another configurable * connection.

      + * + * @deprecated Use {@link DetectorConnectionFactory} with a {@link SslConnectionFactory} instead. */ -public class OptionalSslConnectionFactory extends AbstractConnectionFactory +@Deprecated +public class OptionalSslConnectionFactory extends DetectorConnectionFactory { - private static final Logger LOG = Log.getLogger(OptionalSslConnection.class); - private static final int TLS_ALERT_FRAME_TYPE = 0x15; - private static final int TLS_HANDSHAKE_FRAME_TYPE = 0x16; - private static final int TLS_MAJOR_VERSION = 3; - - private final SslConnectionFactory sslConnectionFactory; - private final String otherProtocol; + private static final Logger LOG = LoggerFactory.getLogger(OptionalSslConnectionFactory.class); + private final String _nextProtocol; /** *

      Creates a new ConnectionFactory whose connections can upgrade to TLS or another protocol.

      - *

      If {@code otherProtocol} is {@code null}, and the first bytes are not TLS, then - * {@link #otherProtocol(ByteBuffer, EndPoint)} is called.

      * - * @param sslConnectionFactory The SslConnectionFactory to use if the first bytes are TLS - * @param otherProtocol the protocol of the ConnectionFactory to use if the first bytes are not TLS, + * @param sslConnectionFactory The {@link SslConnectionFactory} to use if the first bytes are TLS + * @param nextProtocol the protocol of the {@link ConnectionFactory} to use if the first bytes are not TLS, * or null to explicitly handle the non-TLS case */ - public OptionalSslConnectionFactory(SslConnectionFactory sslConnectionFactory, String otherProtocol) + public OptionalSslConnectionFactory(SslConnectionFactory sslConnectionFactory, String nextProtocol) { - super("ssl|other"); - this.sslConnectionFactory = sslConnectionFactory; - this.otherProtocol = otherProtocol; - } - - @Override - public Connection newConnection(Connector connector, EndPoint endPoint) - { - return configure(new OptionalSslConnection(endPoint, connector), connector, endPoint); + super(sslConnectionFactory); + _nextProtocol = nextProtocol; } /** - * @param buffer The buffer with the first bytes of the connection - * @return whether the bytes seem TLS bytes - */ - protected boolean seemsTLS(ByteBuffer buffer) - { - int tlsFrameType = buffer.get(0) & 0xFF; - int tlsMajorVersion = buffer.get(1) & 0xFF; - return (tlsFrameType == TLS_HANDSHAKE_FRAME_TYPE || tlsFrameType == TLS_ALERT_FRAME_TYPE) && tlsMajorVersion == TLS_MAJOR_VERSION; - } - - /** - *

      Callback method invoked when {@code otherProtocol} is {@code null} - * and the first bytes are not TLS.

      + *

      Callback method invoked when the detected bytes are not TLS.

      *

      This typically happens when a client is trying to connect to a TLS * port using the {@code http} scheme (and not the {@code https} scheme).

      * + * @param connector The connector object + * @param endPoint The connection EndPoint object + * @param buffer The buffer with the first bytes of the connection + */ + protected void nextProtocol(Connector connector, EndPoint endPoint, ByteBuffer buffer) + { + if (LOG.isDebugEnabled()) + LOG.debug("OptionalSSL TLS detection unsuccessful, attempting to upgrade to {}", _nextProtocol); + if (_nextProtocol != null) + { + ConnectionFactory connectionFactory = connector.getConnectionFactory(_nextProtocol); + if (connectionFactory == null) + throw new IllegalStateException("Cannot find protocol '" + _nextProtocol + "' in connector's protocol list " + connector.getProtocols() + " for " + endPoint); + upgradeToConnectionFactory(connectionFactory, connector, endPoint); + } + else + { + otherProtocol(buffer, endPoint); + } + } + + /** + *

      Legacy callback method invoked when {@code nextProtocol} is {@code null} + * and the first bytes are not TLS.

      + *

      This typically happens when a client is trying to connect to a TLS + * port using the {@code http} scheme (and not the {@code https} scheme).

      + *

      This method is kept around for backward compatibility.

      + * * @param buffer The buffer with the first bytes of the connection * @param endPoint The connection EndPoint object - * @see #seemsTLS(ByteBuffer) + * @deprecated Override {@link #nextProtocol(Connector, EndPoint, ByteBuffer)} instead. */ + @Deprecated protected void otherProtocol(ByteBuffer buffer, EndPoint endPoint) { + LOG.warn("Detected non-TLS bytes, but no other protocol to upgrade to for {}", endPoint); + // There are always at least 2 bytes. int byte1 = buffer.get(0) & 0xFF; int byte2 = buffer.get(1) & 0xFF; if (byte1 == 'G' && byte2 == 'E') { - // Plain text HTTP to a HTTPS port, + // Plain text HTTP to an HTTPS port, // write a minimal response. String body = "\r\n" + @@ -122,105 +126,4 @@ public class OptionalSslConnectionFactory extends AbstractConnectionFactory endPoint.close(); } } - - private class OptionalSslConnection extends AbstractConnection implements Connection.UpgradeFrom - { - private final Connector connector; - private final ByteBuffer buffer; - - public OptionalSslConnection(EndPoint endPoint, Connector connector) - { - super(endPoint, connector.getExecutor()); - this.connector = connector; - this.buffer = BufferUtil.allocateDirect(1536); - } - - @Override - public void onOpen() - { - super.onOpen(); - fillInterested(); - } - - @Override - public void onFillable() - { - try - { - while (true) - { - int filled = getEndPoint().fill(buffer); - if (filled > 0) - { - // Always have at least 2 bytes. - if (BufferUtil.length(buffer) >= 2) - { - upgrade(buffer); - break; - } - } - else if (filled == 0) - { - fillInterested(); - break; - } - else - { - close(); - break; - } - } - } - catch (IOException x) - { - LOG.warn(x); - close(); - } - } - - @Override - public ByteBuffer onUpgradeFrom() - { - return buffer; - } - - private void upgrade(ByteBuffer buffer) - { - if (LOG.isDebugEnabled()) - LOG.debug("Read {}", BufferUtil.toDetailString(buffer)); - - EndPoint endPoint = getEndPoint(); - if (seemsTLS(buffer)) - { - if (LOG.isDebugEnabled()) - LOG.debug("Detected TLS bytes, upgrading to {}", sslConnectionFactory); - endPoint.upgrade(sslConnectionFactory.newConnection(connector, endPoint)); - } - else - { - if (otherProtocol != null) - { - ConnectionFactory connectionFactory = connector.getConnectionFactory(otherProtocol); - if (connectionFactory != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("Detected non-TLS bytes, upgrading to {}", connectionFactory); - Connection next = connectionFactory.newConnection(connector, endPoint); - endPoint.upgrade(next); - } - else - { - LOG.warn("Missing {} {} in {}", otherProtocol, ConnectionFactory.class.getSimpleName(), connector); - close(); - } - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Detected non-TLS bytes, but no other protocol to upgrade to"); - otherProtocol(buffer, endPoint); - } - } - } - } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java index 43261cd5c1b..ddba526aab3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -27,7 +27,8 @@ import java.nio.ByteBuffer; import java.nio.channels.ReadPendingException; import java.nio.channels.WritePendingException; import java.nio.charset.StandardCharsets; -import java.util.Iterator; +import java.util.HashMap; +import java.util.Map; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.Connection; @@ -36,8 +37,8 @@ import org.eclipse.jetty.util.AttributesMap; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      ConnectionFactory for the PROXY Protocol.

      @@ -46,431 +47,517 @@ import org.eclipse.jetty.util.log.Logger; * * @see http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt */ -public class ProxyConnectionFactory extends AbstractConnectionFactory +public class ProxyConnectionFactory extends DetectorConnectionFactory { - private static final Logger LOG = Log.getLogger(ProxyConnectionFactory.class); public static final String TLS_VERSION = "TLS_VERSION"; + private static final Logger LOG = LoggerFactory.getLogger(ProxyConnectionFactory.class); - private final String _next; - private int _maxProxyHeader = 1024; - - /** - * Proxy Connection Factory that uses the next ConnectionFactory - * on the connector as the next protocol - */ public ProxyConnectionFactory() { - super("proxy"); - _next = null; + this(null); } public ProxyConnectionFactory(String nextProtocol) { - super("proxy"); - _next = nextProtocol; + super(new ProxyV1ConnectionFactory(nextProtocol), new ProxyV2ConnectionFactory(nextProtocol)); + } + + private static ConnectionFactory findNextConnectionFactory(String nextProtocol, Connector connector, String currentProtocol, EndPoint endp) + { + currentProtocol = "[" + currentProtocol + "]"; + if (LOG.isDebugEnabled()) + LOG.debug("finding connection factory following {} for protocol {}", currentProtocol, nextProtocol); + String nextProtocolToFind = nextProtocol; + if (nextProtocol == null) + nextProtocolToFind = AbstractConnectionFactory.findNextProtocol(connector, currentProtocol); + if (nextProtocolToFind == null) + throw new IllegalStateException("Cannot find protocol following '" + currentProtocol + "' in connector's protocol list " + connector.getProtocols() + " for " + endp); + ConnectionFactory connectionFactory = connector.getConnectionFactory(nextProtocolToFind); + if (connectionFactory == null) + throw new IllegalStateException("Cannot find protocol '" + nextProtocol + "' in connector's protocol list " + connector.getProtocols() + " for " + endp); + if (LOG.isDebugEnabled()) + LOG.debug("found next connection factory {} for protocol {}", connectionFactory, nextProtocol); + return connectionFactory; } public int getMaxProxyHeader() { - return _maxProxyHeader; + ProxyV2ConnectionFactory v2 = getBean(ProxyV2ConnectionFactory.class); + return v2.getMaxProxyHeader(); } public void setMaxProxyHeader(int maxProxyHeader) { - _maxProxyHeader = maxProxyHeader; + ProxyV2ConnectionFactory v2 = getBean(ProxyV2ConnectionFactory.class); + v2.setMaxProxyHeader(maxProxyHeader); } - @Override - public Connection newConnection(Connector connector, EndPoint endp) + private static class ProxyV1ConnectionFactory extends AbstractConnectionFactory implements Detecting { - String next = _next; - if (next == null) + private static final byte[] SIGNATURE = "PROXY".getBytes(StandardCharsets.US_ASCII); + + private final String _nextProtocol; + + private ProxyV1ConnectionFactory(String nextProtocol) { - for (Iterator i = connector.getProtocols().iterator(); i.hasNext(); ) - { - String p = i.next(); - if (getProtocol().equalsIgnoreCase(p)) - { - next = i.next(); - break; - } - } - } - - return new ProxyProtocolV1orV2Connection(endp, connector, next); - } - - public class ProxyProtocolV1orV2Connection extends AbstractConnection - { - private final Connector _connector; - private final String _next; - private ByteBuffer _buffer = BufferUtil.allocate(16); - - protected ProxyProtocolV1orV2Connection(EndPoint endp, Connector connector, String next) - { - super(endp, connector.getExecutor()); - _connector = connector; - _next = next; + super("proxy"); + this._nextProtocol = nextProtocol; } @Override - public void onOpen() + public Detection detect(ByteBuffer buffer) { - super.onOpen(); - fillInterested(); + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 attempting detection with {} bytes", buffer.remaining()); + if (buffer.remaining() < SIGNATURE.length) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 detection requires more bytes"); + return Detection.NEED_MORE_BYTES; + } + + for (int i = 0; i < SIGNATURE.length; i++) + { + byte signatureByte = SIGNATURE[i]; + byte byteInBuffer = buffer.get(i); + if (byteInBuffer != signatureByte) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 detection unsuccessful"); + return Detection.NOT_RECOGNIZED; + } + } + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 detection succeeded"); + return Detection.RECOGNIZED; } @Override - public void onFillable() + public Connection newConnection(Connector connector, EndPoint endp) { - try + ConnectionFactory nextConnectionFactory = findNextConnectionFactory(_nextProtocol, connector, getProtocol(), endp); + return configure(new ProxyProtocolV1Connection(endp, connector, nextConnectionFactory), connector, endp); + } + + private static class ProxyProtocolV1Connection extends AbstractConnection implements Connection.UpgradeFrom, Connection.UpgradeTo + { + // 0 1 2 3 4 5 6 + // 98765432109876543210987654321 + // PROXY P R.R.R.R L.L.L.L R Lrn + private static final int CR_INDEX = 6; + private static final int LF_INDEX = 7; + + private final Connector _connector; + private final ConnectionFactory _next; + private final ByteBuffer _buffer; + private final StringBuilder _builder = new StringBuilder(); + private final String[] _fields = new String[6]; + private int _index; + private int _length; + + private ProxyProtocolV1Connection(EndPoint endp, Connector connector, ConnectionFactory next) { - while (BufferUtil.space(_buffer) > 0) + super(endp, connector.getExecutor()); + _connector = connector; + _next = next; + _buffer = _connector.getByteBufferPool().acquire(getInputBufferSize(), true); + } + + @Override + public void onFillable() + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 onFillable current index = ", _index); + try { - // Read data - int fill = getEndPoint().fill(_buffer); - if (fill < 0) + while (_index < LF_INDEX) { - getEndPoint().shutdownOutput(); - return; + // Read data + int fill = getEndPoint().fill(_buffer); + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 filled buffer with {} bytes", fill); + if (fill < 0) + { + _connector.getByteBufferPool().release(_buffer); + getEndPoint().shutdownOutput(); + return; + } + if (fill == 0) + { + fillInterested(); + return; + } + + if (parse()) + break; } - if (fill == 0) + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 onFillable parsing done, now upgrading"); + upgrade(); + } + catch (Throwable x) + { + LOG.warn("Proxy v1 error for {}", getEndPoint(), x); + releaseAndClose(); + } + } + + @Override + public void onOpen() + { + super.onOpen(); + + try + { + while (_index < LF_INDEX) { - fillInterested(); - return; + if (!parse()) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 onOpen parsing ran out of bytes, marking as fillInterested"); + fillInterested(); + return; + } + } + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 onOpen parsing done, now upgrading"); + upgrade(); + } + catch (Throwable x) + { + LOG.warn("Proxy v1 error for {}", getEndPoint(), x); + releaseAndClose(); + } + } + + @Override + public ByteBuffer onUpgradeFrom() + { + return _buffer; + } + + @Override + public void onUpgradeTo(ByteBuffer prefilled) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 copying prefilled buffer {}", BufferUtil.toDetailString(prefilled)); + if (BufferUtil.hasContent(prefilled)) + BufferUtil.append(_buffer, prefilled); + } + + /** + * @return true when parsing is done, false when more bytes are needed. + */ + private boolean parse() throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 parsing {}", BufferUtil.toDetailString(_buffer)); + _length += _buffer.remaining(); + + // Parse fields + while (_buffer.hasRemaining()) + { + byte b = _buffer.get(); + if (_index < CR_INDEX) + { + if (b == ' ' || b == '\r') + { + _fields[_index++] = _builder.toString(); + _builder.setLength(0); + if (b == '\r') + _index = CR_INDEX; + } + else if (b < ' ') + { + throw new IOException("Proxy v1 bad character " + (b & 0xFF)); + } + else + { + _builder.append((char)b); + } + } + else + { + if (b == '\n') + { + _index = LF_INDEX; + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 parsing is done"); + return true; + } + + throw new IOException("Proxy v1 bad CRLF " + (b & 0xFF)); } } - // Is it a V1? - switch (_buffer.get(0)) - { - case 'P': - { - ProxyProtocolV1Connection v1 = new ProxyProtocolV1Connection(getEndPoint(), _connector, _next, _buffer); - getEndPoint().upgrade(v1); - return; - } - case 0x0D: - { - ProxyProtocolV2Connection v2 = new ProxyProtocolV2Connection(getEndPoint(), _connector, _next, _buffer); - getEndPoint().upgrade(v2); - return; - } - default: - LOG.warn("Not PROXY protocol for {}", getEndPoint()); - close(); - } + // Not enough bytes. + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 parsing requires more bytes"); + return false; } - catch (Throwable x) + + private void releaseAndClose() { - LOG.warn("PROXY error for " + getEndPoint(), x); + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 releasing buffer and closing"); + _connector.getByteBufferPool().release(_buffer); close(); } - } - } - public static class ProxyProtocolV1Connection extends AbstractConnection - { - // 0 1 2 3 4 5 6 - // 98765432109876543210987654321 - // PROXY P R.R.R.R L.L.L.L R Lrn - - private static final int[] SIZE = {29, 23, 21, 13, 5, 3, 1}; - private final Connector _connector; - private final String _next; - private final StringBuilder _builder = new StringBuilder(); - private final String[] _field = new String[6]; - private int _fields; - private int _length; - - protected ProxyProtocolV1Connection(EndPoint endp, Connector connector, String next, ByteBuffer buffer) - { - super(endp, connector.getExecutor()); - _connector = connector; - _next = next; - _length = buffer.remaining(); - parse(buffer); - } - - @Override - public void onOpen() - { - super.onOpen(); - fillInterested(); - } - - private boolean parse(ByteBuffer buffer) - { - // parse fields - while (buffer.hasRemaining()) + private void upgrade() { - byte b = buffer.get(); - if (_fields < 6) + int proxyLineLength = _length - _buffer.remaining(); + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v1 pre-upgrade packet length (including CRLF) is {}", proxyLineLength); + if (proxyLineLength >= 110) { - if (b == ' ' || b == '\r' && _fields == 5) - { - _field[_fields++] = _builder.toString(); - _builder.setLength(0); - } - else if (b < ' ') - { - LOG.warn("Bad character {} for {}", b & 0xFF, getEndPoint()); - close(); - return false; - } - else - { - _builder.append((char)b); - } - } - else - { - if (b == '\n') - { - _fields = 7; - return true; - } - - LOG.warn("Bad CRLF for {}", getEndPoint()); - close(); - return false; - } - } - return true; - } - - @Override - public void onFillable() - { - try - { - ByteBuffer buffer = null; - while (_fields < 7) - { - // Create a buffer that will not read too much data - // since once read it is impossible to push back for the - // real connection to read it. - int size = Math.max(1, SIZE[_fields] - _builder.length()); - if (buffer == null || buffer.capacity() != size) - buffer = BufferUtil.allocate(size); - else - BufferUtil.clear(buffer); - - // Read data - int fill = getEndPoint().fill(buffer); - if (fill < 0) - { - getEndPoint().shutdownOutput(); - return; - } - if (fill == 0) - { - fillInterested(); - return; - } - - _length += fill; - if (_length >= 108) - { - LOG.warn("PROXY line too long {} for {}", _length, getEndPoint()); - close(); - return; - } - - if (!parse(buffer)) - return; + LOG.warn("Proxy v1 PROXY line too long {} for {}", proxyLineLength, getEndPoint()); + releaseAndClose(); + return; } // Check proxy - if (!"PROXY".equals(_field[0])) + if (!"PROXY".equals(_fields[0])) { - LOG.warn("Not PROXY protocol for {}", getEndPoint()); - close(); + LOG.warn("Proxy v1 not PROXY protocol for {}", getEndPoint()); + releaseAndClose(); return; } - // Extract Addresses - InetSocketAddress remote = new InetSocketAddress(_field[2], Integer.parseInt(_field[4])); - InetSocketAddress local = new InetSocketAddress(_field[3], Integer.parseInt(_field[5])); - - // Create the next protocol - ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next); - if (connectionFactory == null) + String srcIP = _fields[2]; + String srcPort = _fields[4]; + String dstIP = _fields[3]; + String dstPort = _fields[5]; + // If UNKNOWN, we must ignore the information sent, so use the EndPoint's. + boolean unknown = "UNKNOWN".equalsIgnoreCase(_fields[1]); + if (unknown) { - LOG.warn("No Next protocol '{}' for {}", _next, getEndPoint()); - close(); - return; + srcIP = getEndPoint().getRemoteAddress().getAddress().getHostAddress(); + srcPort = String.valueOf(getEndPoint().getRemoteAddress().getPort()); + dstIP = getEndPoint().getLocalAddress().getAddress().getHostAddress(); + dstPort = String.valueOf(getEndPoint().getLocalAddress().getPort()); } + InetSocketAddress remote = new InetSocketAddress(srcIP, Integer.parseInt(srcPort)); + InetSocketAddress local = new InetSocketAddress(dstIP, Integer.parseInt(dstPort)); if (LOG.isDebugEnabled()) - LOG.warn("Next protocol '{}' for {} r={} l={}", _next, getEndPoint(), remote, local); + LOG.debug("Proxy v1 next protocol '{}' for {} r={} l={}", _next, getEndPoint(), remote, local); EndPoint endPoint = new ProxyEndPoint(getEndPoint(), remote, local); - Connection newConnection = connectionFactory.newConnection(_connector, endPoint); - endPoint.upgrade(newConnection); - } - catch (Throwable x) - { - LOG.warn("PROXY error for " + getEndPoint(), x); - close(); + upgradeToConnectionFactory(_next, _connector, endPoint); } } } - private enum Family + private static class ProxyV2ConnectionFactory extends AbstractConnectionFactory implements Detecting { - UNSPEC, INET, INET6, UNIX - } - - private enum Transport - { - UNSPEC, STREAM, DGRAM - } - - private static final byte[] MAGIC = new byte[]{0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}; - - public class ProxyProtocolV2Connection extends AbstractConnection - { - private final Connector _connector; - private final String _next; - private final boolean _local; - private final Family _family; - private final Transport _transport; - private final int _length; - private final ByteBuffer _buffer; - - protected ProxyProtocolV2Connection(EndPoint endp, Connector connector, String next, ByteBuffer buffer) throws IOException + private enum Family { - super(endp, connector.getExecutor()); - _connector = connector; - _next = next; + UNSPEC, INET, INET6, UNIX + } - if (buffer.remaining() != 16) - throw new IllegalStateException(); + private enum Transport + { + UNSPEC, STREAM, DGRAM + } + + private static final byte[] SIGNATURE = new byte[] + { + 0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A + }; + + private final String _nextProtocol; + private int _maxProxyHeader = 1024; + + private ProxyV2ConnectionFactory(String nextProtocol) + { + super("proxy"); + this._nextProtocol = nextProtocol; + } + + @Override + public Detection detect(ByteBuffer buffer) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 attempting detection with {} bytes", buffer.remaining()); + if (buffer.remaining() < SIGNATURE.length) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 detection requires more bytes"); + return Detection.NEED_MORE_BYTES; + } + + for (int i = 0; i < SIGNATURE.length; i++) + { + byte signatureByte = SIGNATURE[i]; + byte byteInBuffer = buffer.get(i); + if (byteInBuffer != signatureByte) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 detection unsuccessful"); + return Detection.NOT_RECOGNIZED; + } + } if (LOG.isDebugEnabled()) - LOG.debug("PROXYv2 header {} for {}", BufferUtil.toHexSummary(buffer), this); + LOG.debug("Proxy v2 detection succeeded"); + return Detection.RECOGNIZED; + } - // struct proxy_hdr_v2 { - // uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */ - // uint8_t ver_cmd; /* protocol version and command */ - // uint8_t fam; /* protocol family and address */ - // uint16_t len; /* number of following bytes part of the header */ - // }; - for (byte magic : MAGIC) - { - if (buffer.get() != magic) - throw new IOException("Bad PROXY protocol v2 signature"); - } + public int getMaxProxyHeader() + { + return _maxProxyHeader; + } - int versionAndCommand = 0xff & buffer.get(); - if ((versionAndCommand & 0xf0) != 0x20) - throw new IOException("Bad PROXY protocol v2 version"); - _local = (versionAndCommand & 0xf) == 0x00; - - int transportAndFamily = 0xff & buffer.get(); - switch (transportAndFamily >> 4) - { - case 0: - _family = Family.UNSPEC; - break; - case 1: - _family = Family.INET; - break; - case 2: - _family = Family.INET6; - break; - case 3: - _family = Family.UNIX; - break; - default: - throw new IOException("Bad PROXY protocol v2 family"); - } - - switch (0xf & transportAndFamily) - { - case 0: - _transport = Transport.UNSPEC; - break; - case 1: - _transport = Transport.STREAM; - break; - case 2: - _transport = Transport.DGRAM; - break; - default: - throw new IOException("Bad PROXY protocol v2 family"); - } - - _length = buffer.getChar(); - - if (!_local && (_family == Family.UNSPEC || _family == Family.UNIX || _transport != Transport.STREAM)) - throw new IOException(String.format("Unsupported PROXY protocol v2 mode 0x%x,0x%x", versionAndCommand, transportAndFamily)); - - if (_length > getMaxProxyHeader()) - throw new IOException(String.format("Unsupported PROXY protocol v2 mode 0x%x,0x%x,0x%x", versionAndCommand, transportAndFamily, _length)); - - _buffer = _length > 0 ? BufferUtil.allocate(_length) : BufferUtil.EMPTY_BUFFER; + public void setMaxProxyHeader(int maxProxyHeader) + { + _maxProxyHeader = maxProxyHeader; } @Override - public void onOpen() + public Connection newConnection(Connector connector, EndPoint endp) { - super.onOpen(); - if (_buffer.remaining() == _length) - next(); - else - fillInterested(); + ConnectionFactory nextConnectionFactory = findNextConnectionFactory(_nextProtocol, connector, getProtocol(), endp); + return configure(new ProxyProtocolV2Connection(endp, connector, nextConnectionFactory), connector, endp); } - @Override - public void onFillable() + private class ProxyProtocolV2Connection extends AbstractConnection implements Connection.UpgradeFrom, Connection.UpgradeTo { - try + private static final int HEADER_LENGTH = 16; + + private final Connector _connector; + private final ConnectionFactory _next; + private final ByteBuffer _buffer; + private boolean _local; + private Family _family; + private int _length; + private boolean _headerParsed; + + protected ProxyProtocolV2Connection(EndPoint endp, Connector connector, ConnectionFactory next) { - while (_buffer.remaining() < _length) + super(endp, connector.getExecutor()); + _connector = connector; + _next = next; + _buffer = _connector.getByteBufferPool().acquire(getInputBufferSize(), true); + } + + @Override + public void onUpgradeTo(ByteBuffer prefilled) + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 copying prefilled buffer {}", BufferUtil.toDetailString(prefilled)); + if (BufferUtil.hasContent(prefilled)) + BufferUtil.append(_buffer, prefilled); + } + + @Override + public void onOpen() + { + super.onOpen(); + + try { - // Read data - int fill = getEndPoint().fill(_buffer); - if (fill < 0) + parseHeader(); + if (_headerParsed && _buffer.remaining() >= _length) { - getEndPoint().shutdownOutput(); - return; + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 onOpen parsing fixed length packet part done, now upgrading"); + parseBodyAndUpgrade(); } - if (fill == 0) + else { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 onOpen parsing fixed length packet ran out of bytes, marking as fillInterested"); fillInterested(); - return; } } - next(); - } - catch (Throwable x) - { - LOG.warn("PROXY error for " + getEndPoint(), x); - close(); - } - } - - private void next() - { - if (LOG.isDebugEnabled()) - LOG.debug("PROXYv2 next {} from {} for {}", _next, BufferUtil.toHexSummary(_buffer), this); - - // Create the next protocol - ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next); - if (connectionFactory == null) - { - LOG.info("Next protocol '{}' for {}", _next, getEndPoint()); - close(); - return; + catch (Exception x) + { + LOG.warn("Proxy v2 error for {}", getEndPoint(), x); + releaseAndClose(); + } } - // Do we need to wrap the endpoint? - EndPoint endPoint = getEndPoint(); - if (!_local) + @Override + public void onFillable() { try + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 onFillable header parsed? ", _headerParsed); + while (!_headerParsed) + { + // Read data + int fill = getEndPoint().fill(_buffer); + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 filled buffer with {} bytes", fill); + if (fill < 0) + { + _connector.getByteBufferPool().release(_buffer); + getEndPoint().shutdownOutput(); + return; + } + if (fill == 0) + { + fillInterested(); + return; + } + + parseHeader(); + } + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 onFillable header parsed, length = {}, buffer = {}", _length, BufferUtil.toDetailString(_buffer)); + + while (_buffer.remaining() < _length) + { + // Read data + int fill = getEndPoint().fill(_buffer); + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 filled buffer with {} bytes", fill); + if (fill < 0) + { + _connector.getByteBufferPool().release(_buffer); + getEndPoint().shutdownOutput(); + return; + } + if (fill == 0) + { + fillInterested(); + return; + } + } + + parseBodyAndUpgrade(); + } + catch (Throwable x) + { + LOG.warn("Proxy v2 error for " + getEndPoint(), x); + releaseAndClose(); + } + } + + @Override + public ByteBuffer onUpgradeFrom() + { + return _buffer; + } + + private void parseBodyAndUpgrade() throws IOException + { + int nonProxyRemaining = _buffer.remaining() - _length; + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 parsing body, length = {}, buffer = {}", _length, BufferUtil.toHexSummary(_buffer)); + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 body {} from {} for {}", _next, BufferUtil.toHexSummary(_buffer), this); + + // Do we need to wrap the endpoint? + EndPoint endPoint = getEndPoint(); + if (!_local) { InetAddress src; InetAddress dst; @@ -514,97 +601,235 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory endPoint = proxyEndPoint; // Any additional info? - while (_buffer.hasRemaining()) + while (_buffer.remaining() > nonProxyRemaining) { int type = 0xff & _buffer.get(); - int length = _buffer.getShort(); + int length = _buffer.getChar(); byte[] value = new byte[length]; _buffer.get(value); if (LOG.isDebugEnabled()) - LOG.debug(String.format("T=%x L=%d V=%s for %s", type, length, TypeUtil.toHexString(value), this)); + LOG.debug(String.format("Proxy v2 T=%x L=%d V=%s for %s", type, length, TypeUtil.toHexString(value), this)); - switch (type) + // PP2_TYPE_NOOP is only used for byte alignment, skip them. + if (type != ProxyEndPoint.PP2_TYPE_NOOP) + proxyEndPoint.putTLV(type, value); + + if (type == ProxyEndPoint.PP2_TYPE_SSL) { - case 0x20: // PP2_TYPE_SSL + int client = value[0] & 0xFF; + if (client == ProxyEndPoint.PP2_TYPE_SSL_PP2_CLIENT_SSL) { - int client = value[0] & 0xFF; - switch (client) + int i = 5; // Index of the first sub_tlv, after verify. + while (i < length) { - case 0x01: // PP2_CLIENT_SSL + int subType = value[i++] & 0xFF; + int subLength = (value[i++] & 0xFF) * 256 + (value[i++] & 0xFF); + byte[] subValue = new byte[subLength]; + System.arraycopy(value, i, subValue, 0, subLength); + i += subLength; + if (subType == ProxyEndPoint.PP2_SUBTYPE_SSL_VERSION) { - int i = 5; // Index of the first sub_tlv, after verify. - while (i < length) - { - int subType = value[i++] & 0xFF; - int subLength = (value[i++] & 0xFF) * 256 + (value[i++] & 0xFF); - byte[] subValue = new byte[subLength]; - System.arraycopy(value, i, subValue, 0, subLength); - i += subLength; - switch (subType) - { - case 0x21: // PP2_SUBTYPE_SSL_VERSION - String tlsVersion = new String(subValue, StandardCharsets.US_ASCII); - proxyEndPoint.setAttribute(TLS_VERSION, tlsVersion); - break; - case 0x22: // PP2_SUBTYPE_SSL_CN - case 0x23: // PP2_SUBTYPE_SSL_CIPHER - case 0x24: // PP2_SUBTYPE_SSL_SIG_ALG - case 0x25: // PP2_SUBTYPE_SSL_KEY_ALG - default: - break; - } - } - break; + String tlsVersion = new String(subValue, StandardCharsets.US_ASCII); + proxyEndPoint.setAttribute(TLS_VERSION, tlsVersion); } - case 0x02: // PP2_CLIENT_CERT_CONN - case 0x04: // PP2_CLIENT_CERT_SESS - default: - break; } - break; } - case 0x01: // PP2_TYPE_ALPN - case 0x02: // PP2_TYPE_AUTHORITY - case 0x03: // PP2_TYPE_CRC32C - case 0x04: // PP2_TYPE_NOOP - case 0x30: // PP2_TYPE_NETNS - default: - break; } } if (LOG.isDebugEnabled()) - LOG.debug("{} {}", getEndPoint(), proxyEndPoint.toString()); - } - catch (Exception e) - { - LOG.warn(e); + LOG.debug("Proxy v2 {} {}", getEndPoint(), proxyEndPoint.toString()); } + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 parsing dynamic packet part is now done, upgrading to {}", _nextProtocol); + upgradeToConnectionFactory(_next, _connector, endPoint); } - Connection newConnection = connectionFactory.newConnection(_connector, endPoint); - endPoint.upgrade(newConnection); + private void parseHeader() throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 parsing fixed length packet part, buffer = {}", BufferUtil.toDetailString(_buffer)); + if (_buffer.remaining() < HEADER_LENGTH) + return; + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 header {} for {}", BufferUtil.toHexSummary(_buffer), this); + + // struct proxy_hdr_v2 { + // uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */ + // uint8_t ver_cmd; /* protocol version and command */ + // uint8_t fam; /* protocol family and address */ + // uint16_t len; /* number of following bytes part of the header */ + // }; + for (byte signatureByte : SIGNATURE) + { + if (_buffer.get() != signatureByte) + throw new IOException("Proxy v2 bad PROXY signature"); + } + + int versionAndCommand = 0xFF & _buffer.get(); + if ((versionAndCommand & 0xF0) != 0x20) + throw new IOException("Proxy v2 bad PROXY version"); + _local = (versionAndCommand & 0xF) == 0x00; + + int transportAndFamily = 0xFF & _buffer.get(); + switch (transportAndFamily >> 4) + { + case 0: + _family = Family.UNSPEC; + break; + case 1: + _family = Family.INET; + break; + case 2: + _family = Family.INET6; + break; + case 3: + _family = Family.UNIX; + break; + default: + throw new IOException("Proxy v2 bad PROXY family"); + } + + Transport transport; + switch (0xF & transportAndFamily) + { + case 0: + transport = Transport.UNSPEC; + break; + case 1: + transport = Transport.STREAM; + break; + case 2: + transport = Transport.DGRAM; + break; + default: + throw new IOException("Proxy v2 bad PROXY family"); + } + + _length = _buffer.getChar(); + + if (!_local && (_family == Family.UNSPEC || _family == Family.UNIX || transport != Transport.STREAM)) + throw new IOException(String.format("Proxy v2 unsupported PROXY mode 0x%x,0x%x", versionAndCommand, transportAndFamily)); + + if (_length > getMaxProxyHeader()) + throw new IOException(String.format("Proxy v2 Unsupported PROXY mode 0x%x,0x%x,0x%x", versionAndCommand, transportAndFamily, _length)); + + if (LOG.isDebugEnabled()) + LOG.debug("Proxy v2 fixed length packet part is now parsed"); + _headerParsed = true; + } + + private void releaseAndClose() + { + _connector.getByteBufferPool().release(_buffer); + close(); + } } } - public static class ProxyEndPoint extends AttributesMap implements EndPoint + public static class ProxyEndPoint extends AttributesMap implements EndPoint, EndPoint.Wrapper { - private final EndPoint _endp; + private static final int PP2_TYPE_NOOP = 0x04; + private static final int PP2_TYPE_SSL = 0x20; + private static final int PP2_TYPE_SSL_PP2_CLIENT_SSL = 0x01; + private static final int PP2_SUBTYPE_SSL_VERSION = 0x21; + + private final EndPoint _endPoint; private final InetSocketAddress _remote; private final InetSocketAddress _local; + private Map _tlvs; - public ProxyEndPoint(EndPoint endp, InetSocketAddress remote, InetSocketAddress local) + public ProxyEndPoint(EndPoint endPoint, InetSocketAddress remote, InetSocketAddress local) { - _endp = endp; + _endPoint = endPoint; _remote = remote; _local = local; } - @Override - public boolean isOptimizedForDirectBuffers() + public EndPoint unwrap() { - return _endp.isOptimizedForDirectBuffers(); + return _endPoint; + } + + /** + *

      Sets a TLV vector, see section 2.2.7 of the PROXY protocol specification.

      + * + * @param type the TLV type + * @param value the TLV value + */ + private void putTLV(int type, byte[] value) + { + if (_tlvs == null) + _tlvs = new HashMap<>(); + _tlvs.put(type, value); + } + + /** + *

      Gets a TLV vector, see section 2.2.7 of the PROXY protocol specification.

      + * + * @param type the TLV type + * @return the TLV value or null if not present. + */ + public byte[] getTLV(int type) + { + return _tlvs != null ? _tlvs.get(type) : null; + } + + @Override + public void close(Throwable cause) + { + _endPoint.close(cause); + } + + @Override + public int fill(ByteBuffer buffer) throws IOException + { + return _endPoint.fill(buffer); + } + + @Override + public void fillInterested(Callback callback) throws ReadPendingException + { + _endPoint.fillInterested(callback); + } + + @Override + public boolean flush(ByteBuffer... buffer) throws IOException + { + return _endPoint.flush(buffer); + } + + @Override + public Connection getConnection() + { + return _endPoint.getConnection(); + } + + @Override + public void setConnection(Connection connection) + { + _endPoint.setConnection(connection); + } + + @Override + public long getCreatedTimeStamp() + { + return _endPoint.getCreatedTimeStamp(); + } + + @Override + public long getIdleTimeout() + { + return _endPoint.getIdleTimeout(); + } + + @Override + public void setIdleTimeout(long idleTimeout) + { + _endPoint.setIdleTimeout(idleTimeout); } @Override @@ -619,6 +844,54 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory return _remote; } + @Override + public Object getTransport() + { + return _endPoint.getTransport(); + } + + @Override + public boolean isFillInterested() + { + return _endPoint.isFillInterested(); + } + + @Override + public boolean isInputShutdown() + { + return _endPoint.isInputShutdown(); + } + + @Override + public boolean isOpen() + { + return _endPoint.isOpen(); + } + + @Override + public boolean isOutputShutdown() + { + return _endPoint.isOutputShutdown(); + } + + @Override + public void onClose(Throwable cause) + { + _endPoint.onClose(cause); + } + + @Override + public void onOpen() + { + _endPoint.onOpen(); + } + + @Override + public void shutdownOutput() + { + _endPoint.shutdownOutput(); + } + @Override public String toString() { @@ -627,127 +900,25 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory hashCode(), _remote, _local, - _endp); - } - - @Override - public boolean isOpen() - { - return _endp.isOpen(); - } - - @Override - public long getCreatedTimeStamp() - { - return _endp.getCreatedTimeStamp(); - } - - @Override - public void shutdownOutput() - { - _endp.shutdownOutput(); - } - - @Override - public boolean isOutputShutdown() - { - return _endp.isOutputShutdown(); - } - - @Override - public boolean isInputShutdown() - { - return _endp.isInputShutdown(); - } - - @Override - public void close(Throwable cause) - { - _endp.close(cause); - } - - @Override - public int fill(ByteBuffer buffer) throws IOException - { - return _endp.fill(buffer); - } - - @Override - public boolean flush(ByteBuffer... buffer) throws IOException - { - return _endp.flush(buffer); - } - - @Override - public Object getTransport() - { - return _endp.getTransport(); - } - - @Override - public long getIdleTimeout() - { - return _endp.getIdleTimeout(); - } - - @Override - public void setIdleTimeout(long idleTimeout) - { - _endp.setIdleTimeout(idleTimeout); - } - - @Override - public void fillInterested(Callback callback) throws ReadPendingException - { - _endp.fillInterested(callback); + _endPoint); } @Override public boolean tryFillInterested(Callback callback) { - return _endp.tryFillInterested(callback); - } - - @Override - public boolean isFillInterested() - { - return _endp.isFillInterested(); - } - - @Override - public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException - { - _endp.write(callback, buffers); - } - - @Override - public Connection getConnection() - { - return _endp.getConnection(); - } - - @Override - public void setConnection(Connection connection) - { - _endp.setConnection(connection); - } - - @Override - public void onOpen() - { - _endp.onOpen(); - } - - @Override - public void onClose(Throwable cause) - { - _endp.onClose(cause); + return _endPoint.tryFillInterested(callback); } @Override public void upgrade(Connection newConnection) { - _endp.upgrade(newConnection); + _endPoint.upgrade(newConnection); + } + + @Override + public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException + { + _endPoint.write(callback, buffers); } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/PushBuilderImpl.java b/jetty-server/src/main/java/org/eclipse/jetty/server/PushBuilderImpl.java index 74bf77775f5..78c78ac5508 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/PushBuilderImpl.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/PushBuilderImpl.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -28,15 +28,15 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * */ public class PushBuilderImpl implements PushBuilder { - private static final Logger LOG = Log.getLogger(PushBuilderImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(PushBuilderImpl.class); private static final HttpField JettyPush = new HttpField("x-http2-push", "PushBuilder"); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/QuietServletException.java b/jetty-server/src/main/java/org/eclipse/jetty/server/QuietServletException.java index a3912197bb1..1cf53032682 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/QuietServletException.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/QuietServletException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 1cc1ec53847..6abada24f58 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -58,6 +58,7 @@ import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletMapping; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpUpgradeHandler; @@ -94,8 +95,8 @@ import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.UrlEncoded; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Jetty Request. @@ -140,9 +141,8 @@ import org.eclipse.jetty.util.log.Logger; public class Request implements HttpServletRequest { public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.jetty.multipartConfig"; - public static final String __MULTIPARTS = "org.eclipse.jetty.multiParts"; - private static final Logger LOG = Log.getLogger(Request.class); + private static final Logger LOG = LoggerFactory.getLogger(Request.class); private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); private static final int INPUT_NONE = 0; private static final int INPUT_STREAM = 1; @@ -190,6 +190,85 @@ public class Request implements HttpServletRequest return null; } + public static HttpServletMapping getServletMapping(PathSpec pathSpec, String servletPath, String servletName) + { + final MappingMatch match; + final String mapping; + if (pathSpec instanceof ServletPathSpec) + { + switch (((ServletPathSpec)pathSpec).getGroup()) + { + case ROOT: + match = MappingMatch.CONTEXT_ROOT; + mapping = ""; + break; + case DEFAULT: + match = MappingMatch.DEFAULT; + mapping = "/"; + break; + case EXACT: + match = MappingMatch.EXACT; + mapping = servletPath.startsWith("/") ? servletPath.substring(1) : servletPath; + break; + case SUFFIX_GLOB: + match = MappingMatch.EXTENSION; + int dot = servletPath.lastIndexOf('.'); + mapping = servletPath.substring(0, dot); + break; + case PREFIX_GLOB: + match = MappingMatch.PATH; + mapping = servletPath; + break; + default: + match = null; + mapping = servletPath; + break; + } + } + else + { + match = null; + mapping = servletPath; + } + + return new HttpServletMapping() + { + @Override + public String getMatchValue() + { + return (mapping == null ? "" : mapping); + } + + @Override + public String getPattern() + { + if (pathSpec != null) + return pathSpec.getDeclaration(); + return ""; + } + + @Override + public String getServletName() + { + return (servletName == null ? "" : servletName); + } + + @Override + public MappingMatch getMappingMatch() + { + return match; + } + + @Override + public String toString() + { + return "HttpServletMapping{matchValue=" + getMatchValue() + + ", pattern=" + getPattern() + ", servletName=" + getServletName() + + ", mappingMatch=" + getMappingMatch() + "}"; + } + }; + } + private final HttpChannel _channel; private final List _requestAttributeListeners = new ArrayList<>(); private final HttpInput _input; @@ -211,6 +290,7 @@ public class Request implements HttpServletRequest private String _contentType; private String _characterEncoding; private ContextHandler.Context _context; + private ContextHandler.Context _errorContext; private Cookies _cookies; private DispatcherType _dispatcherType; private int _inputState = INPUT_NONE; @@ -226,8 +306,9 @@ public class Request implements HttpServletRequest private HttpSession _session; private SessionHandler _sessionHandler; private long _timeStamp; - private MultiParts _multiParts; //if the request is a multi-part mime + private MultiPartFormInputStream _multiParts; //if the request is a multi-part mime private AsyncContextState _async; + private List _sessions; //list of sessions used during lifetime of request public Request(HttpChannel channel, HttpInput input) { @@ -352,6 +433,48 @@ public class Request implements HttpServletRequest if (listener instanceof AsyncListener) throw new IllegalArgumentException(listener.getClass().toString()); } + + /** + * Remember a session that this request has just entered. + * + * @param s the session + */ + public void enterSession(HttpSession s) + { + if (!(s instanceof Session)) + return; + + if (_sessions == null) + _sessions = new ArrayList<>(); + if (LOG.isDebugEnabled()) + LOG.debug("Request {} entering session={}", this, s); + _sessions.add((Session)s); + } + + /** + * Complete this request's access to a session. + * + * @param session the session + */ + private void leaveSession(Session session) + { + if (LOG.isDebugEnabled()) + LOG.debug("Request {} leaving session {}", this, session); + session.getSessionHandler().complete(session); + } + + /** + * A response is being committed for a session, + * potentially write the session out before the + * client receives the response. + * @param session the session + */ + private void commitSession(Session session) + { + if (LOG.isDebugEnabled()) + LOG.debug("Response {} committing for session {}", this, session); + session.getSessionHandler().commit(session); + } private MultiMap getParameters() { @@ -429,9 +552,9 @@ public class Request implements HttpServletRequest catch (UnsupportedEncodingException e) { if (LOG.isDebugEnabled()) - LOG.warn(e); + LOG.warn("Unable to decode query", e); else - LOG.warn(e.toString()); + LOG.warn("Unable to decode query - {}", e.toString()); } } } @@ -472,8 +595,9 @@ public class Request implements HttpServletRequest } catch (IOException e) { - LOG.debug(e); - throw new RuntimeIOException(e); + String msg = "Unable to extract content parameters"; + LOG.debug(msg, e); + throw new RuntimeIOException(msg, e); } } } @@ -484,65 +608,49 @@ public class Request implements HttpServletRequest { try { - int maxFormContentSize = -1; - int maxFormKeys = -1; + int maxFormContentSize = ContextHandler.DEFAULT_MAX_FORM_CONTENT_SIZE; + int maxFormKeys = ContextHandler.DEFAULT_MAX_FORM_KEYS; if (_context != null) { - maxFormContentSize = _context.getContextHandler().getMaxFormContentSize(); - maxFormKeys = _context.getContextHandler().getMaxFormKeys(); + ContextHandler contextHandler = _context.getContextHandler(); + maxFormContentSize = contextHandler.getMaxFormContentSize(); + maxFormKeys = contextHandler.getMaxFormKeys(); } - - if (maxFormContentSize < 0) + else { - Object obj = _channel.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize"); - if (obj == null) - maxFormContentSize = 200000; - else if (obj instanceof Number) - { - Number size = (Number)obj; - maxFormContentSize = size.intValue(); - } - else if (obj instanceof String) - { - maxFormContentSize = Integer.parseInt((String)obj); - } - } - - if (maxFormKeys < 0) - { - Object obj = _channel.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys"); - if (obj == null) - maxFormKeys = 1000; - else if (obj instanceof Number) - { - Number keys = (Number)obj; - maxFormKeys = keys.intValue(); - } - else if (obj instanceof String) - { - maxFormKeys = Integer.parseInt((String)obj); - } + maxFormContentSize = lookupServerAttribute(ContextHandler.MAX_FORM_CONTENT_SIZE_KEY, maxFormContentSize); + maxFormKeys = lookupServerAttribute(ContextHandler.MAX_FORM_KEYS_KEY, maxFormKeys); } int contentLength = getContentLength(); - if (contentLength > maxFormContentSize && maxFormContentSize > 0) - { - throw new IllegalStateException("Form too large: " + contentLength + " > " + maxFormContentSize); - } + if (maxFormContentSize >= 0 && contentLength > maxFormContentSize) + throw new IllegalStateException("Form is larger than max length " + maxFormContentSize); + InputStream in = getInputStream(); if (_input.isAsync()) throw new IllegalStateException("Cannot extract parameters with async IO"); - UrlEncoded.decodeTo(in, params, getCharacterEncoding(), contentLength < 0 ? maxFormContentSize : -1, maxFormKeys); + UrlEncoded.decodeTo(in, params, getCharacterEncoding(), maxFormContentSize, maxFormKeys); } catch (IOException e) { - LOG.debug(e); - throw new RuntimeIOException(e); + String msg = "Unable to extract form parameters"; + LOG.debug(msg, e); + throw new RuntimeIOException(msg, e); } } + private int lookupServerAttribute(String key, int dftValue) + { + Object attribute = _channel.getServer().getAttribute(key); + if (attribute instanceof Number) + return ((Number)attribute).intValue(); + else if (attribute instanceof String) + return Integer.parseInt((String)attribute); + return dftValue; + } + @Override public AsyncContext getAsyncContext() { @@ -603,9 +711,6 @@ public class Request implements HttpServletRequest return (_attributes == null) ? null : _attributes.getAttribute(name); } - /* - * @see javax.servlet.ServletRequest#getAttributeNames() - */ @Override public Enumeration getAttributeNames() { @@ -632,9 +737,6 @@ public class Request implements HttpServletRequest return _authentication; } - /* - * @see javax.servlet.http.HttpServletRequest#getAuthType() - */ @Override public String getAuthType() { @@ -646,21 +748,24 @@ public class Request implements HttpServletRequest return null; } - /* - * @see javax.servlet.ServletRequest#getCharacterEncoding() - */ @Override public String getCharacterEncoding() { if (_characterEncoding == null) { - String contentType = getContentType(); - if (contentType != null) + if (_context != null) + _characterEncoding = _context.getRequestCharacterEncoding(); + + if (_characterEncoding == null) { - MimeTypes.Type mime = MimeTypes.CACHE.get(contentType); - String charset = (mime == null || mime.getCharset() == null) ? MimeTypes.getCharsetFromContentType(contentType) : mime.getCharset().toString(); - if (charset != null) - _characterEncoding = charset; + String contentType = getContentType(); + if (contentType != null) + { + MimeTypes.Type mime = MimeTypes.CACHE.get(contentType); + String charset = (mime == null || mime.getCharset() == null) ? MimeTypes.getCharsetFromContentType(contentType) : mime.getCharset().toString(); + if (charset != null) + _characterEncoding = charset; + } } } return _characterEncoding; @@ -674,9 +779,6 @@ public class Request implements HttpServletRequest return _channel; } - /* - * @see javax.servlet.ServletRequest#getContentLength() - */ @Override public int getContentLength() { @@ -700,9 +802,6 @@ public class Request implements HttpServletRequest return (int)metadata.getFields().getLongField(HttpHeader.CONTENT_LENGTH.asString()); } - /* - * @see javax.servlet.ServletRequest.getContentLengthLong() - */ @Override public long getContentLengthLong() { @@ -719,9 +818,6 @@ public class Request implements HttpServletRequest return _input.getContentConsumed(); } - /* - * @see javax.servlet.ServletRequest#getContentType() - */ @Override public String getContentType() { @@ -741,18 +837,28 @@ public class Request implements HttpServletRequest return _context; } - /* - * @see javax.servlet.http.HttpServletRequest#getContextPath() + /** + * @return The current {@link Context context} used for this error handling for this request. If the request is asynchronous, + * then it is the context that called async. Otherwise it is the last non-null context passed to #setContext */ + public Context getErrorContext() + { + if (isAsyncStarted()) + { + ContextHandler handler = _channel.getState().getContextHandler(); + if (handler != null) + return handler.getServletContext(); + } + + return _errorContext; + } + @Override public String getContextPath() { return _contextPath; } - /* - * @see javax.servlet.http.HttpServletRequest#getCookies() - */ @Override public Cookie[] getCookies() { @@ -784,9 +890,6 @@ public class Request implements HttpServletRequest return _cookies.getCookies(); } - /* - * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) - */ @Override public long getDateHeader(String name) { @@ -800,9 +903,6 @@ public class Request implements HttpServletRequest return _dispatcherType; } - /* - * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String) - */ @Override public String getHeader(String name) { @@ -810,9 +910,6 @@ public class Request implements HttpServletRequest return metadata == null ? null : metadata.getFields().get(name); } - /* - * @see javax.servlet.http.HttpServletRequest#getHeaderNames() - */ @Override public Enumeration getHeaderNames() { @@ -820,9 +917,6 @@ public class Request implements HttpServletRequest return metadata == null ? Collections.emptyEnumeration() : metadata.getFields().getFieldNames(); } - /* - * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String) - */ @Override public Enumeration getHeaders(String name) { @@ -843,9 +937,6 @@ public class Request implements HttpServletRequest return _inputState; } - /* - * @see javax.servlet.ServletRequest#getInputStream() - */ @Override public ServletInputStream getInputStream() throws IOException { @@ -859,9 +950,6 @@ public class Request implements HttpServletRequest return _input; } - /* - * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) - */ @Override public int getIntHeader(String name) { @@ -869,9 +957,6 @@ public class Request implements HttpServletRequest return metadata == null ? -1 : (int)metadata.getFields().getLongField(name); } - /* - * @see javax.servlet.ServletRequest#getLocale() - */ @Override public Locale getLocale() { @@ -897,9 +982,6 @@ public class Request implements HttpServletRequest return new Locale(language, country); } - /* - * @see javax.servlet.ServletRequest#getLocales() - */ @Override public Enumeration getLocales() { @@ -929,9 +1011,6 @@ public class Request implements HttpServletRequest return Collections.enumeration(locales); } - /* - * @see javax.servlet.ServletRequest#getLocalAddr() - */ @Override public String getLocalAddr() { @@ -946,7 +1025,7 @@ public class Request implements HttpServletRequest } catch (java.net.UnknownHostException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } @@ -959,9 +1038,6 @@ public class Request implements HttpServletRequest return address.getHostAddress(); } - /* - * @see javax.servlet.ServletRequest#getLocalName() - */ @Override public String getLocalName() { @@ -981,14 +1057,11 @@ public class Request implements HttpServletRequest } catch (java.net.UnknownHostException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return null; } - /* - * @see javax.servlet.ServletRequest#getLocalPort() - */ @Override public int getLocalPort() { @@ -998,9 +1071,6 @@ public class Request implements HttpServletRequest return local == null ? 0 : local.getPort(); } - /* - * @see javax.servlet.http.HttpServletRequest#getMethod() - */ @Override public String getMethod() { @@ -1010,36 +1080,24 @@ public class Request implements HttpServletRequest return null; } - /* - * @see javax.servlet.ServletRequest#getParameter(java.lang.String) - */ @Override public String getParameter(String name) { return getParameters().getValue(name, 0); } - /* - * @see javax.servlet.ServletRequest#getParameterMap() - */ @Override public Map getParameterMap() { return Collections.unmodifiableMap(getParameters().toStringArrayMap()); } - /* - * @see javax.servlet.ServletRequest#getParameterNames() - */ @Override public Enumeration getParameterNames() { return Collections.enumeration(getParameters().keySet()); } - /* - * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) - */ @Override public String[] getParameterValues(String name) { @@ -1069,18 +1127,12 @@ public class Request implements HttpServletRequest _parameters = null; } - /* - * @see javax.servlet.http.HttpServletRequest#getPathInfo() - */ @Override public String getPathInfo() { return _pathInfo; } - /* - * @see javax.servlet.http.HttpServletRequest#getPathTranslated() - */ @Override public String getPathTranslated() { @@ -1089,9 +1141,6 @@ public class Request implements HttpServletRequest return _context.getRealPath(_pathInfo); } - /* - * @see javax.servlet.ServletRequest#getProtocol() - */ @Override public String getProtocol() { @@ -1118,9 +1167,6 @@ public class Request implements HttpServletRequest return _queryEncoding; } - /* - * @see javax.servlet.http.HttpServletRequest#getQueryString() - */ @Override public String getQueryString() { @@ -1128,9 +1174,6 @@ public class Request implements HttpServletRequest return metadata == null ? null : metadata.getURI().getQuery(); } - /* - * @see javax.servlet.ServletRequest#getReader() - */ @Override public BufferedReader getReader() throws IOException { @@ -1185,9 +1228,6 @@ public class Request implements HttpServletRequest return remote; } - /* - * @see javax.servlet.ServletRequest#getRemoteAddr() - */ @Override public String getRemoteAddr() { @@ -1205,9 +1245,6 @@ public class Request implements HttpServletRequest return address.getHostAddress(); } - /* - * @see javax.servlet.ServletRequest#getRemoteHost() - */ @Override public String getRemoteHost() { @@ -1217,9 +1254,6 @@ public class Request implements HttpServletRequest return remote == null ? "" : remote.getHostString(); } - /* - * @see javax.servlet.ServletRequest#getRemotePort() - */ @Override public int getRemotePort() { @@ -1229,9 +1263,6 @@ public class Request implements HttpServletRequest return remote == null ? 0 : remote.getPort(); } - /* - * @see javax.servlet.http.HttpServletRequest#getRemoteUser() - */ @Override public String getRemoteUser() { @@ -1241,9 +1272,6 @@ public class Request implements HttpServletRequest return p.getName(); } - /* - * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String) - */ @Override public RequestDispatcher getRequestDispatcher(String path) { @@ -1269,18 +1297,12 @@ public class Request implements HttpServletRequest return _context.getRequestDispatcher(path); } - /* - * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() - */ @Override public String getRequestedSessionId() { return _requestedSessionId; } - /* - * @see javax.servlet.http.HttpServletRequest#getRequestURI() - */ @Override public String getRequestURI() { @@ -1288,9 +1310,6 @@ public class Request implements HttpServletRequest return metadata == null ? null : metadata.getURI().getPath(); } - /* - * @see javax.servlet.http.HttpServletRequest#getRequestURL() - */ @Override public StringBuffer getRequestURL() { @@ -1322,9 +1341,6 @@ public class Request implements HttpServletRequest return url; } - /* - * @see javax.servlet.ServletRequest#getScheme() - */ @Override public String getScheme() { @@ -1333,9 +1349,6 @@ public class Request implements HttpServletRequest return scheme == null ? HttpScheme.HTTP.asString() : scheme; } - /* - * @see javax.servlet.ServletRequest#getServerName() - */ @Override public String getServerName() { @@ -1363,14 +1376,11 @@ public class Request implements HttpServletRequest } catch (java.net.UnknownHostException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return null; } - /* - * @see javax.servlet.ServletRequest#getServerPort() - */ @Override public int getServerPort() { @@ -1412,9 +1422,6 @@ public class Request implements HttpServletRequest return null; } - /* - * @see javax.servlet.http.HttpServletRequest#getServletPath() - */ @Override public String getServletPath() { @@ -1448,18 +1455,79 @@ public class Request implements HttpServletRequest return session.getId(); } - /* - * @see javax.servlet.http.HttpServletRequest#getSession() + /** + * Called when the request is fully finished being handled. + * For every session in any context that the session has + * accessed, ensure that the session is completed. */ + public void onCompleted() + { + if (_sessions != null) + { + for (Session s:_sessions) + leaveSession(s); + } + + //Clean up any tmp files created by MultiPartInputStream + if (_multiParts != null) + { + try + { + _multiParts.deleteParts(); + } + catch (Throwable e) + { + LOG.warn("Errors deleting multipart tmp files", e); + } + } + } + + /** + * Called when a response is about to be committed, ie sent + * back to the client + */ + public void onResponseCommit() + { + if (_sessions != null) + { + for (Session s:_sessions) + commitSession(s); + } + } + + /** + * Find a session that this request has already entered for the + * given SessionHandler + * + * @param sessionHandler the SessionHandler (ie context) to check + * @return + */ + public HttpSession getSession(SessionHandler sessionHandler) + { + if (_sessions == null || _sessions.size() == 0 || sessionHandler == null) + return null; + + HttpSession session = null; + + for (HttpSession s:_sessions) + { + Session ss = Session.class.cast(s); + if (sessionHandler == ss.getSessionHandler()) + { + session = s; + if (ss.isValid()) + return session; + } + } + return session; + } + @Override public HttpSession getSession() { return getSession(true); } - /* - * @see javax.servlet.http.HttpServletRequest#getSession(boolean) - */ @Override public HttpSession getSession(boolean create) { @@ -1559,9 +1627,6 @@ public class Request implements HttpServletRequest return _scope; } - /* - * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() - */ @Override public Principal getUserPrincipal() { @@ -1594,18 +1659,12 @@ public class Request implements HttpServletRequest return _asyncNotSupportedSource == null; } - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() - */ @Override public boolean isRequestedSessionIdFromCookie() { return _requestedSessionId != null && _requestedSessionIdFromCookie; } - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() - */ @Override @Deprecated(since = "Servlet API 2.1") public boolean isRequestedSessionIdFromUrl() @@ -1613,18 +1672,12 @@ public class Request implements HttpServletRequest return _requestedSessionId != null && !_requestedSessionIdFromCookie; } - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() - */ @Override public boolean isRequestedSessionIdFromURL() { return _requestedSessionId != null && !_requestedSessionIdFromCookie; } - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() - */ @Override public boolean isRequestedSessionIdValid() { @@ -1635,9 +1688,6 @@ public class Request implements HttpServletRequest return (session != null && _sessionHandler.getSessionIdManager().getId(_requestedSessionId).equals(_sessionHandler.getId(session))); } - /* - * @see javax.servlet.ServletRequest#isSecure() - */ @Override public boolean isSecure() { @@ -1649,9 +1699,6 @@ public class Request implements HttpServletRequest _secure = secure; } - /* - * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) - */ @Override public boolean isUserInRole(String role) { @@ -1745,7 +1792,7 @@ public class Request implements HttpServletRequest } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); _reader = null; } } @@ -1786,12 +1833,11 @@ public class Request implements HttpServletRequest _inputState = INPUT_NONE; _multiParts = null; _remote = null; + _sessions = null; _input.recycle(); + _requestAttributeListeners.clear(); } - /* - * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String) - */ @Override public void removeAttribute(String name) { @@ -1820,7 +1866,7 @@ public class Request implements HttpServletRequest _asyncNotSupportedSource = supported ? null : (source == null ? "unknown" : source); } - /* + /** * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to * {@link #setQueryEncoding}. * @@ -1870,9 +1916,6 @@ public class Request implements HttpServletRequest _authentication = authentication; } - /* - * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) - */ @Override public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException { @@ -1924,6 +1967,7 @@ public class Request implements HttpServletRequest else { _context = context; + _errorContext = context; } } @@ -2137,7 +2181,7 @@ public class Request implements HttpServletRequest AsyncContextEvent event = new AsyncContextEvent(_context, _async, state, this, servletRequest, servletResponse); event.setDispatchContext(getServletContext()); - String uri = ((HttpServletRequest)servletRequest).getRequestURI(); + String uri = unwrap(servletRequest).getRequestURI(); if (_contextPath != null && uri.startsWith(_contextPath)) uri = uri.substring(_contextPath.length()); else @@ -2149,6 +2193,19 @@ public class Request implements HttpServletRequest return _async; } + public static HttpServletRequest unwrap(ServletRequest servletRequest) + { + if (servletRequest instanceof HttpServletRequestWrapper) + { + return (HttpServletRequestWrapper)servletRequest; + } + if (servletRequest instanceof ServletRequestWrapper) + { + return unwrap(((ServletRequestWrapper)servletRequest).getRequest()); + } + return ((HttpServletRequest)servletRequest); + } + @Override public String toString() { @@ -2185,15 +2242,12 @@ public class Request implements HttpServletRequest { String contentType = getContentType(); if (contentType == null || !MimeTypes.Type.MULTIPART_FORM_DATA.is(HttpFields.valueParameters(contentType, null))) - throw new ServletException("Content-Type != multipart/form-data"); + throw new ServletException("Unsupported Content-Type [" + contentType + "], expected [multipart/form-data]"); return getParts(null); } private Collection getParts(MultiMap params) throws IOException { - if (_multiParts == null) - _multiParts = (MultiParts)getAttribute(__MULTIPARTS); - if (_multiParts == null) { MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT); @@ -2201,7 +2255,6 @@ public class Request implements HttpServletRequest throw new IllegalStateException("No multipart config for servlet"); _multiParts = newMultiParts(config); - setAttribute(__MULTIPARTS, _multiParts); Collection parts = _multiParts.getParts(); String formCharset = null; @@ -2263,10 +2316,10 @@ public class Request implements HttpServletRequest return _multiParts.getParts(); } - private MultiParts newMultiParts(MultipartConfigElement config) throws IOException + private MultiPartFormInputStream newMultiParts(MultipartConfigElement config) throws IOException { - return new MultiParts.MultiPartsHttpParser(getInputStream(), getContentType(), config, - (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); + return new MultiPartFormInputStream(getInputStream(), getContentType(), config, + (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null)); } @Override @@ -2363,9 +2416,6 @@ public class Request implements HttpServletRequest } } - /** - * @see javax.servlet.http.HttpServletRequest#upgrade(java.lang.Class) - */ @Override public T upgrade(Class handlerClass) throws IOException, ServletException { @@ -2385,73 +2435,6 @@ public class Request implements HttpServletRequest @Override public HttpServletMapping getHttpServletMapping() { - final PathSpec pathSpec = _pathSpec; - final MappingMatch match; - final String mapping; - if (pathSpec instanceof ServletPathSpec) - { - switch (((ServletPathSpec)pathSpec).getGroup()) - { - case ROOT: - match = MappingMatch.CONTEXT_ROOT; - mapping = ""; - break; - case DEFAULT: - match = MappingMatch.DEFAULT; - mapping = "/"; - break; - case EXACT: - match = MappingMatch.EXACT; - mapping = _servletPath.startsWith("/") ? _servletPath.substring(1) : _servletPath; - break; - case SUFFIX_GLOB: - match = MappingMatch.EXTENSION; - int dot = _servletPath.lastIndexOf('.'); - mapping = _servletPath.substring(0, dot); - break; - case PREFIX_GLOB: - match = MappingMatch.PATH; - mapping = _servletPath; - break; - default: - match = null; - mapping = _servletPath; - break; - } - } - else - { - match = null; - mapping = _servletPath; - } - - return new HttpServletMapping() - { - @Override - public String getMatchValue() - { - return mapping; - } - - @Override - public String getPattern() - { - if (pathSpec != null) - pathSpec.toString(); - return null; - } - - @Override - public String getServletName() - { - return Request.this.getServletName(); - } - - @Override - public MappingMatch getMappingMatch() - { - return match; - } - }; + return Request.getServletMapping(_pathSpec, _servletPath, getServletName()); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java index ada57acbe03..dcdefdc6536 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogCollection.java index 204bd22b607..bd8ef066b1c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogCollection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogWriter.java index 44213fe8c1a..b9c3b9e666d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -28,8 +28,8 @@ import org.eclipse.jetty.util.RolloverFileOutputStream; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Writer which outputs pre-formatted request log strings to a file using {@link RolloverFileOutputStream}. @@ -37,7 +37,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject("Request Log writer which writes to file") public class RequestLogWriter extends AbstractLifeCycle implements RequestLog.Writer { - private static final Logger LOG = Log.getLogger(RequestLogWriter.class); + private static final Logger LOG = LoggerFactory.getLogger(RequestLogWriter.class); private String _filename; private boolean _append; @@ -230,7 +230,7 @@ public class RequestLogWriter extends AbstractLifeCycle implements RequestLog.Wr } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } if (_out != null && _closeOut) try @@ -239,7 +239,7 @@ public class RequestLogWriter extends AbstractLifeCycle implements RequestLog.Wr } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } _out = null; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceContentFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceContentFactory.java index 95a9d83e533..d235990aa52 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceContentFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceContentFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -32,7 +32,7 @@ import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; /** - * A HttpContent.Factory for transient content (not cached). The HttpContent's created by + * An HttpContent.Factory for transient content (not cached). The HttpContent's created by * this factory are not intended to be cached, so memory limits for individual * HttpOutput streams are enforced. */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java index 083a81032e8..b8ce35ebdb2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.Collection; @@ -46,14 +47,16 @@ import org.eclipse.jetty.http.QuotedCSV; import org.eclipse.jetty.http.QuotedQualityCSV; import org.eclipse.jetty.io.WriterOutputStream; import org.eclipse.jetty.server.resource.HttpContentRangeWriter; +import org.eclipse.jetty.server.resource.InputStreamRangeWriter; import org.eclipse.jetty.server.resource.RangeWriter; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.MultiPartOutputStream; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.util.Arrays.stream; import static java.util.Collections.emptyList; @@ -64,7 +67,7 @@ import static org.eclipse.jetty.http.HttpHeaderValue.IDENTITY; */ public class ResourceService { - private static final Logger LOG = Log.getLogger(ResourceService.class); + private static final Logger LOG = LoggerFactory.getLogger(ResourceService.class); private static final PreEncodedHttpField ACCEPT_RANGES = new PreEncodedHttpField(HttpHeader.ACCEPT_RANGES, "bytes"); @@ -294,7 +297,7 @@ public class ResourceService } catch (IllegalArgumentException e) { - LOG.warn(Log.EXCEPTION, e); + LOG.warn("Failed to serve resource: {}", pathInContext, e); if (!response.isCommitted()) response.sendError(500, e.getMessage()); } @@ -669,18 +672,14 @@ public class ResourceService if (include) { // write without headers - content.getResource().writeTo(out, 0, content_length); + writeContent(content, out, 0, content_length); } // else if we can't do a bypass write because of wrapping else if (written || !(out instanceof HttpOutput)) { // write normally putHeaders(response, content, written ? -1 : 0); - ByteBuffer buffer = content.getIndirectBuffer(); - if (buffer != null) - BufferUtil.writeTo(buffer, out); - else - content.getResource().writeTo(out, 0, content_length); + writeContent(content, out, 0, content_length); } // else do a bypass write else @@ -706,10 +705,11 @@ public class ResourceService @Override public void failed(Throwable x) { + String msg = "Failed to send content"; if (x instanceof IOException) - LOG.debug(x); + LOG.debug(msg, x); else - LOG.warn(x); + LOG.warn(msg, x); context.complete(); content.release(); } @@ -753,7 +753,7 @@ public class ResourceService response.addDateHeader(HttpHeader.DATE.asString(), System.currentTimeMillis()); response.setHeader(HttpHeader.CONTENT_RANGE.asString(), singleSatisfiableRange.toHeaderRangeString(content_length)); - content.getResource().writeTo(out, singleSatisfiableRange.getFirst(), singleLength); + writeContent(content, out, singleSatisfiableRange.getFirst(), singleLength); return true; } @@ -815,6 +815,33 @@ public class ResourceService return true; } + private static void writeContent(HttpContent content, OutputStream out, long start, long contentLength) throws IOException + { + // Is the write for the whole content? + if (start == 0 && content.getResource().length() == contentLength) + { + // attempt efficient ByteBuffer based write for whole content + ByteBuffer buffer = content.getIndirectBuffer(); + if (buffer != null) + { + BufferUtil.writeTo(buffer, out); + return; + } + + try (InputStream input = content.getResource().getInputStream()) + { + IO.copy(input, out); + return; + } + } + + // Use a ranged writer + try (InputStreamRangeWriter rangeWriter = new InputStreamRangeWriter(() -> content.getInputStream())) + { + rangeWriter.writeTo(out, start, contentLength); + } + } + protected void putHeaders(HttpServletResponse response, HttpContent content, long contentLength) { if (response instanceof Response) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index 13ac5e09b3e..1d934ac14ea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -24,22 +24,24 @@ import java.nio.channels.IllegalSelectorException; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; -import java.util.List; +import java.util.Iterator; import java.util.ListIterator; import java.util.Locale; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -import javax.servlet.RequestDispatcher; import javax.servlet.ServletOutputStream; +import javax.servlet.ServletResponse; +import javax.servlet.ServletResponseWrapper; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; import javax.servlet.http.HttpSession; import org.eclipse.jetty.http.CookieCompliance; import org.eclipse.jetty.http.DateGenerator; import org.eclipse.jetty.http.HttpContent; import org.eclipse.jetty.http.HttpCookie; +import org.eclipse.jetty.http.HttpCookie.SameSite; import org.eclipse.jetty.http.HttpCookie.SetCookieHttpField; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; @@ -54,20 +56,21 @@ import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.PreEncodedHttpField; import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ErrorHandler; +import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.util.AtomicBiInteger; +import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      {@link Response} provides the implementation for {@link HttpServletResponse}.

      */ public class Response implements HttpServletResponse { - private static final Logger LOG = Log.getLogger(Response.class); + private static final Logger LOG = LoggerFactory.getLogger(Response.class); private static final int __MIN_BUFFER_SIZE = 1; private static final HttpField __EXPIRES_01JAN1970 = new PreEncodedHttpField(HttpHeader.EXPIRES, DateGenerator.__01Jan1970); @@ -83,15 +86,9 @@ public class Response implements HttpServletResponse */ public static final String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include."; - /** - * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie - * will be set as HTTP ONLY. - */ - public static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__"; - private final HttpChannel _channel; private final HttpFields _fields = new HttpFields(); - private final AtomicInteger _include = new AtomicInteger(); + private final AtomicBiInteger _errorSentAndIncludes = new AtomicBiInteger(); // hi is errorSent flag, lo is include count private final HttpOutput _out; private int _status = HttpStatus.OK_200; private String _reason; @@ -137,6 +134,7 @@ public class Response implements HttpServletResponse _out.recycle(); _fields.clear(); _encodingFrom = EncodingFrom.NOT_SET; + _trailers = null; } public HttpOutput getHttpOutput() @@ -144,19 +142,46 @@ public class Response implements HttpServletResponse return _out; } + public void reopen() + { + // Make the response mutable and reopen output. + setErrorSent(false); + _out.reopen(); + } + + public void errorClose() + { + // Make the response immutable and soft close the output. + setErrorSent(true); + _out.softClose(); + } + + /** + * @return true if the response is mutable, ie not errorSent and not included + */ + private boolean isMutable() + { + return _errorSentAndIncludes.get() == 0; + } + + private void setErrorSent(boolean errorSent) + { + _errorSentAndIncludes.getAndSetHi(errorSent ? 1 : 0); + } + public boolean isIncluding() { - return _include.get() > 0; + return _errorSentAndIncludes.getLo() > 0; } public void include() { - _include.incrementAndGet(); + _errorSentAndIncludes.add(0, 1); } public void included() { - _include.decrementAndGet(); + _errorSentAndIncludes.add(0, -1); if (_outputType == OutputType.WRITER) { _writer.reopen(); @@ -168,13 +193,42 @@ public class Response implements HttpServletResponse { if (StringUtil.isBlank(cookie.getName())) throw new IllegalArgumentException("Cookie.name cannot be blank/null"); - + // add the set cookie - _fields.add(new SetCookieHttpField(cookie, getHttpChannel().getHttpConfiguration().getResponseCookieCompliance())); + _fields.add(new SetCookieHttpField(checkSameSite(cookie), getHttpChannel().getHttpConfiguration().getResponseCookieCompliance())); // Expire responses with set-cookie headers so they do not get cached. _fields.put(__EXPIRES_01JAN1970); } + + /** + * Check that samesite is set on the cookie. If not, use a + * context default value, if one has been set. + * + * @param cookie the cookie to check + * @return either the original cookie, or a new one that has the samesit default set + */ + private HttpCookie checkSameSite(HttpCookie cookie) + { + if (cookie == null || cookie.getSameSite() != null) + return cookie; + + //sameSite is not set, use the default configured for the context, if one exists + SameSite contextDefault = HttpCookie.getSameSiteDefault(_channel.getRequest().getContext()); + if (contextDefault == null) + return cookie; //no default set + + return new HttpCookie(cookie.getName(), + cookie.getValue(), + cookie.getDomain(), + cookie.getPath(), + cookie.getMaxAge(), + cookie.isHttpOnly(), + cookie.isSecure(), + cookie.getComment(), + cookie.getVersion(), + contextDefault); + } @Override public void addCookie(Cookie cookie) @@ -183,19 +237,10 @@ public class Response implements HttpServletResponse throw new IllegalArgumentException("Cookie.name cannot be blank/null"); String comment = cookie.getComment(); - boolean httpOnly = cookie.isHttpOnly(); - - if (comment != null) - { - int i = comment.indexOf(HTTP_ONLY_COMMENT); - if (i >= 0) - { - httpOnly = true; - comment = StringUtil.strip(comment.trim(), HTTP_ONLY_COMMENT); - if (comment.length() == 0) - comment = null; - } - } + // HttpOnly was supported as a comment in cookie flags before the java.net.HttpCookie implementation so need to check that + boolean httpOnly = cookie.isHttpOnly() || HttpCookie.isHttpOnlyInComment(comment); + SameSite sameSite = HttpCookie.getSameSiteFromComment(comment); + comment = HttpCookie.getCommentWithoutAttributes(comment); addCookie(new HttpCookie( cookie.getName(), @@ -206,7 +251,8 @@ public class Response implements HttpServletResponse httpOnly, cookie.getSecure(), comment, - cookie.getVersion())); + cookie.getVersion(), + sameSite)); } /** @@ -223,7 +269,7 @@ public class Response implements HttpServletResponse if (field.getHeader() == HttpHeader.SET_COOKIE) { - final CookieCompliance compliance = getHttpChannel().getHttpConfiguration().getResponseCookieCompliance(); + CookieCompliance compliance = getHttpChannel().getHttpConfiguration().getResponseCookieCompliance(); HttpCookie oldCookie; if (field instanceof SetCookieHttpField) @@ -250,7 +296,7 @@ public class Response implements HttpServletResponse else if (!cookie.getPath().equals(oldCookie.getPath())) continue; - i.set(new SetCookieHttpField(cookie, compliance)); + i.set(new SetCookieHttpField(checkSameSite(cookie), compliance)); return; } } @@ -389,71 +435,40 @@ public class Response implements HttpServletResponse sendError(sc, null); } + /** + * Send an error response. + *

      In addition to the servlet standard handling, this method supports some additional codes:

      + *
      + *
      102
      Send a partial PROCESSING response and allow additional responses
      + *
      -1
      Abort the HttpChannel and close the connection/stream
      + *
      + * @param code The error code + * @param message The message + * @throws IOException If an IO problem occurred sending the error response. + */ @Override public void sendError(int code, String message) throws IOException { if (isIncluding()) return; - if (isCommitted()) - { - if (LOG.isDebugEnabled()) - LOG.debug("Aborting on sendError on committed response {} {}", code, message); - code = -1; - } - else - resetBuffer(); - switch (code) { case -1: - _channel.abort(new IOException()); - return; - case 102: + _channel.abort(new IOException(message)); + break; + case HttpStatus.PROCESSING_102: sendProcessing(); - return; + break; default: + _channel.getState().sendError(code, message); break; } - - _outputType = OutputType.NONE; - setContentType(null); - setCharacterEncoding(null); - setHeader(HttpHeader.EXPIRES, null); - setHeader(HttpHeader.LAST_MODIFIED, null); - setHeader(HttpHeader.CACHE_CONTROL, null); - setHeader(HttpHeader.CONTENT_TYPE, null); - setHeader(HttpHeader.CONTENT_LENGTH, null); - - setStatus(code); - - Request request = _channel.getRequest(); - Throwable cause = (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION); - _reason = HttpStatus.getMessage(code); - if (message == null) - message = cause == null ? _reason : cause.toString(); - - // If we are allowed to have a body, then produce the error page. - if (code != SC_NO_CONTENT && code != SC_NOT_MODIFIED && - code != SC_PARTIAL_CONTENT && code >= SC_OK) - { - ContextHandler.Context context = request.getContext(); - ContextHandler contextHandler = context == null ? _channel.getState().getContextHandler() : context.getContextHandler(); - request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, code); - request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); - request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); - request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME, request.getServletName()); - ErrorHandler errorHandler = ErrorHandler.getErrorHandler(_channel.getServer(), contextHandler); - if (errorHandler != null) - errorHandler.handle(null, request, request, this); - } - if (!request.isAsyncStarted()) - closeOutput(); } /** * Sends a 102-Processing response. - * If the connection is a HTTP connection, the version is 1.1 and the + * If the connection is an HTTP connection, the version is 1.1 and the * request has a Expect header starting with 102, then a 102 response is * sent. This indicates that the request still be processed and real response * can still be sent. This method is called by sendError if it is passed 102. @@ -481,7 +496,7 @@ public class Response implements HttpServletResponse if ((code < HttpServletResponse.SC_MULTIPLE_CHOICES) || (code >= HttpServletResponse.SC_BAD_REQUEST)) throw new IllegalArgumentException("Not a 3xx redirect code"); - if (isIncluding()) + if (!isMutable()) return; if (location == null) @@ -527,34 +542,34 @@ public class Response implements HttpServletResponse @Override public void setDateHeader(String name, long date) { - if (!isIncluding()) + if (isMutable()) _fields.putDateField(name, date); } @Override public void addDateHeader(String name, long date) { - if (!isIncluding()) + if (isMutable()) _fields.addDateField(name, date); } public void setHeader(HttpHeader name, String value) { - if (HttpHeader.CONTENT_TYPE == name) - setContentType(value); - else + if (isMutable()) { - if (isIncluding()) - return; - - _fields.put(name, value); - - if (HttpHeader.CONTENT_LENGTH == name) + if (HttpHeader.CONTENT_TYPE == name) + setContentType(value); + else { - if (value == null) - _contentLength = -1L; - else - _contentLength = Long.parseLong(value); + _fields.put(name, value); + + if (HttpHeader.CONTENT_LENGTH == name) + { + if (value == null) + _contentLength = -1L; + else + _contentLength = Long.parseLong(value); + } } } } @@ -562,17 +577,21 @@ public class Response implements HttpServletResponse @Override public void setHeader(String name, String value) { + long biInt = _errorSentAndIncludes.get(); + if (biInt != 0) + { + boolean errorSent = AtomicBiInteger.getHi(biInt) != 0; + boolean including = AtomicBiInteger.getLo(biInt) > 0; + if (!errorSent && including && name.startsWith(SET_INCLUDE_HEADER_PREFIX)) + name = name.substring(SET_INCLUDE_HEADER_PREFIX.length()); + else + return; + } + if (HttpHeader.CONTENT_TYPE.is(name)) setContentType(value); else { - if (isIncluding()) - { - if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) - name = name.substring(SET_INCLUDE_HEADER_PREFIX.length()); - else - return; - } _fields.put(name, value); if (HttpHeader.CONTENT_LENGTH.is(name)) { @@ -608,9 +627,12 @@ public class Response implements HttpServletResponse @Override public void addHeader(String name, String value) { - if (isIncluding()) + long biInt = _errorSentAndIncludes.get(); + if (biInt != 0) { - if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) + boolean errorSent = AtomicBiInteger.getHi(biInt) != 0; + boolean including = AtomicBiInteger.getLo(biInt) > 0; + if (!errorSent && including && name.startsWith(SET_INCLUDE_HEADER_PREFIX)) name = name.substring(SET_INCLUDE_HEADER_PREFIX.length()); else return; @@ -634,7 +656,7 @@ public class Response implements HttpServletResponse @Override public void setIntHeader(String name, int value) { - if (!isIncluding()) + if (isMutable()) { _fields.putLongField(name, value); if (HttpHeader.CONTENT_LENGTH.is(name)) @@ -645,7 +667,7 @@ public class Response implements HttpServletResponse @Override public void addIntHeader(String name, int value) { - if (!isIncluding()) + if (isMutable()) { _fields.add(name, Integer.toString(value)); if (HttpHeader.CONTENT_LENGTH.is(name)) @@ -658,10 +680,13 @@ public class Response implements HttpServletResponse { if (sc <= 0) throw new IllegalArgumentException(); - if (!isIncluding()) + if (isMutable()) { + // Null the reason only if the status is different. This allows + // a specific reason to be sent with setStatusWithReason followed by sendError. + if (_status != sc) + _reason = null; _status = sc; - _reason = null; } } @@ -676,7 +701,7 @@ public class Response implements HttpServletResponse { if (sc <= 0) throw new IllegalArgumentException(); - if (!isIncluding()) + if (isMutable()) { _status = sc; _reason = message; @@ -691,9 +716,18 @@ public class Response implements HttpServletResponse String encoding = MimeTypes.getCharsetAssumedFromContentType(_contentType); if (encoding != null) return encoding; + encoding = MimeTypes.getCharsetInferredFromContentType(_contentType); if (encoding != null) return encoding; + + Context context = _channel.getRequest().getContext(); + if (context != null) + { + encoding = context.getResponseCharacterEncoding(); + if (encoding != null) + return encoding; + } return StringUtil.__ISO_8859_1; } return _characterEncoding; @@ -724,6 +758,11 @@ public class Response implements HttpServletResponse return _outputType == OutputType.STREAM; } + public boolean isWritingOrStreaming() + { + return isWriting() || isStreaming(); + } + @Override public PrintWriter getWriter() throws IOException { @@ -732,23 +771,42 @@ public class Response implements HttpServletResponse if (_outputType == OutputType.NONE) { - /* get encoding from Content-Type header */ + //first try explicit char encoding String encoding = _characterEncoding; + + //try char set from mime type if (encoding == null) { if (_mimeType != null && _mimeType.isCharsetAssumed()) encoding = _mimeType.getCharsetString(); - else - { - encoding = MimeTypes.getCharsetAssumedFromContentType(_contentType); - if (encoding == null) - { - encoding = MimeTypes.getCharsetInferredFromContentType(_contentType); - if (encoding == null) - encoding = StringUtil.__ISO_8859_1; - setCharacterEncoding(encoding, EncodingFrom.INFERRED); - } - } + } + + //try char set assumed from content type + if (encoding == null) + { + encoding = MimeTypes.getCharsetAssumedFromContentType(_contentType); + } + + //try char set inferred from content type + if (encoding == null) + { + encoding = MimeTypes.getCharsetInferredFromContentType(_contentType); + setCharacterEncoding(encoding, EncodingFrom.INFERRED); + } + + //try any default char encoding for the context + if (encoding == null) + { + Context context = _channel.getRequest().getContext(); + if (context != null) + encoding = context.getResponseCharacterEncoding(); + } + + //fallback to last resort iso-8859-1 + if (encoding == null) + { + encoding = StringUtil.__ISO_8859_1; + setCharacterEncoding(encoding, EncodingFrom.INFERRED); } Locale locale = getLocale(); @@ -777,7 +835,7 @@ public class Response implements HttpServletResponse // Protect from setting after committed as default handling // of a servlet HEAD request ALWAYS sets _content length, even // if the getHandling committed the response! - if (isCommitted() || isIncluding()) + if (isCommitted() || !isMutable()) return; if (len > 0) @@ -832,21 +890,29 @@ public class Response implements HttpServletResponse public void closeOutput() throws IOException { - switch (_outputType) - { - case WRITER: - _writer.close(); - if (!_out.isClosed()) - _out.close(); - break; - case STREAM: - if (!_out.isClosed()) - getOutputStream().close(); - break; - default: - if (!_out.isClosed()) - _out.close(); - } + if (_outputType == OutputType.WRITER) + _writer.close(); + else + _out.close(); + } + + /** + * close the output + * + * @deprecated Use {@link #closeOutput()} + */ + @Deprecated + public void completeOutput() throws IOException + { + closeOutput(); + } + + public void completeOutput(Callback callback) + { + if (_outputType == OutputType.WRITER) + _writer.complete(callback); + else + _out.complete(callback); } public long getLongContentLength() @@ -859,7 +925,7 @@ public class Response implements HttpServletResponse // Protect from setting after committed as default handling // of a servlet HEAD request ALWAYS sets _content length, even // if the getHandling committed the response! - if (isCommitted() || isIncluding()) + if (isCommitted() || !isMutable()) return; _contentLength = len; _fields.putLongField(HttpHeader.CONTENT_LENGTH.toString(), len); @@ -879,7 +945,7 @@ public class Response implements HttpServletResponse private void setCharacterEncoding(String encoding, EncodingFrom from) { - if (isIncluding() || isWriting()) + if (!isMutable() || isWriting()) return; if (_outputType != OutputType.WRITER && !isCommitted()) @@ -932,7 +998,7 @@ public class Response implements HttpServletResponse @Override public void setContentType(String contentType) { - if (isCommitted() || isIncluding()) + if (isCommitted() || !isMutable()) return; if (contentType == null) @@ -1039,19 +1105,21 @@ public class Response implements HttpServletResponse @Override public void reset() { - reset(false); - } - - public void reset(boolean preserveCookies) - { - resetForForward(); _status = 200; _reason = null; + _out.resetBuffer(); + _outputType = OutputType.NONE; _contentLength = -1; + _contentType = null; + _mimeType = null; + _characterEncoding = null; + _encodingFrom = EncodingFrom.NOT_SET; + _trailers = null; - List cookies = preserveCookies ? _fields.getFields(HttpHeader.SET_COOKIE) : null; + // Clear all response headers _fields.clear(); + // recreate necessary connection related fields for (String value : _channel.getRequest().getHttpFields().getCSV(HttpHeader.CONNECTION, false)) { HttpHeaderValue cb = HttpHeaderValue.CACHE.get(value); @@ -1074,21 +1142,57 @@ public class Response implements HttpServletResponse } } - if (preserveCookies) - cookies.forEach(_fields::add); - else + // recreate session cookies + Request request = getHttpChannel().getRequest(); + HttpSession session = request.getSession(false); + if (session != null && session.isNew()) { - Request request = getHttpChannel().getRequest(); - HttpSession session = request.getSession(false); - if (session != null && session.isNew()) + SessionHandler sh = request.getSessionHandler(); + if (sh != null) { - SessionHandler sh = request.getSessionHandler(); - if (sh != null) - { - HttpCookie c = sh.getSessionCookie(session, request.getContextPath(), request.isSecure()); - if (c != null) - addCookie(c); - } + HttpCookie c = sh.getSessionCookie(session, request.getContextPath(), request.isSecure()); + if (c != null) + addCookie(c); + } + } + } + + public void resetContent() + { + _out.resetBuffer(); + _outputType = OutputType.NONE; + _contentLength = -1; + _contentType = null; + _mimeType = null; + _characterEncoding = null; + _encodingFrom = EncodingFrom.NOT_SET; + + // remove the content related response headers and keep all others + for (Iterator i = getHttpFields().iterator(); i.hasNext(); ) + { + HttpField field = i.next(); + if (field.getHeader() == null) + continue; + + switch (field.getHeader()) + { + case CONTENT_TYPE: + case CONTENT_LENGTH: + case CONTENT_ENCODING: + case CONTENT_LANGUAGE: + case CONTENT_RANGE: + case CONTENT_MD5: + case CONTENT_LOCATION: + case TRANSFER_ENCODING: + case CACHE_CONTROL: + case LAST_MODIFIED: + case EXPIRES: + case ETAG: + case DATE: + case VARY: + i.remove(); + continue; + default: } } } @@ -1103,13 +1207,7 @@ public class Response implements HttpServletResponse public void resetBuffer() { _out.resetBuffer(); - } - - @Override - public void setTrailerFields(Supplier> trailers) - { - // TODO new for 4.0 - avoid transient supplier? - this._trailers = new HttpFieldsSupplier(trailers); + _out.reopen(); } public Supplier getTrailers() @@ -1117,14 +1215,26 @@ public class Response implements HttpServletResponse return _trailers; } + public void setTrailers(Supplier trailers) + { + _trailers = trailers; + } + @Override public Supplier> getTrailerFields() { if (_trailers instanceof HttpFieldsSupplier) - ((HttpFieldsSupplier)_trailers).getSupplier(); + return ((HttpFieldsSupplier)_trailers).getSupplier(); return null; } + @Override + public void setTrailerFields(Supplier> trailers) + { + // TODO new for 4.0 - avoid transient supplier? + this._trailers = new HttpFieldsSupplier(trailers); + } + protected MetaData.Response newResponseMetaData() { MetaData.Response info = new MetaData.Response(_channel.getRequest().getHttpVersion(), getStatus(), getReason(), _fields, getLongContentLength()); @@ -1153,13 +1263,16 @@ public class Response implements HttpServletResponse @Override public boolean isCommitted() { + // If we are in sendError state, we pretend to be committed + if (_channel.isSendError()) + return true; return _channel.isCommitted(); } @Override public void setLocale(Locale locale) { - if (locale == null || isCommitted() || isIncluding()) + if (locale == null || isCommitted() || !isMutable()) return; _locale = locale; @@ -1292,6 +1405,19 @@ public class Response implements HttpServletResponse } } + public static HttpServletResponse unwrap(ServletResponse servletResponse) + { + if (servletResponse instanceof HttpServletResponseWrapper) + { + return (HttpServletResponseWrapper)servletResponse; + } + if (servletResponse instanceof ServletResponseWrapper) + { + return unwrap(((ServletResponseWrapper)servletResponse).getResponse()); + } + return (HttpServletResponse)servletResponse; + } + private static class HttpFieldsSupplier implements Supplier { private final Supplier> _supplier; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java index f2c6352e623..58787784d82 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -27,8 +27,9 @@ import javax.servlet.ServletResponse; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.Callback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Specialized PrintWriter for servlet Responses @@ -42,7 +43,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ResponseWriter extends PrintWriter { - private static final Logger LOG = Log.getLogger(ResponseWriter.class); + private static final Logger LOG = LoggerFactory.getLogger(ResponseWriter.class); private static final String __lineSeparator = System.getProperty("line.separator"); private static final String __trueln = "true" + __lineSeparator; private static final String __falseln = "false" + __lineSeparator; @@ -113,7 +114,7 @@ public class ResponseWriter extends PrintWriter } if (LOG.isDebugEnabled()) - LOG.debug(th); + LOG.debug("PrintWriter Error is set", th); } @Override @@ -128,10 +129,13 @@ public class ResponseWriter extends PrintWriter private void isOpen() throws IOException { if (_ioException != null) - throw new RuntimeIOException(_ioException); + throw _ioException; if (_isClosed) - throw new EofException("Stream closed"); + { + _ioException = new EofException("Stream closed"); + throw _ioException; + } } @Override @@ -145,7 +149,7 @@ public class ResponseWriter extends PrintWriter out.flush(); } } - catch (IOException ex) + catch (Throwable ex) { setError(ex); } @@ -168,6 +172,15 @@ public class ResponseWriter extends PrintWriter } } + public void complete(Callback callback) + { + synchronized (lock) + { + _isClosed = true; + } + _httpWriter.complete(callback); + } + @Override public void write(int c) { @@ -181,7 +194,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("Write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -203,7 +216,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("Write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -231,7 +244,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("Write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -315,7 +328,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -343,7 +356,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("Write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -390,7 +403,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("Write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -416,7 +429,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("Write interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) @@ -478,7 +491,7 @@ public class ResponseWriter extends PrintWriter } catch (InterruptedIOException ex) { - LOG.debug(ex); + LOG.debug("format interrupted", ex); Thread.currentThread().interrupt(); } catch (IOException ex) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SameFileAliasChecker.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SameFileAliasChecker.java new file mode 100644 index 00000000000..c56a403598b --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SameFileAliasChecker.java @@ -0,0 +1,78 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.jetty.server.handler.ContextHandler.AliasCheck; +import org.eclipse.jetty.util.resource.PathResource; +import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Alias checking for working with FileSystems that normalize access to the + * File System. + *

      + * The Java {@link Files#isSameFile(Path, Path)} method is used to determine + * if the requested file is the same as the alias file. + *

      + *

      + * For File Systems that are case insensitive (eg: Microsoft Windows FAT32 and NTFS), + * the access to the file can be in any combination or style of upper and lowercase. + *

      + *

      + * For File Systems that normalize UTF-8 access (eg: Mac OSX on HFS+ or APFS, + * or Linux on XFS) the the actual file could be stored using UTF-16, + * but be accessed using NFD UTF-8 or NFC UTF-8 for the same file. + *

      + */ +public class SameFileAliasChecker implements AliasCheck +{ + private static final Logger LOG = LoggerFactory.getLogger(SameFileAliasChecker.class); + + @Override + public boolean check(String uri, Resource resource) + { + // Only support PathResource alias checking + if (!(resource instanceof PathResource)) + return false; + + try + { + PathResource pathResource = (PathResource)resource; + Path path = pathResource.getPath(); + Path alias = pathResource.getAliasPath(); + + if (Files.isSameFile(path, alias)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Allow alias to same file {} --> {}", path, alias); + return true; + } + } + catch (IOException e) + { + LOG.trace("IGNORED", e); + } + return false; + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java index 92984e26a8b..2649849d554 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -35,11 +35,11 @@ import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SniX509ExtendedKeyManager; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.X509; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      Customizer that extracts the attribute from an {@link SSLContext} @@ -48,7 +48,7 @@ import org.eclipse.jetty.util.ssl.X509; */ public class SecureRequestCustomizer implements HttpConfiguration.Customizer { - private static final Logger LOG = Log.getLogger(SecureRequestCustomizer.class); + private static final Logger LOG = LoggerFactory.getLogger(SecureRequestCustomizer.class); /** * The name of the SSLSession attribute that will contain any cached information. @@ -57,6 +57,7 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer private String sslSessionAttribute = "org.eclipse.jetty.servlet.request.ssl_session"; + private boolean _sniRequired; private boolean _sniHostCheck; private long _stsMaxAge = -1; private boolean _stsIncludeSubDomains; @@ -82,6 +83,22 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer @Name("stsMaxAgeSeconds") long stsMaxAgeSeconds, @Name("stsIncludeSubdomains") boolean stsIncludeSubdomains) { + this(false, sniHostCheck, stsMaxAgeSeconds, stsIncludeSubdomains); + } + + /** + * @param sniRequired True if a SNI certificate is required. + * @param sniHostCheck True if the SNI Host name must match. + * @param stsMaxAgeSeconds The max age in seconds for a Strict-Transport-Security response header. If set less than zero then no header is sent. + * @param stsIncludeSubdomains If true, a include subdomain property is sent with any Strict-Transport-Security header + */ + public SecureRequestCustomizer( + @Name("sniRequired") boolean sniRequired, + @Name("sniHostCheck") boolean sniHostCheck, + @Name("stsMaxAgeSeconds") long stsMaxAgeSeconds, + @Name("stsIncludeSubdomains") boolean stsIncludeSubdomains) + { + _sniRequired = sniRequired; _sniHostCheck = sniHostCheck; _stsMaxAge = stsMaxAgeSeconds; _stsIncludeSubDomains = stsIncludeSubdomains; @@ -89,7 +106,7 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer } /** - * @return True if the SNI Host name must match. + * @return True if the SNI Host name must match when there is an SNI certificate. */ public boolean isSniHostCheck() { @@ -97,13 +114,31 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer } /** - * @param sniHostCheck True if the SNI Host name must match. + * @param sniHostCheck True if the SNI Host name must match when there is an SNI certificate. */ public void setSniHostCheck(boolean sniHostCheck) { _sniHostCheck = sniHostCheck; } + /** + * @return True if SNI is required, else requests will be rejected with 400 response. + * @see SslContextFactory.Server#isSniRequired() + */ + public boolean isSniRequired() + { + return _sniRequired; + } + + /** + * @param sniRequired True if SNI is required, else requests will be rejected with 400 response. + * @see SslContextFactory.Server#setSniRequired(boolean) + */ + public void setSniRequired(boolean sniRequired) + { + _sniRequired = sniRequired; + } + /** * @return The max age in seconds for a Strict-Transport-Security response header. If set less than zero then no header is sent. */ @@ -208,19 +243,23 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer { SSLSession sslSession = sslEngine.getSession(); - if (_sniHostCheck) + if (_sniHostCheck || _sniRequired) { String name = request.getServerName(); X509 x509 = (X509)sslSession.getValue(SniX509ExtendedKeyManager.SNI_X509); - if (x509 != null && !x509.matches(name)) + if (LOG.isDebugEnabled()) + LOG.debug("Host {} with SNI {}", name, x509); + + if (x509 == null) + { + if (_sniRequired) + throw new BadMessageException(400, "SNI required"); + } + else if (_sniHostCheck && !x509.matches(name)) { - LOG.warn("Host {} does not match SNI {}", name, x509); throw new BadMessageException(400, "Host does not match SNI"); } - - if (LOG.isDebugEnabled()) - LOG.debug("Host {} matched SNI {}", name, x509); } try @@ -259,7 +298,7 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer } catch (Exception e) { - LOG.warn(Log.EXCEPTION, e); + LOG.warn("Unable to customize request with encryption details", e); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index d2ffc2f564e..d9ade6e27d4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -27,7 +27,7 @@ import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -44,7 +44,6 @@ import org.eclipse.jetty.http.PreEncodedHttpField; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.server.handler.StatisticsHandler; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.MultiException; @@ -54,13 +53,14 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.AttributeContainerMap; +import org.eclipse.jetty.util.component.Graceful; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Locker; +import org.eclipse.jetty.util.thread.AutoLock; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ShutdownThread; import org.eclipse.jetty.util.thread.ThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Jetty HTTP Servlet Server. @@ -72,20 +72,21 @@ import org.eclipse.jetty.util.thread.ThreadPool; @ManagedObject(value = "Jetty HTTP Servlet server") public class Server extends HandlerWrapper implements Attributes { - private static final Logger LOG = Log.getLogger(Server.class); + private static final Logger LOG = LoggerFactory.getLogger(Server.class); private final AttributeContainerMap _attributes = new AttributeContainerMap(); private final ThreadPool _threadPool; private final List _connectors = new CopyOnWriteArrayList<>(); private SessionIdManager _sessionIdManager; private boolean _stopAtShutdown; - private boolean _dumpAfterStart = false; - private boolean _dumpBeforeStop = false; + private boolean _dumpAfterStart; + private boolean _dumpBeforeStop; private ErrorHandler _errorHandler; private RequestLog _requestLog; - - private final Locker _dateLocker = new Locker(); + private boolean _dryRun; + private final AutoLock _dateLock = new AutoLock(); private volatile DateField _dateField; + private long _stopTimeout; public Server() { @@ -131,6 +132,16 @@ public class Server extends HandlerWrapper implements Attributes setServer(this); } + public boolean isDryRun() + { + return _dryRun; + } + + public void setDryRun(boolean dryRun) + { + _dryRun = dryRun; + } + public RequestLog getRequestLog() { return _requestLog; @@ -163,24 +174,21 @@ public class Server extends HandlerWrapper implements Attributes return Jetty.VERSION; } + public void setStopTimeout(long stopTimeout) + { + _stopTimeout = stopTimeout; + } + + public long getStopTimeout() + { + return _stopTimeout; + } + public boolean getStopAtShutdown() { return _stopAtShutdown; } - /** - * Set a graceful stop time. - * The {@link StatisticsHandler} must be configured so that open connections can - * be tracked for a graceful shutdown. - * - * @see org.eclipse.jetty.util.component.ContainerLifeCycle#setStopTimeout(long) - */ - @Override - public void setStopTimeout(long stopTimeout) - { - super.setStopTimeout(stopTimeout); - } - /** * Set stop server at shutdown behaviour. * @@ -315,7 +323,7 @@ public class Server extends HandlerWrapper implements Attributes if (df == null || df._seconds != seconds) { - try (Locker.Lock lock = _dateLocker.lock()) + try (AutoLock lock = _dateLock.lock()) { df = _dateField; if (df == null || df._seconds != seconds) @@ -367,25 +375,33 @@ public class Server extends HandlerWrapper implements Attributes MultiException mex = new MultiException(); // Open network connector to ensure ports are available - _connectors.stream().filter(NetworkConnector.class::isInstance).map(NetworkConnector.class::cast).forEach(connector -> + if (!_dryRun) { - try + _connectors.stream().filter(NetworkConnector.class::isInstance).map(NetworkConnector.class::cast).forEach(connector -> { - connector.open(); - } - catch (Throwable th) - { - mex.add(th); - } - }); - - // Throw now if verified start sequence and there was an open exception - mex.ifExceptionThrow(); + try + { + connector.open(); + } + catch (Throwable th) + { + mex.add(th); + } + }); + // Throw now if verified start sequence and there was an open exception + mex.ifExceptionThrow(); + } // Start the server and components, but not connectors! // #start(LifeCycle) is overridden so that connectors are not started super.doStart(); + if (_dryRun) + { + LOG.info(String.format("Started(dry run) %s @%dms", this, Uptime.getUptime())); + throw new StopException(); + } + // start connectors for (Connector connector : _connectors) { @@ -402,7 +418,7 @@ public class Server extends HandlerWrapper implements Attributes } mex.ifExceptionThrow(); - LOG.info(String.format("Started @%dms", Uptime.getUptime())); + LOG.info(String.format("Started %s @%dms", this, Uptime.getUptime())); } catch (Throwable th) { @@ -423,7 +439,7 @@ public class Server extends HandlerWrapper implements Attributes } finally { - if (isDumpAfterStart()) + if (isDumpAfterStart() && !(_dryRun && isDumpBeforeStop())) dumpStdErr(); } } @@ -442,26 +458,26 @@ public class Server extends HandlerWrapper implements Attributes if (isDumpBeforeStop()) dumpStdErr(); + LOG.info(String.format("Stopped %s", this)); if (LOG.isDebugEnabled()) LOG.debug("doStop {}", this); MultiException mex = new MultiException(); - try + if (getStopTimeout() > 0) { - // list if graceful futures - List> futures = new ArrayList<>(); - // First shutdown the network connectors to stop accepting new connections - for (Connector connector : _connectors) + long end = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(getStopTimeout()); + try { - futures.add(connector.shutdown()); + Graceful.shutdown(this).get(getStopTimeout(), TimeUnit.MILLISECONDS); } - // then shutdown all graceful handlers - doShutdown(futures); - } - catch (Throwable e) - { - mex.add(e); + catch (Throwable e) + { + mex.add(e); + } + QueuedThreadPool qtp = getBean(QueuedThreadPool.class); + if (qtp != null) + qtp.setStopTimeout(Math.max(1000L, TimeUnit.NANOSECONDS.toMillis(end - System.nanoTime()))); } // Now stop the connectors (this will close existing connections) @@ -514,10 +530,16 @@ public class Server extends HandlerWrapper implements Attributes if (HttpMethod.OPTIONS.is(request.getMethod()) || "*".equals(target)) { if (!HttpMethod.OPTIONS.is(request.getMethod())) + { + request.setHandled(true); response.sendError(HttpStatus.BAD_REQUEST_400); - handleOptions(request, response); - if (!request.isHandled()) - handle(target, request, request, response); + } + else + { + handleOptions(request, response); + if (!request.isHandled()) + handle(target, request, request, response); + } } else handle(target, request, request, response); @@ -558,8 +580,8 @@ public class Server extends HandlerWrapper implements Attributes } final String target = baseRequest.getPathInfo(); - final HttpServletRequest request = (HttpServletRequest)event.getSuppliedRequest(); - final HttpServletResponse response = (HttpServletResponse)event.getSuppliedResponse(); + final HttpServletRequest request = Request.unwrap(event.getSuppliedRequest()); + final HttpServletResponse response = Response.unwrap(event.getSuppliedResponse()); if (LOG.isDebugEnabled()) LOG.debug("{} {} {} on {}", request.getDispatcherType(), request.getMethod(), target, channel); @@ -590,45 +612,30 @@ public class Server extends HandlerWrapper implements Attributes _sessionIdManager = sessionIdManager; } - /* - * @see org.eclipse.util.AttributesMap#clearAttributes() - */ @Override public void clearAttributes() { _attributes.clearAttributes(); } - /* - * @see org.eclipse.util.AttributesMap#getAttribute(java.lang.String) - */ @Override public Object getAttribute(String name) { return _attributes.getAttribute(name); } - /* - * @see org.eclipse.util.AttributesMap#getAttributeNames() - */ @Override public Enumeration getAttributeNames() { return _attributes.getAttributeNames(); } - /* - * @see org.eclipse.util.AttributesMap#removeAttribute(java.lang.String) - */ @Override public void removeAttribute(String name) { _attributes.removeAttribute(name); } - /* - * @see org.eclipse.util.AttributesMap#setAttribute(java.lang.String, java.lang.Object) - */ @Override public void setAttribute(String name, Object attribute) { @@ -675,7 +682,7 @@ public class Server extends HandlerWrapper implements Attributes } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to build server URI", e); return null; } } @@ -683,7 +690,7 @@ public class Server extends HandlerWrapper implements Attributes @Override public String toString() { - return String.format("%s[%s]", super.toString(), getVersion()); + return String.format("%s[%s,sto=%d]", super.toString(), getVersion(), getStopTimeout()); } @Override diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnectionStatistics.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnectionStatistics.java index 87a436d2ce1..fa5ad25dd9d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnectionStatistics.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnectionStatistics.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java index e7aec0ea14e..5baaa6988ff 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -223,10 +223,8 @@ public class ServerConnector extends AbstractNetworkConnector @Override protected void doStart() throws Exception { - for (EventListener l : getBeans(EventListener.class)) - { + for (EventListener l : getBeans(SelectorManager.SelectorManagerListener.class)) _manager.addEventListener(l); - } super.doStart(); @@ -369,7 +367,7 @@ public class ServerConnector extends AbstractNetworkConnector } catch (IOException e) { - LOG.warn(e); + LOG.warn("Unable to close {}", serverChannel, e); } } } @@ -403,7 +401,7 @@ public class ServerConnector extends AbstractNetworkConnector } catch (SocketException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java index c9a8ef3c92c..3d6030c9620 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -35,7 +35,7 @@ import javax.servlet.http.Part; /** * ServletRequestHttpWrapper * - * Class to tunnel a ServletRequest via a HttpServletRequest + * Class to tunnel a ServletRequest via an HttpServletRequest */ public class ServletRequestHttpWrapper extends ServletRequestWrapper implements HttpServletRequest { @@ -195,54 +195,36 @@ public class ServletRequestHttpWrapper extends ServletRequestWrapper implements return false; } - /** - * @see javax.servlet.http.HttpServletRequest#authenticate(javax.servlet.http.HttpServletResponse) - */ @Override public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { return false; } - /** - * @see javax.servlet.http.HttpServletRequest#getPart(java.lang.String) - */ @Override public Part getPart(String name) throws IOException, ServletException { return null; } - /** - * @see javax.servlet.http.HttpServletRequest#getParts() - */ @Override public Collection getParts() throws IOException, ServletException { return null; } - /** - * @see javax.servlet.http.HttpServletRequest#login(java.lang.String, java.lang.String) - */ @Override public void login(String username, String password) throws ServletException { } - /** - * @see javax.servlet.http.HttpServletRequest#logout() - */ @Override public void logout() throws ServletException { } - /** - * @see javax.servlet.http.HttpServletRequest#changeSessionId() - */ @Override public String changeSessionId() { @@ -250,9 +232,6 @@ public class ServletRequestHttpWrapper extends ServletRequestWrapper implements return null; } - /** - * @see javax.servlet.http.HttpServletRequest#upgrade(java.lang.Class) - */ @Override public T upgrade(Class handlerClass) throws IOException, ServletException { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java index e35689fb072..31787ba0fbd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletResponse; /** * ServletResponseHttpWrapper * - * Wrapper to tunnel a ServletResponse via a HttpServletResponse + * Wrapper to tunnel a ServletResponse via an HttpServletResponse */ public class ServletResponseHttpWrapper extends ServletResponseWrapper implements HttpServletResponse { @@ -130,36 +130,24 @@ public class ServletResponseHttpWrapper extends ServletResponseWrapper implement { } - /** - * @see javax.servlet.http.HttpServletResponse#getHeader(java.lang.String) - */ @Override public String getHeader(String name) { return null; } - /** - * @see javax.servlet.http.HttpServletResponse#getHeaderNames() - */ @Override public Collection getHeaderNames() { return null; } - /** - * @see javax.servlet.http.HttpServletResponse#getHeaders(java.lang.String) - */ @Override public Collection getHeaders(String name) { return null; } - /** - * @see javax.servlet.http.HttpServletResponse#getStatus() - */ @Override public int getStatus() { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java index bbcd5124811..77638f235ae 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java index 881ed804429..42477dcf50f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Slf4jRequestLogWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Slf4jRequestLogWriter.java index fdc3efe7632..e5faf948df7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Slf4jRequestLogWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Slf4jRequestLogWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -23,7 +23,7 @@ import java.io.IOException; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Slf4jLog; +import org.slf4j.LoggerFactory; /** * Request log writer using a Slf4jLog Logger @@ -31,7 +31,7 @@ import org.eclipse.jetty.util.log.Slf4jLog; @ManagedObject("Slf4j RequestLog Writer") public class Slf4jRequestLogWriter extends AbstractLifeCycle implements RequestLog.Writer { - private Slf4jLog logger; + private org.slf4j.Logger logger; private String loggerName; public Slf4jRequestLogWriter() @@ -65,7 +65,7 @@ public class Slf4jRequestLogWriter extends AbstractLifeCycle implements RequestL @Override protected synchronized void doStart() throws Exception { - logger = new Slf4jLog(loggerName); + logger = LoggerFactory.getLogger(loggerName); super.doStart(); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SocketCustomizationListener.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SocketCustomizationListener.java index 63fb2e1a0d4..39f78844028 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SocketCustomizationListener.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SocketCustomizationListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java index c6a1b9441df..d51d1dcce97 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; +import java.nio.ByteBuffer; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSession; @@ -31,8 +32,12 @@ import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.ssl.SslContextFactory; -public class SslConnectionFactory extends AbstractConnectionFactory +public class SslConnectionFactory extends AbstractConnectionFactory implements ConnectionFactory.Detecting { + private static final int TLS_ALERT_FRAME_TYPE = 0x15; + private static final int TLS_HANDSHAKE_FRAME_TYPE = 0x16; + private static final int TLS_MAJOR_VERSION = 3; + private final SslContextFactory.Server _sslContextFactory; private final String _nextProtocol; private boolean _directBuffersForEncryption = false; @@ -99,6 +104,17 @@ public class SslConnectionFactory extends AbstractConnectionFactory setInputBufferSize(session.getPacketBufferSize()); } + @Override + public Detection detect(ByteBuffer buffer) + { + if (buffer.remaining() < 2) + return Detection.NEED_MORE_BYTES; + int tlsFrameType = buffer.get(0) & 0xFF; + int tlsMajorVersion = buffer.get(1) & 0xFF; + boolean seemsSsl = (tlsFrameType == TLS_HANDSHAKE_FRAME_TYPE || tlsFrameType == TLS_ALERT_FRAME_TYPE) && tlsMajorVersion == TLS_MAJOR_VERSION; + return seemsSsl ? Detection.RECOGNIZED : Detection.NOT_RECOGNIZED; + } + @Override public Connection newConnection(Connector connector, EndPoint endPoint) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java b/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java index 316919347bb..5380d33197f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/UserIdentity.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Utf8HttpWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Utf8HttpWriter.java index ba614f0ddab..937238ece1d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Utf8HttpWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Utf8HttpWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -42,16 +42,11 @@ public class Utf8HttpWriter extends HttpWriter public void write(char[] s, int offset, int length) throws IOException { HttpOutput out = _out; - if (length == 0 && out.isAllContentWritten()) - { - close(); - return; - } while (length > 0) { _bytes.reset(); - int chars = length > MAX_OUTPUT_CHARS ? MAX_OUTPUT_CHARS : length; + int chars = Math.min(length, MAX_OUTPUT_CHARS); byte[] buffer = _bytes.getBuf(); int bytes = _bytes.getCount(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java index cb2e2257eb7..7b4e440be18 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -34,8 +34,8 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractHandler. @@ -51,13 +51,10 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject("Jetty Handler") public abstract class AbstractHandler extends ContainerLifeCycle implements Handler { - private static final Logger LOG = Log.getLogger(AbstractHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractHandler.class); private Server _server; - /** - * - */ public AbstractHandler() { } @@ -66,11 +63,7 @@ public abstract class AbstractHandler extends ContainerLifeCycle implements Hand public abstract void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; /** - * Convenience method to generate error page. - *

      This method can be called from {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} when an {@link DispatcherType#ERROR} dispatch - * is detected and an error page needs to be generated by calling {@link HttpServletResponse#sendError(int, String)} with the appropriate code and reason, - * which are taken from {@link HttpServletRequest#getAttribute(String)} for {@link RequestDispatcher#ERROR_STATUS_CODE} and {@link RequestDispatcher#ERROR_MESSAGE} - * + * Deprecated error page generation * @param target The target of the request - either a URI or a name. * @param baseRequest The original unwrapped request object. * @param request The request either as the {@link Request} object or a wrapper of that request. The @@ -81,21 +74,16 @@ public abstract class AbstractHandler extends ContainerLifeCycle implements Hand * method can be used access the Response object if required. * @throws IOException if unable to handle the request or response processing * @throws ServletException if unable to handle the request or response due to underlying servlet issue - * @see ErrorDispatchHandler for a convenience class that calls this method. */ + @Deprecated protected void doError(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { Object o = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); int code = (o instanceof Integer) ? ((Integer)o).intValue() : (o != null ? Integer.parseInt(o.toString()) : 500); - o = request.getAttribute(RequestDispatcher.ERROR_MESSAGE); - String reason = o != null ? o.toString() : null; - - response.sendError(code, reason); + response.setStatus(code); + baseRequest.setHandled(true); } - /* - * @see org.eclipse.thread.LifeCycle#start() - */ @Override protected void doStart() throws Exception { @@ -106,9 +94,6 @@ public abstract class AbstractHandler extends ContainerLifeCycle implements Hand super.doStart(); } - /* - * @see org.eclipse.thread.LifeCycle#stop() - */ @Override protected void doStop() throws Exception { @@ -123,7 +108,7 @@ public abstract class AbstractHandler extends ContainerLifeCycle implements Hand if (_server == server) return; if (isStarted()) - throw new IllegalStateException(STARTED); + throw new IllegalStateException(getState()); _server = server; } @@ -147,7 +132,9 @@ public abstract class AbstractHandler extends ContainerLifeCycle implements Hand * {@link DispatcherType#ERROR} dispatches are handled by calling the {@link #doError(String, Request, HttpServletRequest, HttpServletResponse)} * method. All other dispatches are passed to the abstract {@link #doNonErrorHandle(String, Request, HttpServletRequest, HttpServletResponse)} * method, which should be implemented with specific handler behavior + * @deprecated This class is no longer required as ERROR dispatch is only done if there is an error page target. */ + @Deprecated public abstract static class ErrorDispatchHandler extends AbstractHandler { @Override @@ -174,6 +161,7 @@ public abstract class AbstractHandler extends ContainerLifeCycle implements Hand * @throws IOException if unable to handle the request or response processing * @throws ServletException if unable to handle the request or response due to underlying servlet issue */ + @Deprecated protected abstract void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java index e56645f5dcf..474f6107240 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java @@ -1,38 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.List; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HandlerContainer; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.MultiException; -import org.eclipse.jetty.util.component.Graceful; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Abstract Handler Container. @@ -40,7 +34,7 @@ import org.eclipse.jetty.util.log.Logger; */ public abstract class AbstractHandlerContainer extends AbstractHandler implements HandlerContainer { - private static final Logger LOG = Log.getLogger(AbstractHandlerContainer.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractHandlerContainer.class); public AbstractHandlerContainer() { @@ -128,7 +122,7 @@ public abstract class AbstractHandlerContainer extends AbstractHandler implement return; if (isStarted()) - throw new IllegalStateException(STARTED); + throw new IllegalStateException(getState()); super.setServer(server); Handler[] handlers = getHandlers(); @@ -138,62 +132,4 @@ public abstract class AbstractHandlerContainer extends AbstractHandler implement h.setServer(server); } } - - /** - * Shutdown nested Gracefule handlers - * - * @param futures A list of Futures which must also be waited on for the shutdown (or null) - * returns A MultiException to which any failures are added or null - */ - protected void doShutdown(List> futures) throws MultiException - { - MultiException mex = null; - - // tell the graceful handlers that we are shutting down - Handler[] gracefuls = getChildHandlersByClass(Graceful.class); - if (futures == null) - futures = new ArrayList<>(gracefuls.length); - for (Handler graceful : gracefuls) - { - futures.add(((Graceful)graceful).shutdown()); - } - - // Wait for all futures with a reducing time budget - long stopTimeout = getStopTimeout(); - if (stopTimeout > 0) - { - long stopBy = System.currentTimeMillis() + stopTimeout; - if (LOG.isDebugEnabled()) - LOG.debug("Graceful shutdown {} by ", this, new Date(stopBy)); - - // Wait for shutdowns - for (Future future : futures) - { - try - { - if (!future.isDone()) - future.get(Math.max(1L, stopBy - System.currentTimeMillis()), TimeUnit.MILLISECONDS); - } - catch (Exception e) - { - // If the future is also a callback, fail it here (rather than cancel) so we can capture the exception - if (future instanceof Callback && !future.isDone()) - ((Callback)future).failed(e); - if (mex == null) - mex = new MultiException(); - mex.add(e); - } - } - } - - // Cancel any shutdowns not done - for (Future future : futures) - { - if (!future.isDone()) - future.cancel(true); - } - - if (mex != null) - mex.ifExceptionThrowMulti(); - } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java index c6186885d9a..6ed9fc44835 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -22,10 +22,10 @@ import java.nio.file.Files; import java.nio.file.Path; import org.eclipse.jetty.server.handler.ContextHandler.AliasCheck; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Symbolic Link AliasChecker. @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.resource.Resource; */ public class AllowSymLinkAliasChecker implements AliasCheck { - private static final Logger LOG = Log.getLogger(AllowSymLinkAliasChecker.class); + private static final Logger LOG = LoggerFactory.getLogger(AllowSymLinkAliasChecker.class); @Override public boolean check(String uri, Resource resource) @@ -52,7 +52,7 @@ public class AllowSymLinkAliasChecker implements AliasCheck Path path = pathResource.getPath(); Path alias = pathResource.getAliasPath(); - if (path.equals(alias)) + if (PathResource.isSameName(alias, path)) return false; // Unknown why this is an alias if (hasSymbolicLink(path) && Files.isSameFile(path, alias)) @@ -64,7 +64,7 @@ public class AllowSymLinkAliasChecker implements AliasCheck } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return false; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java index f4db580b117..5107ef59b5b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -52,6 +52,7 @@ public class AsyncDelayHandler extends HandlerWrapper Object asyncQueryString = null; Object asyncRequestUri = null; Object asyncServletPath = null; + Object asyncHttpServletMapping = null; // Is this request a restarted one? boolean restart = false; @@ -72,6 +73,8 @@ public class AsyncDelayHandler extends HandlerWrapper baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI, null); asyncServletPath = baseRequest.getAttribute(AsyncContext.ASYNC_SERVLET_PATH); baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, null); + asyncHttpServletMapping = baseRequest.getAttribute(AsyncContext.ASYNC_MAPPING); + baseRequest.setAttribute(AsyncContext.ASYNC_MAPPING, null); } // Should we handle this request now? @@ -101,6 +104,7 @@ public class AsyncDelayHandler extends HandlerWrapper baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING, asyncQueryString); baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI, asyncRequestUri); baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, asyncServletPath); + baseRequest.setAttribute(AsyncContext.ASYNC_MAPPING, asyncHttpServletMapping); } // signal the request is leaving the handler diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/BufferedResponseHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/BufferedResponseHandler.java index bbb24c536b0..c7b839ee995 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/BufferedResponseHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/BufferedResponseHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -41,8 +41,8 @@ import org.eclipse.jetty.util.IncludeExclude; import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Buffered Response Handler @@ -63,7 +63,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class BufferedResponseHandler extends HandlerWrapper { - static final Logger LOG = Log.getLogger(BufferedResponseHandler.class); + static final Logger LOG = LoggerFactory.getLogger(BufferedResponseHandler.class); private final IncludeExclude _methods = new IncludeExclude<>(); private final IncludeExclude _paths = new IncludeExclude<>(PathSpecSet.class); @@ -100,9 +100,6 @@ public class BufferedResponseHandler extends HandlerWrapper return _mimeTypes; } - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -271,12 +268,6 @@ public class BufferedResponseHandler extends HandlerWrapper return _next; } - @Override - public boolean isOptimizedForDirectBuffers() - { - return false; - } - protected void commit(Queue buffers, Callback callback) { // If only 1 buffer diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 1e1bb82c6ee..26b955a89d3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -39,8 +39,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Future; import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterRegistration; @@ -77,7 +77,6 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; -import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.StringUtil; @@ -86,9 +85,9 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.DumpableCollection; import org.eclipse.jetty.util.component.Graceful; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ContextHandler. @@ -110,32 +109,38 @@ import org.eclipse.jetty.util.resource.Resource; @ManagedObject("URI Context") public class ContextHandler extends ScopedHandler implements Attributes, Graceful { - public static final int SERVLET_MAJOR_VERSION = 3; - public static final int SERVLET_MINOR_VERSION = 1; + public static final int SERVLET_MAJOR_VERSION = 4; + public static final int SERVLET_MINOR_VERSION = 0; public static final Class[] SERVLET_LISTENER_TYPES = - { - ServletContextListener.class, - ServletContextAttributeListener.class, - ServletRequestListener.class, - ServletRequestAttributeListener.class, - HttpSessionIdListener.class, - HttpSessionListener.class, - HttpSessionAttributeListener.class - }; + { + ServletContextListener.class, + ServletContextAttributeListener.class, + ServletRequestListener.class, + ServletRequestAttributeListener.class, + HttpSessionIdListener.class, + HttpSessionListener.class, + HttpSessionAttributeListener.class + }; public static final int DEFAULT_LISTENER_TYPE_INDEX = 1; + public static final int EXTENDED_LISTENER_TYPE_INDEX = 0; - private static final String __unimplmented = "Unimplemented - use org.eclipse.jetty.servlet.ServletContextHandler"; + private static final String UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER = "Unimplemented {} - use org.eclipse.jetty.servlet.ServletContextHandler"; - private static final Logger LOG = Log.getLogger(ContextHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(ContextHandler.class); - private static final ThreadLocal __context = new ThreadLocal(); + private static final ThreadLocal __context = new ThreadLocal<>(); private static String __serverInfo = "jetty/" + Server.getVersion(); public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes"; + public static final String MAX_FORM_KEYS_KEY = "org.eclipse.jetty.server.Request.maxFormKeys"; + public static final String MAX_FORM_CONTENT_SIZE_KEY = "org.eclipse.jetty.server.Request.maxFormContentSize"; + public static final int DEFAULT_MAX_FORM_KEYS = 1000; + public static final int DEFAULT_MAX_FORM_CONTENT_SIZE = 200000; + /** * Get the current ServletContext implementation. * @@ -171,39 +176,37 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu private final Map _initParams; private ClassLoader _classLoader; private boolean _contextPathDefault = true; + private String _defaultRequestCharacterEncoding; + private String _defaultResponseCharacterEncoding; private String _contextPath = "/"; private String _contextPathEncoded = "/"; - private String _displayName; - + private long _stopTimeout; private Resource _baseResource; private MimeTypes _mimeTypes; private Map _localeEncodingMap; private String[] _welcomeFiles; private ErrorHandler _errorHandler; - private String[] _vhosts; // Host name portion, matching _vconnectors array private boolean[] _vhostswildcard; private String[] _vconnectors; // connector portion, matching _vhosts array - private Logger _logger; private boolean _allowNullPathInfo; - private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys", -1).intValue(); - private int _maxFormContentSize = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormContentSize", -1).intValue(); + private int _maxFormKeys = Integer.getInteger(MAX_FORM_KEYS_KEY, DEFAULT_MAX_FORM_KEYS); + private int _maxFormContentSize = Integer.getInteger(MAX_FORM_CONTENT_SIZE_KEY, DEFAULT_MAX_FORM_CONTENT_SIZE); private boolean _compactPath = false; private boolean _usingSecurityManager = System.getSecurityManager() != null; - private final List _eventListeners = new CopyOnWriteArrayList<>(); private final List _programmaticListeners = new CopyOnWriteArrayList<>(); private final List _servletContextListeners = new CopyOnWriteArrayList<>(); - private final List _destroySerletContextListeners = new ArrayList<>(); + private final List _destroyServletContextListeners = new ArrayList<>(); private final List _servletContextAttributeListeners = new CopyOnWriteArrayList<>(); private final List _servletRequestListeners = new CopyOnWriteArrayList<>(); private final List _servletRequestAttributeListeners = new CopyOnWriteArrayList<>(); private final List _contextListeners = new CopyOnWriteArrayList<>(); - private final List _durableListeners = new CopyOnWriteArrayList<>(); + private final Set _durableListeners = new HashSet<>(); private String[] _protectedTargets; - private final CopyOnWriteArrayList _aliasChecks = new CopyOnWriteArrayList(); + private final CopyOnWriteArrayList _aliasChecks = new CopyOnWriteArrayList<>(); public enum Availability { @@ -237,7 +240,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu { _scontext = context == null ? new Context() : context; _attributes = new AttributesMap(); - _initParams = new HashMap(); + _initParams = new HashMap<>(); addAliasCheck(new ApproveNonExistentDirectoryAliases()); if (File.separatorChar == '/') addAliasCheck(new AllowSymLinkAliasChecker()); @@ -255,7 +258,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu { dumpObjects(out, indent, new ClassLoaderDump(getClassLoader()), - new DumpableCollection("eventListeners " + this, _eventListeners), new DumpableCollection("handler attributes " + this, ((AttributesMap)getAttributes()).getAttributeEntrySet()), new DumpableCollection("context attributes " + this, ((Context)getServletContext()).getAttributeEntrySet()), new DumpableCollection("initparams " + this, getInitParams().entrySet())); @@ -347,7 +349,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (connectorIndex == 0) { if (connectorOnlyIndexes == null) - connectorOnlyIndexes = new ArrayList(); + connectorOnlyIndexes = new ArrayList<>(); connectorOnlyIndexes.add(i); } } @@ -405,7 +407,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } else { - Set currentVirtualHosts = new HashSet(Arrays.asList(getVirtualHosts())); + Set currentVirtualHosts = new HashSet<>(Arrays.asList(getVirtualHosts())); for (String vh : virtualHosts) { currentVirtualHosts.add(normalizeHostname(vh)); @@ -430,7 +432,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (virtualHosts == null || virtualHosts.length == 0 || _vhosts == null || _vhosts.length == 0) return; // do nothing - Set existingVirtualHosts = new HashSet(Arrays.asList(getVirtualHosts())); + Set existingVirtualHosts = new HashSet<>(Arrays.asList(getVirtualHosts())); for (String vh : virtualHosts) { existingVirtualHosts.remove(normalizeHostname(vh)); @@ -475,18 +477,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return vhosts; } - /* - * @see javax.servlet.ServletContext#getAttribute(java.lang.String) - */ @Override public Object getAttribute(String name) { return _attributes.getAttribute(name); } - /* - * @see javax.servlet.ServletContext#getAttributeNames() - */ @Override public Enumeration getAttributeNames() { @@ -524,9 +520,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu StringBuilder classpath = new StringBuilder(); for (int i = 0; i < urls.length; i++) { + URL url = urls[i]; try { - Resource resource = newResource(urls[i]); + Resource resource = newResource(url); File file = resource.getFile(); if (file != null && file.exists()) { @@ -537,7 +534,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (IOException e) { - LOG.debug(e); + LOG.debug("Could not found resource: {}", url, e); } } if (classpath.length() == 0) @@ -601,101 +598,71 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return _displayName; } - public EventListener[] getEventListeners() - { - return _eventListeners.toArray(new EventListener[_eventListeners.size()]); - } - - /** - * Set the context event listeners. - * - * @param eventListeners the event listeners - * @see ServletContextListener - * @see ServletContextAttributeListener - * @see ServletRequestListener - * @see ServletRequestAttributeListener - */ - public void setEventListeners(EventListener[] eventListeners) - { - _contextListeners.clear(); - _servletContextListeners.clear(); - _servletContextAttributeListeners.clear(); - _servletRequestListeners.clear(); - _servletRequestAttributeListeners.clear(); - _eventListeners.clear(); - - if (eventListeners != null) - for (EventListener listener : eventListeners) - { - addEventListener(listener); - } - } - /** * Add a context event listeners. * * @param listener the event listener to add + * @return true if the listener was added + * @see ContextScopeListener * @see ServletContextListener * @see ServletContextAttributeListener * @see ServletRequestListener * @see ServletRequestAttributeListener */ - public void addEventListener(EventListener listener) + @Override + public boolean addEventListener(EventListener listener) { - _eventListeners.add(listener); - - if (!(isStarted() || isStarting())) + if (super.addEventListener(listener)) { - _durableListeners.add(listener); + if (listener instanceof ContextScopeListener) + { + _contextListeners.add((ContextScopeListener)listener); + if (__context.get() != null) + ((ContextScopeListener)listener).enterScope(__context.get(), null, "Listener registered"); + } + + if (listener instanceof ServletContextListener) + _servletContextListeners.add((ServletContextListener)listener); + + if (listener instanceof ServletContextAttributeListener) + _servletContextAttributeListeners.add((ServletContextAttributeListener)listener); + + if (listener instanceof ServletRequestListener) + _servletRequestListeners.add((ServletRequestListener)listener); + + if (listener instanceof ServletRequestAttributeListener) + _servletRequestAttributeListeners.add((ServletRequestAttributeListener)listener); + + return true; } - - if (listener instanceof ContextScopeListener) - { - _contextListeners.add((ContextScopeListener)listener); - if (__context.get() != null) - ((ContextScopeListener)listener).enterScope(__context.get(), null, "Listener registered"); - } - - if (listener instanceof ServletContextListener) - _servletContextListeners.add((ServletContextListener)listener); - - if (listener instanceof ServletContextAttributeListener) - _servletContextAttributeListeners.add((ServletContextAttributeListener)listener); - - if (listener instanceof ServletRequestListener) - _servletRequestListeners.add((ServletRequestListener)listener); - - if (listener instanceof ServletRequestAttributeListener) - _servletRequestAttributeListeners.add((ServletRequestAttributeListener)listener); + return false; } - /** - * Remove a context event listeners. - * - * @param listener the event listener to remove - * @see ServletContextListener - * @see ServletContextAttributeListener - * @see ServletRequestListener - * @see ServletRequestAttributeListener - */ - public void removeEventListener(EventListener listener) + @Override + public boolean removeEventListener(EventListener listener) { - _eventListeners.remove(listener); + if (super.removeEventListener(listener)) + { + if (listener instanceof ContextScopeListener) + _contextListeners.remove(listener); - if (listener instanceof ContextScopeListener) - _contextListeners.remove(listener); + if (listener instanceof ServletContextListener) + { + _servletContextListeners.remove(listener); + _destroyServletContextListeners.remove(listener); + } - if (listener instanceof ServletContextListener) - _servletContextListeners.remove(listener); + if (listener instanceof ServletContextAttributeListener) + _servletContextAttributeListeners.remove(listener); - if (listener instanceof ServletContextAttributeListener) - _servletContextAttributeListeners.remove(listener); + if (listener instanceof ServletRequestListener) + _servletRequestListeners.remove(listener); - if (listener instanceof ServletRequestListener) - _servletRequestListeners.remove(listener); - - if (listener instanceof ServletRequestAttributeListener) - _servletRequestAttributeListeners.remove(listener); + if (listener instanceof ServletRequestAttributeListener) + _servletRequestAttributeListeners.remove(listener); + return true; + } + return false; } /** @@ -712,10 +679,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu { return _programmaticListeners.contains(listener); } - + public boolean isDurableListener(EventListener listener) { - return _durableListeners.contains(listener); + // The durable listeners are those set when the context is started + if (isStarted()) + return _durableListeners.contains(listener); + // If we are not yet started then all set listeners are durable + return getEventListeners().contains(listener); } /** @@ -732,10 +703,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu * requests can complete, but no new requests are accepted. */ @Override - public Future shutdown() + public CompletableFuture shutdown() { _availability = isRunning() ? Availability.SHUTDOWN : Availability.UNAVAILABLE; - return new FutureCallback(true); + CompletableFuture shutdown = new CompletableFuture(); + shutdown.complete(null); + return shutdown; } /** @@ -772,9 +745,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu _logger = logger; } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -784,9 +754,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu throw new IllegalStateException("Null contextPath"); if (_logger == null) - { - _logger = Log.getLogger(ContextHandler.class.getName() + getLogNameSuffix()); - } + _logger = LoggerFactory.getLogger(ContextHandler.class.getName() + getLogNameSuffix()); ClassLoader oldClassloader = null; Thread currentThread = null; @@ -797,6 +765,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (_mimeTypes == null) _mimeTypes = new MimeTypes(); + _durableListeners.addAll(getEventListeners()); + try { // Set the classloader, context and enter scope @@ -861,7 +831,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu * insert additional handling (Eg configuration) before the call to super.doStart by this method will start contained handlers. * * @throws Exception if unable to start the context - * @see org.eclipse.jetty.server.handler.ContextHandler.Context + * @see ContextHandler.Context */ protected void startContext() throws Exception { @@ -872,28 +842,25 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu super.doStart(); // Call context listeners - _destroySerletContextListeners.clear(); + _destroyServletContextListeners.clear(); if (!_servletContextListeners.isEmpty()) { ServletContextEvent event = new ServletContextEvent(_scontext); for (ServletContextListener listener : _servletContextListeners) { callContextInitialized(listener, event); - _destroySerletContextListeners.add(listener); + _destroyServletContextListeners.add(listener); } } } protected void stopContext() throws Exception { - // stop all the handler hierarchy - super.doStop(); - // Call the context listeners ServletContextEvent event = new ServletContextEvent(_scontext); - Collections.reverse(_destroySerletContextListeners); + Collections.reverse(_destroyServletContextListeners); MultiException ex = new MultiException(); - for (ServletContextListener listener : _destroySerletContextListeners) + for (ServletContextListener listener : _destroyServletContextListeners) { try { @@ -904,6 +871,17 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu ex.add(x); } } + + // stop all the handler hierarchy + try + { + super.doStop(); + } + catch (Exception x) + { + ex.add(x); + } + ex.ifExceptionThrow(); } @@ -921,27 +899,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu l.contextDestroyed(e); } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { // Should we attempt a graceful shutdown? MultiException mex = null; - if (getStopTimeout() > 0) - { - try - { - doShutdown(null); - } - catch (MultiException e) - { - mex = e; - } - } - _availability = Availability.UNAVAILABLE; ClassLoader oldClassloader = null; @@ -964,7 +927,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu stopContext(); // retain only durable listeners - setEventListeners(_durableListeners.toArray(new EventListener[_durableListeners.size()])); + setEventListeners(_durableListeners); _durableListeners.clear(); if (_errorHandler != null) @@ -981,7 +944,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Unable to exit scope", e); } } } @@ -1100,7 +1063,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu case UNAVAILABLE: baseRequest.setHandled(true); response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); - return true; + return false; default: if ((DispatcherType.REQUEST.equals(dispatch) && baseRequest.isHandled())) return false; @@ -1109,17 +1072,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return true; } - /** - * @see org.eclipse.jetty.server.handler.ScopedHandler#doScope(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ @Override public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (LOG.isDebugEnabled()) LOG.debug("scope {}|{}|{} @ {}", baseRequest.getContextPath(), baseRequest.getServletPath(), baseRequest.getPathInfo(), this); - Context oldContext = null; + Context oldContext; String oldContextPath = null; String oldServletPath = null; String oldPathInfo = null; @@ -1135,10 +1094,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (oldContext != _scontext) { // check the target. - if (DispatcherType.REQUEST.equals(dispatch) || DispatcherType.ASYNC.equals(dispatch) || - DispatcherType.ERROR.equals(dispatch) && baseRequest.getHttpChannelState().isAsync()) + if (DispatcherType.REQUEST.equals(dispatch) || DispatcherType.ASYNC.equals(dispatch)) { - if (_compactPath) + if (isCompactPath()) target = URIUtil.compactPath(target); if (!checkContext(target, baseRequest, response)) return; @@ -1184,7 +1142,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (_contextPath.length() == 1) baseRequest.setContextPath(""); else - baseRequest.setContextPath(_contextPathEncoded); + baseRequest.setContextPath(getContextPathEncoded()); baseRequest.setServletPath(null); baseRequest.setPathInfo(pathInfo); } @@ -1259,10 +1217,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } } - /** - * @see org.eclipse.jetty.server.handler.ScopedHandler#doHandle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ @Override public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -1273,29 +1227,11 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (new_context) requestInitialized(baseRequest, request); - switch (dispatch) + if (dispatch == DispatcherType.REQUEST && isProtectedTarget(target)) { - case REQUEST: - if (isProtectedTarget(target)) - { - response.sendError(HttpServletResponse.SC_NOT_FOUND); - baseRequest.setHandled(true); - return; - } - break; - - case ERROR: - // If this is already a dispatch to an error page, proceed normally - if (Boolean.TRUE.equals(baseRequest.getAttribute(Dispatcher.__ERROR_DISPATCH))) - break; - - // We can just call doError here. If there is no error page, then one will - // be generated. If there is an error page, then a RequestDispatcher will be - // used to route the request through appropriate filters etc. - doError(target, baseRequest, request, response); - return; - default: - break; + baseRequest.setHandled(true); + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; } nextHandle(target, baseRequest, request, response); @@ -1323,7 +1259,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Unable to enter scope", e); } } } @@ -1344,7 +1280,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Unable to exit scope", e); } } } @@ -1462,9 +1398,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return Arrays.copyOf(_protectedTargets, _protectedTargets.length); } - /* - * @see javax.servlet.ServletContext#removeAttribute(java.lang.String) - */ @Override public void removeAttribute(String name) { @@ -1519,6 +1452,26 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu _contextPathDefault = true; } + public void setDefaultRequestCharacterEncoding(String encoding) + { + _defaultRequestCharacterEncoding = encoding; + } + + public String getDefaultRequestCharacterEncoding() + { + return _defaultRequestCharacterEncoding; + } + + public void setDefaultResponseCharacterEncoding(String encoding) + { + _defaultResponseCharacterEncoding = encoding; + } + + public String getDefaultResponseCharacterEncoding() + { + return _defaultResponseCharacterEncoding; + } + /** * @return True if the current contextPath is from default settings */ @@ -1625,7 +1578,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu catch (Exception e) { LOG.warn(e.toString()); - LOG.debug(e); + LOG.debug("Unable to set baseResource: {}", resourceBase, e); throw new IllegalArgumentException(resourceBase); } } @@ -1778,7 +1731,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu public void addLocaleEncoding(String locale, String encoding) { if (_localeEncodingMap == null) - _localeEncodingMap = new HashMap(); + _localeEncodingMap = new HashMap<>(); _localeEncodingMap.put(locale, encoding); } @@ -1838,7 +1791,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return null; @@ -1858,7 +1811,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu LOG.debug("Aliased resource: " + resource + "~=" + resource.getAlias()); // alias checks - for (Iterator i = _aliasChecks.iterator(); i.hasNext(); ) + for (Iterator i = getAliasChecks().iterator(); i.hasNext(); ) { AliasCheck check = i.next(); if (check.check(path, resource)) @@ -1924,7 +1877,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu String[] l = resource.list(); if (l != null) { - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); for (int i = 0; i < l.length; i++) { set.add(path + l[i]); @@ -1935,7 +1888,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return Collections.emptySet(); } @@ -1967,7 +1920,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu */ public void addAliasCheck(AliasCheck check) { - _aliasChecks.add(check); + getAliasChecks().add(check); } /** @@ -1983,8 +1936,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu */ public void setAliasChecks(List checks) { - _aliasChecks.clear(); - _aliasChecks.addAll(checks); + getAliasChecks().clear(); + getAliasChecks().addAll(checks); } /** @@ -1992,13 +1945,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu */ public void clearAliasChecks() { - _aliasChecks.clear(); + getAliasChecks().clear(); } /** * Context. *

      - * A partial implementation of {@link javax.servlet.ServletContext}. A complete implementation is provided by the derived {@link ContextHandler}. + * A partial implementation of {@link javax.servlet.ServletContext}. A complete implementation is provided by the + * derived {@link ContextHandler} implementations. *

      */ public class Context extends StaticContext @@ -2015,13 +1969,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return ContextHandler.this; } - /* - * @see javax.servlet.ServletContext#getContext(java.lang.String) - */ @Override public ServletContext getContext(String uripath) { - List contexts = new ArrayList(); + List contexts = new ArrayList<>(); Handler[] handlers = getServer().getChildHandlersByClass(ContextHandler.class); String matchedPath = null; @@ -2094,7 +2045,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu matchedPath = contextPath; } - if (matchedPath != null && matchedPath.equals(contextPath)) + if (matchedPath.equals(contextPath)) contexts.add(ch); } } @@ -2104,9 +2055,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return null; } - /* - * @see javax.servlet.ServletContext#getMimeType(java.lang.String) - */ @Override public String getMimeType(String file) { @@ -2115,9 +2063,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return _mimeTypes.getMimeByExtension(file); } - /* - * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String) - */ @Override public RequestDispatcher getRequestDispatcher(String uriInContext) { @@ -2145,14 +2090,11 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return null; } - /* - * @see javax.servlet.ServletContext#getRealPath(java.lang.String) - */ @Override public String getRealPath(String path) { @@ -2175,7 +2117,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } return null; @@ -2190,9 +2132,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return null; } - /* - * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String) - */ @Override public InputStream getResourceAsStream(String path) { @@ -2209,68 +2148,50 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return null; } } - /* - * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String) - */ @Override public Set getResourcePaths(String path) { return ContextHandler.this.getResourcePaths(path); } - /* - * @see javax.servlet.ServletContext#log(java.lang.Exception, java.lang.String) - */ @Override public void log(Exception exception, String msg) { _logger.warn(msg, exception); } - /* - * @see javax.servlet.ServletContext#log(java.lang.String) - */ @Override public void log(String msg) { _logger.info(msg); } - /* - * @see javax.servlet.ServletContext#log(java.lang.String, java.lang.Throwable) - */ @Override public void log(String message, Throwable throwable) { - _logger.warn(message, throwable); + if (throwable == null) + _logger.warn(message); + else + _logger.warn(message, throwable); } - /* - * @see javax.servlet.ServletContext#getInitParameter(java.lang.String) - */ @Override public String getInitParameter(String name) { return ContextHandler.this.getInitParameter(name); } - /* - * @see javax.servlet.ServletContext#getInitParameterNames() - */ @Override public Enumeration getInitParameterNames() { return ContextHandler.this.getInitParameterNames(); } - /* - * @see javax.servlet.ServletContext#getAttribute(java.lang.String) - */ @Override public synchronized Object getAttribute(String name) { @@ -2280,13 +2201,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return o; } - /* - * @see javax.servlet.ServletContext#getAttributeNames() - */ @Override public synchronized Enumeration getAttributeNames() { - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); Enumeration e = super.getAttributeNames(); while (e.hasMoreElements()) { @@ -2301,9 +2219,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return Collections.enumeration(set); } - /* - * @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object) - */ @Override public synchronized void setAttribute(String name, Object value) { @@ -2330,9 +2245,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } } - /* - * @see javax.servlet.ServletContext#removeAttribute(java.lang.String) - */ @Override public synchronized void removeAttribute(String name) { @@ -2349,9 +2261,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } } - /* - * @see javax.servlet.ServletContext#getServletContextName() - */ @Override public String getServletContextName() { @@ -2433,19 +2342,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } } - @Override - public T createListener(Class clazz) throws ServletException - { - try - { - return createInstance(clazz); - } - catch (Exception e) - { - throw new ServletException(e); - } - } - public void checkListener(Class listener) throws IllegalStateException { boolean ok = false; @@ -2479,7 +2375,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu throw new UnsupportedOperationException(); // no security manager just return the classloader - if (!_usingSecurityManager) + if (!isUsingSecurityManager()) { return _classLoader; } @@ -2507,7 +2403,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu @Override public JspConfigDescriptor getJspConfigDescriptor() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getJspConfigDescriptor()"); return null; } @@ -2535,12 +2431,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return _enabled; } - public T createInstance(Class clazz) throws Exception - { - T o = clazz.getDeclaredConstructor().newInstance(); - return o; - } - @Override public String getVirtualServerName() { @@ -2551,15 +2441,16 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } } + /** + * A simple implementation of ServletContext that is used when there is no + * ContextHandler. This is also used as the base for all other ServletContext + * implementations. + */ public static class StaticContext extends AttributesMap implements ServletContext { private int _effectiveMajorVersion = SERVLET_MAJOR_VERSION; private int _effectiveMinorVersion = SERVLET_MINOR_VERSION; - public StaticContext() - { - } - @Override public ServletContext getContext(String uripath) { @@ -2623,7 +2514,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu @Override public String getServerInfo() { - return __serverInfo; + return ContextHandler.getServerInfo(); } @Override @@ -2700,142 +2591,129 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu @Override public Dynamic addFilter(String filterName, Class filterClass) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addFilter(String, Class)"); return null; } @Override public Dynamic addFilter(String filterName, Filter filter) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addFilter(String, Filter)"); return null; } @Override public Dynamic addFilter(String filterName, String className) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addFilter(String, String)"); return null; } @Override public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, Class servletClass) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addServlet(String, Class)"); return null; } @Override public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addServlet(String, Servlet)"); return null; } @Override public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, String className) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addServlet(String, String)"); return null; } + /** + * @since Servlet 4.0 + */ @Override public ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) { - // TODO new in 4.0 - LOG.warn(__unimplmented); - return null; - } - - @Override - public T createFilter(Class c) throws ServletException - { - LOG.warn(__unimplmented); - return null; - } - - @Override - public T createServlet(Class c) throws ServletException - { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addJspFile(String, String)"); return null; } @Override public Set getDefaultSessionTrackingModes() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getDefaultSessionTrackingModes()"); return null; } @Override public Set getEffectiveSessionTrackingModes() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getEffectiveSessionTrackingModes()"); return null; } @Override public FilterRegistration getFilterRegistration(String filterName) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getFilterRegistration(String)"); return null; } @Override public Map getFilterRegistrations() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getFilterRegistrations()"); return null; } @Override public ServletRegistration getServletRegistration(String servletName) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getServletRegistration(String)"); return null; } @Override public Map getServletRegistrations() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getServletRegistrations()"); return null; } @Override public SessionCookieConfig getSessionCookieConfig() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getSessionCookieConfig()"); return null; } @Override public void setSessionTrackingModes(Set sessionTrackingModes) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setSessionTrackingModes(Set)"); } @Override public void addListener(String className) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(String)"); } @Override public void addListener(T t) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(T)"); } @Override public void addListener(Class listenerClass) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(Class)"); } - @Override - public T createListener(Class clazz) throws ServletException + public T createInstance(Class clazz) throws ServletException { try { @@ -2847,6 +2725,24 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } } + @Override + public T createListener(Class clazz) throws ServletException + { + return createInstance(clazz); + } + + @Override + public T createServlet(Class clazz) throws ServletException + { + return createInstance(clazz); + } + + @Override + public T createFilter(Class clazz) throws ServletException + { + return createInstance(clazz); + } + @Override public ClassLoader getClassLoader() { @@ -2878,14 +2774,14 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu @Override public JspConfigDescriptor getJspConfigDescriptor() { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getJspConfigDescriptor()"); return null; } @Override public void declareRoles(String... roleNames) { - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "declareRoles(String...)"); } @Override @@ -2894,49 +2790,61 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return null; } + /** + * @since Servlet 4.0 + */ @Override public int getSessionTimeout() { - // TODO new in 4.0 - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getSessionTimeout()"); return 0; } + /** + * @since Servlet 4.0 + */ @Override public void setSessionTimeout(int sessionTimeout) { - // TODO new in 4.0 - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setSessionTimeout(int)"); } + /** + * @since Servlet 4.0 + */ @Override public String getRequestCharacterEncoding() { - // TODO new in 4.0 - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getRequestCharacterEncoding()"); return null; } + /** + * @since Servlet 4.0 + */ @Override public void setRequestCharacterEncoding(String encoding) { - // TODO new in 4.0 - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setRequestCharacterEncoding(String)"); } + /** + * @since Servlet 4.0 + */ @Override public String getResponseCharacterEncoding() { - // TODO new in 4.0 - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "getResponseCharacterEncoding()"); return null; } + /** + * @since Servlet 4.0 + */ @Override public void setResponseCharacterEncoding(String encoding) { - // TODO new in 4.0 - LOG.warn(__unimplmented); + LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "setResponseCharacterEncoding(String)"); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index b37c2dbf2c7..a7e72064c5d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -38,9 +38,9 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Trie; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.SerializedExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a @@ -53,7 +53,7 @@ import org.eclipse.jetty.util.thread.SerializedExecutor; @ManagedObject("Context Handler Collection") public class ContextHandlerCollection extends HandlerCollection { - private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class); + private static final Logger LOG = LoggerFactory.getLogger(ContextHandlerCollection.class); private final SerializedExecutor _serializedExecutor = new SerializedExecutor(); public ContextHandlerCollection() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java index f825b81dfd7..0690f20b628 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -47,9 +47,6 @@ public class DebugHandler extends HandlerWrapper implements Connection.Listener private OutputStream _out; private PrintStream _print; - /* - * @see org.eclipse.jetty.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException @@ -120,9 +117,6 @@ public class DebugHandler extends HandlerWrapper implements Connection.Listener _print.println(d + (ms > 99 ? "." : (ms > 9 ? ".0" : ".00")) + ms + ":" + name + " " + message); } - /* (non-Javadoc) - * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart() - */ @Override protected void doStart() throws Exception { @@ -139,9 +133,6 @@ public class DebugHandler extends HandlerWrapper implements Connection.Listener super.doStart(); } - /* (non-Javadoc) - * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStop() - */ @Override protected void doStop() throws Exception { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java index cd0f164d2f3..67c7c1b3efb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -36,9 +36,9 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.nio.charset.StandardCharsets.UTF_8; @@ -52,7 +52,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; */ public class DefaultHandler extends AbstractHandler { - private static final Logger LOG = Log.getLogger(DefaultHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(DefaultHandler.class); final long _faviconModified = (System.currentTimeMillis() / 1000) * 1000L; final byte[] _favicon; @@ -61,10 +61,11 @@ public class DefaultHandler extends AbstractHandler public DefaultHandler() { + String faviconRef = "/org/eclipse/jetty/favicon.ico"; byte[] favbytes = null; try { - URL fav = getClass().getResource("/org/eclipse/jetty/favicon.ico"); + URL fav = getClass().getResource(faviconRef); if (fav != null) { Resource r = Resource.newResource(fav); @@ -73,7 +74,7 @@ public class DefaultHandler extends AbstractHandler } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to find default favicon: {}", faviconRef, e); } finally { @@ -81,9 +82,6 @@ public class DefaultHandler extends AbstractHandler } } - /* - * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java index a1a560ec9c0..3cf51e905ea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java @@ -1,31 +1,36 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; +import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -33,31 +38,36 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.QuotedQualityCSV; +import org.eclipse.jetty.io.ByteBufferOutputStream; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Handler for Error pages * An ErrorHandler is registered with {@link ContextHandler#setErrorHandler(ErrorHandler)} or * {@link Server#setErrorHandler(ErrorHandler)}. - * It is called by the HttpResponse.sendError method to write a error page via {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} + * It is called by the HttpResponse.sendError method to write an error page via {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} * or via {@link #badMessageError(int, String, HttpFields)} for bad requests for which a dispatch cannot be done. */ public class ErrorHandler extends AbstractHandler { - private static final Logger LOG = Log.getLogger(ErrorHandler.class); + // TODO This classes API needs to be majorly refactored/cleanup in jetty-10 + private static final Logger LOG = LoggerFactory.getLogger(ErrorHandler.class); public static final String ERROR_PAGE = "org.eclipse.jetty.server.error_page"; + public static final String ERROR_CONTEXT = "org.eclipse.jetty.server.error_context"; + boolean _showServlet = true; boolean _showStacks = true; + boolean _disableStacks = false; boolean _showMessageInTitle = true; String _cacheControl = "must-revalidate,no-cache,no-store"; @@ -65,84 +75,59 @@ public class ErrorHandler extends AbstractHandler { } - /* - * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public boolean errorPageForMethod(String method) { - doError(target, baseRequest, request, response); + switch (method) + { + case "GET": + case "POST": + case "HEAD": + return true; + default: + return false; + } } - @Override - public void doError(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - String method = request.getMethod(); - if (!HttpMethod.GET.is(method) && !HttpMethod.POST.is(method) && !HttpMethod.HEAD.is(method)) + String cacheControl = getCacheControl(); + if (cacheControl != null) + response.setHeader(HttpHeader.CACHE_CONTROL.asString(), cacheControl); + + // Look for an error page dispatcher + // This logic really should be in ErrorPageErrorHandler, but some implementations extend ErrorHandler + // and implement ErrorPageMapper directly, so we do this here in the base class. + String errorPage = (this instanceof ErrorPageMapper) ? ((ErrorPageMapper)this).getErrorPage(request) : null; + ContextHandler.Context context = baseRequest.getErrorContext(); + Dispatcher errorDispatcher = (errorPage != null && context != null) + ? (Dispatcher)context.getRequestDispatcher(errorPage) : null; + + try + { + if (errorDispatcher != null) + { + try + { + errorDispatcher.error(request, response); + return; + } + catch (ServletException e) + { + LOG.debug("Unable to call error dispatcher", e); + if (response.isCommitted()) + return; + } + } + + String message = (String)request.getAttribute(Dispatcher.ERROR_MESSAGE); + if (message == null) + message = baseRequest.getResponse().getReason(); + generateAcceptableResponse(baseRequest, request, response, response.getStatus(), message); + } + finally { baseRequest.setHandled(true); - return; } - - if (this instanceof ErrorPageMapper) - { - String errorPage = ((ErrorPageMapper)this).getErrorPage(request); - if (errorPage != null) - { - String oldErrorPage = (String)request.getAttribute(ERROR_PAGE); - ContextHandler.Context context = baseRequest.getContext(); - if (context == null) - context = ContextHandler.getCurrentContext(); - if (context == null) - { - LOG.warn("No ServletContext for error page {}", errorPage); - } - else if (oldErrorPage != null && oldErrorPage.equals(errorPage)) - { - LOG.warn("Error page loop {}", errorPage); - } - else - { - request.setAttribute(ERROR_PAGE, errorPage); - - Dispatcher dispatcher = (Dispatcher)context.getRequestDispatcher(errorPage); - try - { - if (LOG.isDebugEnabled()) - LOG.debug("error page dispatch {}->{}", errorPage, dispatcher); - if (dispatcher != null) - { - dispatcher.error(request, response); - return; - } - LOG.warn("No error page found " + errorPage); - } - catch (ServletException e) - { - LOG.warn(Log.EXCEPTION, e); - return; - } - } - } - else - { - if (LOG.isDebugEnabled()) - { - LOG.debug("No Error Page mapping for request({} {}) (using default)", request.getMethod(), request.getRequestURI()); - } - } - } - - if (_cacheControl != null) - response.setHeader(HttpHeader.CACHE_CONTROL.asString(), _cacheControl); - - String message = (String)request.getAttribute(RequestDispatcher.ERROR_MESSAGE); - if (message == null) - message = baseRequest.getResponse().getReason(); - if (message == null) - message = HttpStatus.getMessage(response.getStatus()); - - generateAcceptableResponse(baseRequest, request, response, response.getStatus(), message); } /** @@ -151,7 +136,7 @@ public class ErrorHandler extends AbstractHandler * acceptable to the user-agent. The Accept header is evaluated in * quality order and the method * {@link #generateAcceptableResponse(Request, HttpServletRequest, HttpServletResponse, int, String, String)} - * is called for each mimetype until {@link Request#isHandled()} is true.

      + * is called for each mimetype until the response is written to or committed.

      * * @param baseRequest The base request * @param request The servlet request (may be wrapped) @@ -174,48 +159,10 @@ public class ErrorHandler extends AbstractHandler for (String mimeType : acceptable) { generateAcceptableResponse(baseRequest, request, response, code, message, mimeType); - if (response.isCommitted() || baseRequest.getResponse().isWriting() || baseRequest.getResponse().isStreaming()) + if (response.isCommitted() || baseRequest.getResponse().isWritingOrStreaming()) break; } } - baseRequest.getResponse().closeOutput(); - } - - /** - * Generate an acceptable error response for a mime type. - *

      This method is called for each mime type in the users agent's - * Accept header, until {@link Request#isHandled()} is true and a - * response of the appropriate type is generated. - * - * @param baseRequest The base request - * @param request The servlet request (may be wrapped) - * @param response The response (may be wrapped) - * @param code the http error code - * @param message the http error message - * @param mimeType The mimetype to generate (may be */*or other wildcard) - * @throws IOException if a response cannot be generated - */ - protected void generateAcceptableResponse(Request baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message, String mimeType) - throws IOException - { - switch (mimeType) - { - case "text/html": - case "text/*": - case "*/*": - { - baseRequest.setHandled(true); - Writer writer = getAcceptableWriter(baseRequest, request, response); - if (writer != null) - { - response.setContentType(MimeTypes.Type.TEXT_HTML.asString()); - handleErrorPage(request, writer, code, message); - } - break; - } - default: - break; - } } /** @@ -236,6 +183,7 @@ public class ErrorHandler extends AbstractHandler * @return A {@link Writer} if there is a known acceptable charset or null * @throws IOException if a Writer cannot be returned */ + @Deprecated protected Writer getAcceptableWriter(Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -258,12 +206,146 @@ public class ErrorHandler extends AbstractHandler } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } return null; } + /** + * Generate an acceptable error response for a mime type. + *

      This method is called for each mime type in the users agent's + * Accept header, until {@link Request#isHandled()} is true and a + * response of the appropriate type is generated. + *

      + *

      The default implementation handles "text/html", "text/*" and "*/*". + * The method can be overridden to handle other types. Implementations must + * immediate produce a response and may not be async. + *

      + * + * @param baseRequest The base request + * @param request The servlet request (may be wrapped) + * @param response The response (may be wrapped) + * @param code the http error code + * @param message the http error message + * @param contentType The mimetype to generate (may be */*or other wildcard) + * @throws IOException if a response cannot be generated + */ + protected void generateAcceptableResponse(Request baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message, String contentType) + throws IOException + { + // We can generate an acceptable contentType, but can we generate an acceptable charset? + // TODO refactor this in jetty-10 to be done in the other calling loop + Charset charset = null; + List acceptable = baseRequest.getHttpFields().getQualityCSV(HttpHeader.ACCEPT_CHARSET); + if (!acceptable.isEmpty()) + { + for (String name : acceptable) + { + if ("*".equals(name)) + { + charset = StandardCharsets.UTF_8; + break; + } + + try + { + charset = Charset.forName(name); + } + catch (Exception e) + { + LOG.trace("IGNORED", e); + } + } + if (charset == null) + return; + } + + MimeTypes.Type type; + switch (contentType) + { + case "text/html": + case "text/*": + case "*/*": + type = MimeTypes.Type.TEXT_HTML; + if (charset == null) + charset = StandardCharsets.ISO_8859_1; + break; + + case "text/json": + case "application/json": + type = MimeTypes.Type.TEXT_JSON; + if (charset == null) + charset = StandardCharsets.UTF_8; + break; + + case "text/plain": + type = MimeTypes.Type.TEXT_PLAIN; + if (charset == null) + charset = StandardCharsets.ISO_8859_1; + break; + + default: + return; + } + + // write into the response aggregate buffer and flush it asynchronously. + while (true) + { + try + { + // TODO currently the writer used here is of fixed size, so a large + // TODO error page may cause a BufferOverflow. In which case we try + // TODO again with stacks disabled. If it still overflows, it is + // TODO written without a body. + ByteBuffer buffer = baseRequest.getResponse().getHttpOutput().acquireBuffer(); + ByteBufferOutputStream out = new ByteBufferOutputStream(buffer); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, charset)); + + switch (type) + { + case TEXT_HTML: + response.setContentType(MimeTypes.Type.TEXT_HTML.asString()); + response.setCharacterEncoding(charset.name()); + handleErrorPage(request, writer, code, message); + break; + case TEXT_JSON: + response.setContentType(contentType); + writeErrorJson(request, writer, code, message); + break; + case TEXT_PLAIN: + response.setContentType(MimeTypes.Type.TEXT_PLAIN.asString()); + response.setCharacterEncoding(charset.name()); + writeErrorPlain(request, writer, code, message); + break; + default: + throw new IllegalStateException(); + } + + writer.flush(); + break; + } + catch (BufferOverflowException e) + { + if (LOG.isDebugEnabled()) + LOG.warn("Error page too large: {} {} {}", code, message, request, e); + else + LOG.warn("Error page too large: {} {} {}", code, message, request); + baseRequest.getResponse().resetContent(); + if (!_disableStacks) + { + LOG.info("Disabling showsStacks for " + this); + _disableStacks = true; + continue; + } + break; + } + } + + // Do an asynchronous completion. + baseRequest.getHttpChannel().sendResponseAndComplete(); + } + protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException { @@ -288,12 +370,13 @@ public class ErrorHandler extends AbstractHandler { writer.write("\n"); writer.write("Error "); - writer.write(Integer.toString(code)); - - if (_showMessageInTitle) + // TODO this code is duplicated in writeErrorPageMessage + String status = Integer.toString(code); + writer.write(status); + if (message != null && !message.equals(status)) { writer.write(' '); - write(writer, message); + writer.write(StringUtil.sanitizeXmlString(message)); } writer.write("\n"); } @@ -304,7 +387,7 @@ public class ErrorHandler extends AbstractHandler String uri = request.getRequestURI(); writeErrorPageMessage(request, writer, code, message, uri); - if (showStacks) + if (showStacks && !_disableStacks) writeErrorPageStacks(request, writer); Request.getBaseRequest(request).getHttpChannel().getHttpConfiguration() @@ -315,35 +398,116 @@ public class ErrorHandler extends AbstractHandler throws IOException { writer.write("

      HTTP ERROR "); + String status = Integer.toString(code); + writer.write(status); + if (message != null && !message.equals(status)) + { + writer.write(' '); + writer.write(StringUtil.sanitizeXmlString(message)); + } + writer.write("

      \n"); + writer.write("\n"); + htmlRow(writer, "URI", uri); + htmlRow(writer, "STATUS", status); + htmlRow(writer, "MESSAGE", message); + htmlRow(writer, "SERVLET", request.getAttribute(Dispatcher.ERROR_SERVLET_NAME)); + Throwable cause = (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION); + while (cause != null) + { + htmlRow(writer, "CAUSED BY", cause); + cause = cause.getCause(); + } + writer.write("
      \n"); + } + + private void htmlRow(Writer writer, String tag, Object value) + throws IOException + { + writer.write(""); + writer.write(tag); + writer.write(":"); + if (value == null) + writer.write("-"); + else + writer.write(StringUtil.sanitizeXmlString(value.toString())); + writer.write("\n"); + } + + private void writeErrorPlain(HttpServletRequest request, PrintWriter writer, int code, String message) + { + writer.write("HTTP ERROR "); writer.write(Integer.toString(code)); - writer.write("\n

      Problem accessing "); - write(writer, uri); - writer.write(". Reason:\n

          ");
      -        write(writer, message);
      -        writer.write("

      "); + writer.write(' '); + writer.write(StringUtil.sanitizeXmlString(message)); + writer.write("\n"); + writer.printf("URI: %s%n", request.getRequestURI()); + writer.printf("STATUS: %s%n", code); + writer.printf("MESSAGE: %s%n", message); + if (isShowServlet()) + { + writer.printf("SERVLET: %s%n", request.getAttribute(Dispatcher.ERROR_SERVLET_NAME)); + } + Throwable cause = (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION); + while (cause != null) + { + writer.printf("CAUSED BY %s%n", cause); + if (_showStacks && !_disableStacks) + { + cause.printStackTrace(writer); + } + cause = cause.getCause(); + } + } + + private void writeErrorJson(HttpServletRequest request, PrintWriter writer, int code, String message) + { + Throwable cause = (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION); + Object servlet = request.getAttribute(Dispatcher.ERROR_SERVLET_NAME); + Map json = new HashMap<>(); + + json.put("url", request.getRequestURI()); + json.put("status", Integer.toString(code)); + json.put("message", message); + if (isShowServlet() && servlet != null) + { + json.put("servlet", servlet.toString()); + } + int c = 0; + while (cause != null) + { + json.put("cause" + c++, cause.toString()); + cause = cause.getCause(); + } + + writer.append(json.entrySet().stream() + .map(e -> QuotedStringTokenizer.quote(e.getKey()) + + ":" + + QuotedStringTokenizer.quote(StringUtil.sanitizeXmlString((e.getValue())))) + .collect(Collectors.joining(",\n", "{\n", "\n}"))); } protected void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException { Throwable th = (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); - while (th != null) + if (th != null) { writer.write("

      Caused by:

      ");
      -            StringWriter sw = new StringWriter();
      -            PrintWriter pw = new PrintWriter(sw);
      -            th.printStackTrace(pw);
      -            pw.flush();
      -            write(writer, sw.getBuffer().toString());
      +            // You have to pre-generate and then use #write(writer, String)
      +            try (StringWriter sw = new StringWriter();
      +                 PrintWriter pw = new PrintWriter(sw))
      +            {
      +                th.printStackTrace(pw);
      +                pw.flush();
      +                write(writer, sw.getBuffer().toString()); // sanitize
      +            }
                   writer.write("
      \n"); - - th = th.getCause(); } } /** * Bad Message Error body - *

      Generate a error response body to be sent for a bad message. + *

      Generate an error response body to be sent for a bad message. * In this case there is something wrong with the request, so either * a request cannot be built, or it is not safe to build a request. * This method allows for a simple error page body to be returned @@ -382,6 +546,22 @@ public class ErrorHandler extends AbstractHandler _cacheControl = cacheControl; } + /** + * @return True if the error page will show the Servlet that generated the error + */ + public boolean isShowServlet() + { + return _showServlet; + } + + /** + * @param showServlet True if the error page will show the Servlet that generated the error + */ + public void setShowServlet(boolean showServlet) + { + _showServlet = showServlet; + } + /** * @return True if stack traces are shown in the error pages */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index dfea9fc93b7..f677a9cccbb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -82,7 +82,7 @@ public class HandlerCollection extends AbstractHandlerContainer public void setHandlers(Handler[] handlers) { if (!_mutableWhenRunning && isStarted()) - throw new IllegalStateException(STARTED); + throw new IllegalStateException(getState()); while (true) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java index 82c142e899e..2507ea9322e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerList.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -43,9 +43,6 @@ public class HandlerList extends HandlerCollection super(handlers); } - /** - * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java index 27a53fecf98..86d58347660 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -74,7 +74,7 @@ public class HandlerWrapper extends AbstractHandlerContainer public void setHandler(Handler handler) { if (isStarted()) - throw new IllegalStateException(STARTED); + throw new IllegalStateException(getState()); // check for loops if (handler == this || (handler instanceof HandlerContainer && diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java index b78146f8505..162d1ce3f89 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -81,27 +81,18 @@ public class HotSwapHandler extends AbstractHandlerContainer } } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { super.doStart(); } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { super.doStop(); } - /* - * @see org.eclipse.jetty.server.server.EventHandler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java index c6d260eb74a..e1a96242b7d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java index bf2a96cffe6..e35b6bce96d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -26,15 +26,19 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.util.IncludeExclude; import org.eclipse.jetty.util.IncludeExcludeSet; +import org.eclipse.jetty.util.InetAddressPattern; import org.eclipse.jetty.util.InetAddressSet; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.eclipse.jetty.server.handler.InetAccessSet.AccessTuple; +import static org.eclipse.jetty.server.handler.InetAccessSet.PatternTuple; /** * InetAddress Access Handler @@ -43,18 +47,13 @@ import org.eclipse.jetty.util.log.Logger; * provided by and {@link IncludeExcludeSet} over a {@link InetAddressSet}. This * handler uses the real internet address of the connection, not one reported in * the forwarded for headers, as this cannot be as easily forged. - *

      - * Additionally, there may be times when you want to only apply this handler to - * a subset of your connectors. In this situation you can use - * connectorNames to specify the connector names that you want this IP - * access filter to apply to. + *

      */ public class InetAccessHandler extends HandlerWrapper { - private static final Logger LOG = Log.getLogger(InetAccessHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(InetAccessHandler.class); - private final IncludeExcludeSet _addrs = new IncludeExcludeSet<>(InetAddressSet.class); - private final IncludeExclude _names = new IncludeExclude<>(); + private final IncludeExcludeSet _set = new IncludeExcludeSet<>(InetAccessSet.class); /** * Clears all the includes, excludes, included connector names and excluded @@ -62,92 +61,158 @@ public class InetAccessHandler extends HandlerWrapper */ public void clear() { - _addrs.clear(); - _names.clear(); + _set.clear(); } /** - * Includes an InetAddress pattern + * Includes an InetAccess pattern with an optional connector name, address and URI mapping. * - * @param pattern InetAddress pattern to include + *

      The connector name is separated from the InetAddress pattern with an '@' character, + * and the InetAddress pattern is separated from the URI pattern using the "|" (pipe) + * character. URI patterns follow the servlet specification for simple * prefix and + * suffix wild cards (e.g. /, /foo, /foo/bar, /foo/bar/*, *.baz).

      + * + *
      Examples: + *
        + *
      • "connector1@127.0.0.1|/foo"
      • + *
      • "127.0.0.1|/foo"
      • + *
      • "connector1@127.0.0.1"
      • + *
      • "127.0.0.1"
      • + *
      + * + * @param pattern InetAccess pattern to include * @see InetAddressSet */ public void include(String pattern) { - _addrs.include(pattern); + _set.include(PatternTuple.from(pattern)); } /** - * Includes InetAddress patterns + * Includes InetAccess patterns * * @param patterns InetAddress patterns to include * @see InetAddressSet */ public void include(String... patterns) { - _addrs.include(patterns); + for (String pattern : patterns) + { + include(pattern); + } } /** - * Excludes an InetAddress pattern + * Includes an InetAccess entry. + * + * @param connectorName optional name of a connector to include. + * @param addressPattern optional InetAddress pattern to include. + * @param pathSpec optional pathSpec to include. + */ + public void include(String connectorName, String addressPattern, PathSpec pathSpec) + { + _set.include(new PatternTuple(connectorName, InetAddressPattern.from(addressPattern), pathSpec)); + } + + /** + * Excludes an InetAccess entry pattern with an optional connector name, address and URI mapping. + * + *

      The connector name is separated from the InetAddress pattern with an '@' character, + * and the InetAddress pattern is separated from the URI pattern using the "|" (pipe) + * character. URI patterns follow the servlet specification for simple * prefix and + * suffix wild cards (e.g. /, /foo, /foo/bar, /foo/bar/*, *.baz).

      + * + *
      Examples: + *
        + *
      • "connector1@127.0.0.1|/foo"
      • + *
      • "127.0.0.1|/foo"
      • + *
      • "connector1@127.0.0.1"
      • + *
      • "127.0.0.1"
      • + *
      * * @param pattern InetAddress pattern to exclude * @see InetAddressSet */ public void exclude(String pattern) { - _addrs.exclude(pattern); + _set.exclude(PatternTuple.from(pattern)); } /** - * Excludes InetAddress patterns + * Excludes InetAccess patterns * * @param patterns InetAddress patterns to exclude * @see InetAddressSet */ public void exclude(String... patterns) { - _addrs.exclude(patterns); + for (String pattern : patterns) + { + exclude(pattern); + } + } + + /** + * Excludes an InetAccess entry. + * + * @param connectorName optional name of a connector to exclude. + * @param addressPattern optional InetAddress pattern to exclude. + * @param pathSpec optional pathSpec to exclude. + */ + public void exclude(String connectorName, String addressPattern, PathSpec pathSpec) + { + _set.exclude(new PatternTuple(connectorName, InetAddressPattern.from(addressPattern), pathSpec)); } /** * Includes a connector name. * * @param name Connector name to include in this handler. + * @deprecated use {@link InetAccessHandler#include(String)} instead. */ + @Deprecated public void includeConnector(String name) { - _names.include(name); + throw new UnsupportedOperationException(); } /** * Excludes a connector name. * * @param name Connector name to exclude in this handler. + * @deprecated use {@link InetAccessHandler#include(String)} instead. */ + @Deprecated public void excludeConnector(String name) { - _names.exclude(name); + _set.exclude(new PatternTuple(name, null, null)); } /** * Includes connector names. * * @param names Connector names to include in this handler. + * @deprecated use {@link InetAccessHandler#include(String)} instead. */ + @Deprecated public void includeConnectors(String... names) { - _names.include(names); + throw new UnsupportedOperationException(); } /** * Excludes connector names. * * @param names Connector names to exclude in this handler. + * @deprecated use {@link InetAccessHandler#include(String)} instead. */ + @Deprecated public void excludeConnectors(String... names) { - _names.exclude(names); + for (String name : names) + { + excludeConnector(name); + } } /** @@ -187,23 +252,16 @@ public class InetAccessHandler extends HandlerWrapper */ protected boolean isAllowed(InetAddress addr, Request baseRequest, HttpServletRequest request) { - String name = baseRequest.getHttpChannel().getConnector().getName(); - if (LOG.isDebugEnabled()) - { - Boolean allowedByName = _names.isIncludedAndNotExcluded(name); - Boolean allowedByAddr = _addrs.isIncludedAndNotExcluded(addr); - LOG.debug("{} allowedByName={} allowedByAddr={} for {}/{}", this, allowedByName, allowedByAddr, addr, request); - } - return _names.test(name) && _addrs.test(addr); + String connectorName = baseRequest.getHttpChannel().getConnector().getName(); + String path = baseRequest.getMetaData().getURI().getDecodedPath(); + return _set.test(new AccessTuple(connectorName, addr, path)); } @Override public void dump(Appendable out, String indent) throws IOException { dumpObjects(out, indent, - new DumpableCollection("included", _addrs.getIncluded()), - new DumpableCollection("excluded", _addrs.getExcluded()), - new DumpableCollection("includedConnector", _names.getIncluded()), - new DumpableCollection("excludedConnector", _names.getExcluded())); + new DumpableCollection("included", _set.getIncluded()), + new DumpableCollection("excluded", _set.getExcluded())); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessSet.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessSet.java new file mode 100644 index 00000000000..8cf62c3f279 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessSet.java @@ -0,0 +1,158 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.handler; + +import java.net.InetAddress; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Predicate; + +import org.eclipse.jetty.http.pathmap.PathSpec; +import org.eclipse.jetty.http.pathmap.ServletPathSpec; +import org.eclipse.jetty.util.InetAddressPattern; +import org.eclipse.jetty.util.StringUtil; + +public class InetAccessSet extends AbstractSet implements Set, Predicate +{ + private ArrayList tuples = new ArrayList<>(); + + @Override + public boolean add(PatternTuple storageTuple) + { + return tuples.add(storageTuple); + } + + @Override + public boolean remove(Object o) + { + return tuples.remove(o); + } + + @Override + public Iterator iterator() + { + return tuples.iterator(); + } + + @Override + public int size() + { + return tuples.size(); + } + + @Override + public boolean test(AccessTuple entry) + { + if (entry == null) + return false; + + for (PatternTuple tuple : tuples) + { + if (tuple.test(entry)) + return true; + } + return false; + } + + static class PatternTuple implements Predicate + { + private final String connector; + private final InetAddressPattern address; + private final PathSpec pathSpec; + + public static PatternTuple from(String pattern) + { + + String path = null; + int pathIndex = pattern.indexOf('|'); + if (pathIndex >= 0) + path = pattern.substring(pathIndex + 1); + + String connector = null; + int connectorIndex = pattern.indexOf('@'); + if (connectorIndex >= 0) + connector = pattern.substring(0, connectorIndex); + + String addr = null; + int addrStart = (connectorIndex < 0) ? 0 : connectorIndex + 1; + int addrEnd = (pathIndex < 0) ? pattern.length() : pathIndex; + if (addrStart != addrEnd) + addr = pattern.substring(addrStart, addrEnd); + + return new PatternTuple(connector, InetAddressPattern.from(addr), + StringUtil.isEmpty(path) ? null : new ServletPathSpec(path)); + } + + public PatternTuple(String connector, InetAddressPattern address, PathSpec pathSpec) + { + this.connector = connector; + this.address = address; + this.pathSpec = pathSpec; + } + + @Override + public boolean test(AccessTuple entry) + { + // Match for connector. + if ((connector != null) && !connector.equals(entry.getConnector())) + return false; + + // If we have a path we must must be at this path to match for an address. + if ((pathSpec != null) && !pathSpec.matches(entry.getPath())) + return false; + + // Match for InetAddress. + if ((address != null) && !address.test(entry.getAddress())) + return false; + + return true; + } + } + + static class AccessTuple + { + private final String connector; + private final InetAddress address; + private final String path; + + public AccessTuple(String connector, InetAddress address, String path) + { + this.connector = connector; + this.address = address; + this.path = path; + } + + public String getConnector() + { + return connector; + } + + public InetAddress getAddress() + { + return address; + } + + public String getPath() + { + return path; + } + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ManagedAttributeListener.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ManagedAttributeListener.java index 9e4fe6e44c5..e7450c9afb7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ManagedAttributeListener.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ManagedAttributeListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -26,15 +26,15 @@ import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Enable Jetty style JMX MBeans from within a Context */ public class ManagedAttributeListener implements ServletContextListener, ServletContextAttributeListener { - private static final Logger LOG = Log.getLogger(ManagedAttributeListener.class); + private static final Logger LOG = LoggerFactory.getLogger(ManagedAttributeListener.class); final Set _managedAttributes = new HashSet<>(); final ContextHandler _context; @@ -100,7 +100,6 @@ public class ManagedAttributeListener implements ServletContextListener, Servlet protected void updateBean(String name, Object oldBean, Object newBean) { - LOG.info("update {} {}->{} on {}", name, oldBean, newBean, _context); if (LOG.isDebugEnabled()) LOG.debug("update {} {}->{} on {}", name, oldBean, newBean, _context); _context.updateBean(oldBean, newBean, false); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java index b4268edd44b..7d80fe740a2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java index 5405151dc0c..5e8bf28eebd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -41,9 +41,6 @@ public class RequestLogHandler extends HandlerWrapper { private RequestLog _requestLog; - /* - * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java index f1349032a65..b3412f56f11 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -37,10 +37,10 @@ import org.eclipse.jetty.server.ResourceService; import org.eclipse.jetty.server.ResourceService.WelcomeFactory; import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Resource Handler. @@ -50,7 +50,7 @@ import org.eclipse.jetty.util.resource.ResourceFactory; */ public class ResourceHandler extends HandlerWrapper implements ResourceFactory, WelcomeFactory { - private static final Logger LOG = Log.getLogger(ResourceHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(ResourceHandler.class); Resource _baseResource; ContextHandler _context; @@ -174,7 +174,7 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory, } catch (Exception e) { - LOG.debug(e); + LOG.debug("Unable to get Resource for {}", path, e); } return null; @@ -214,9 +214,6 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory, return _welcomes; } - /* - * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -397,8 +394,7 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory, } catch (Exception e) { - LOG.warn(e.toString()); - LOG.debug(e); + LOG.warn("Invalid Base Resource reference: {}", resourceBase, e); throw new IllegalArgumentException(resourceBase); } } @@ -419,8 +415,7 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory, } catch (Exception e) { - LOG.warn(e.toString()); - LOG.debug(e); + LOG.warn("Invalid StyleSheet reference: {}", stylesheet, e); throw new IllegalArgumentException(stylesheet); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java index 4a60d3d6757..92a157d915b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ScopedHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -105,9 +105,6 @@ public abstract class ScopedHandler extends HandlerWrapper protected ScopedHandler _outerScope; protected ScopedHandler _nextScope; - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart() - */ @Override protected void doStart() throws Exception { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SecuredRedirectHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SecuredRedirectHandler.java index 61c620589ee..bef74df7b94 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SecuredRedirectHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SecuredRedirectHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java index 947cf9ce5f2..17201afb8d1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -31,14 +31,14 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A handler that shuts the server down on a valid request. Used to do "soft" restarts from Java. * If _exitJvm is set to true a hard System.exit() call is being made. * If _sendShutdownAtStart is set to true, starting the server will try to shut down an existing server at the same port. - * If _sendShutdownAtStart is set to true, make a http call to + * If _sendShutdownAtStart is set to true, make an http call to * "http://localhost:" + port + "/shutdown?token=" + shutdownCookie * in order to shut down the server. * @@ -74,7 +74,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ShutdownHandler extends HandlerWrapper { - private static final Logger LOG = Log.getLogger(ShutdownHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(ShutdownHandler.class); private final String _shutdownToken; private boolean _sendShutdownAtStart; @@ -93,7 +93,7 @@ public class ShutdownHandler extends HandlerWrapper /** * @param shutdownToken a secret password to avoid unauthorized shutdown attempts * @param exitJVM If true, when the shutdown is executed, the handler class System.exit() - * @param sendShutdownAtStart If true, a shutdown is sent as a HTTP post + * @param sendShutdownAtStart If true, a shutdown is sent as an HTTP post * during startup, which will shutdown any previously running instances of * this server with an identically configured ShutdownHandler */ @@ -190,8 +190,9 @@ public class ShutdownHandler extends HandlerWrapper connector.shutdown(); } - response.sendError(200, "Connectors closed, commencing full shutdown"); baseRequest.setHandled(true); + response.setStatus(200); + response.flushBuffer(); final Server server = getServer(); new Thread() @@ -205,7 +206,7 @@ public class ShutdownHandler extends HandlerWrapper } catch (InterruptedException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } catch (Exception e) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java index 0c5a9705aba..dac8a1d49dc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java @@ -1,25 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; import java.io.IOException; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAdder; @@ -35,21 +35,21 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpChannelState; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.component.Graceful; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.util.statistic.SampleStatistic; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject("Request Statistics Gathering") public class StatisticsHandler extends HandlerWrapper implements Graceful { - private static final Logger LOG = Log.getLogger(StatisticsHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(StatisticsHandler.class); private final AtomicLong _statsStartedAt = new AtomicLong(); + private volatile Shutdown _shutdown; private final CounterStatistic _requestStats = new CounterStatistic(); private final SampleStatistic _requestTimeStats = new SampleStatistic(); @@ -67,15 +67,6 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful private final LongAdder _responses5xx = new LongAdder(); private final LongAdder _responsesTotalBytes = new LongAdder(); - private final Graceful.Shutdown _shutdown = new Graceful.Shutdown() - { - @Override - protected FutureCallback newShutdownCallback() - { - return new FutureCallback(_requestStats.getCurrent() == 0); - } - }; - private final AtomicBoolean _wrapWarning = new AtomicBoolean(); private final AsyncListener _onCompletion = new AsyncListener() @@ -115,9 +106,9 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful // If we have no more dispatches, should we signal shutdown? if (d == 0) { - FutureCallback shutdown = _shutdown.get(); + Shutdown shutdown = _shutdown; if (shutdown != null) - shutdown.succeeded(); + shutdown.check(); } } }; @@ -204,12 +195,12 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful updateResponse(baseRequest); // If we have no more dispatches, should we signal shutdown? - FutureCallback shutdown = _shutdown.get(); + Shutdown shutdown = _shutdown; if (shutdown != null) { response.flushBuffer(); if (d == 0) - shutdown.succeeded(); + shutdown.check(); } } // else onCompletion will handle it. @@ -251,7 +242,14 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful @Override protected void doStart() throws Exception { - _shutdown.cancel(); + _shutdown = new Shutdown(this) + { + @Override + public boolean isShutdownDone() + { + return _requestStats.getCurrent() == 0; + } + }; super.doStart(); statsReset(); } @@ -259,8 +257,8 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful @Override protected void doStop() throws Exception { - _shutdown.cancel(); super.doStop(); + _shutdown = null; } /** @@ -576,15 +574,19 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful } @Override - public Future shutdown() + public CompletableFuture shutdown() { - return _shutdown.shutdown(); + Shutdown shutdown = _shutdown; + if (shutdown == null) + return CompletableFuture.completedFuture(null); + return shutdown.shutdown(); } @Override public boolean isShutdown() { - return _shutdown.isShutdown(); + Shutdown shutdown = _shutdown; + return shutdown == null || shutdown.isShutdown(); } @Override @@ -592,4 +594,5 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful { return String.format("%s@%x{%s,r=%d,d=%d}", getClass().getSimpleName(), hashCode(), getState(), _requestStats.getCurrent(), _dispatchedStats.getCurrent()); } + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java index 7666bcb0641..5fbf5105d59 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler; @@ -46,9 +46,9 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Locker; +import org.eclipse.jetty.util.thread.AutoLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      Handler to limit the threads per IP address for DOS protection

      @@ -72,7 +72,7 @@ import org.eclipse.jetty.util.thread.Locker; */ public class ThreadLimitHandler extends HandlerWrapper { - private static final Logger LOG = Log.getLogger(ThreadLimitHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(ThreadLimitHandler.class); private static final String REMOTE = "o.e.j.s.h.TLH.REMOTE"; private static final String PERMIT = "o.e.j.s.h.TLH.PASS"; @@ -140,7 +140,7 @@ public class ThreadLimitHandler extends HandlerWrapper } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } return _threadLimit; @@ -241,7 +241,7 @@ public class ThreadLimitHandler extends HandlerWrapper } } - protected Remote getRemote(Request baseRequest) + private Remote getRemote(Request baseRequest) { Remote remote = (Remote)baseRequest.getAttribute(REMOTE); if (remote != null) @@ -329,11 +329,11 @@ public class ThreadLimitHandler extends HandlerWrapper return (comma >= 0) ? forwardedFor.substring(comma + 1).trim() : forwardedFor; } - private final class Remote implements Closeable + private static final class Remote implements Closeable { private final String _ip; private final int _limit; - private final Locker _locker = new Locker(); + private final AutoLock _lock = new AutoLock(); private int _permits; private Deque> _queue = new ArrayDeque<>(); private final CompletableFuture _permitted = CompletableFuture.completedFuture(this); @@ -346,7 +346,7 @@ public class ThreadLimitHandler extends HandlerWrapper public CompletableFuture acquire() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { // Do we have available passes? if (_permits < _limit) @@ -358,16 +358,16 @@ public class ThreadLimitHandler extends HandlerWrapper } // No pass available, so queue a new future - CompletableFuture pass = new CompletableFuture(); + CompletableFuture pass = new CompletableFuture<>(); _queue.addLast(pass); return pass; } } @Override - public void close() throws IOException + public void close() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { // reduce the allocated passes _permits--; @@ -396,14 +396,14 @@ public class ThreadLimitHandler extends HandlerWrapper @Override public String toString() { - try (Locker.Lock lock = _locker.lock()) + try (AutoLock lock = _lock.lock()) { return String.format("R[ip=%s,p=%d,l=%d,q=%d]", _ip, _permits, _limit, _queue.size()); } } } - private final class RFC7239 extends QuotedCSV + private static final class RFC7239 extends QuotedCSV { String _for; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipFactory.java index bf1c64277dd..3c935e3e536 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler.gzip; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java index 5c590b2d3e5..59da37ce07e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler.gzip; @@ -25,7 +25,6 @@ import java.util.ListIterator; import java.util.Set; import java.util.regex.Pattern; import java.util.zip.Deflater; - import javax.servlet.DispatcherType; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -34,6 +33,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.CompressedContentFormat; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpMethod; @@ -48,8 +48,8 @@ import org.eclipse.jetty.util.RegexSet; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.compression.DeflaterPool; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A Handler that can dynamically GZIP uncompress requests, and compress responses. @@ -91,8 +91,7 @@ import org.eclipse.jetty.util.log.Logger; * *
    • * Is the Response {@code Content-Length} header present, and does its - * value meet the minimum gzip size requirements? - *
      (Default: 16 bytes. see {@link GzipHandler#DEFAULT_MIN_GZIP_SIZE}) + * value meet the minimum gzip size requirements (default 32 bytes)? *
    • *
    • * Is the Request {@code Accept} header present and does it contain the @@ -154,9 +153,9 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory { public static final String GZIP = "gzip"; public static final String DEFLATE = "deflate"; - public static final int DEFAULT_MIN_GZIP_SIZE = 2048; - public static final int COMPRESSION_LEVEL = Deflater.DEFAULT_COMPRESSION; - private static final Logger LOG = Log.getLogger(GzipHandler.class); + public static final int DEFAULT_MIN_GZIP_SIZE = 32; + public static final int BREAK_EVEN_GZIP_SIZE = 23; + private static final Logger LOG = LoggerFactory.getLogger(GzipHandler.class); private static final HttpField X_CE_GZIP = new PreEncodedHttpField("X-Content-Encoding", "gzip"); private static final HttpField TE_CHUNKED = new PreEncodedHttpField(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED.asString()); private static final Pattern COMMA_GZIP = Pattern.compile(".*, *gzip"); @@ -422,7 +421,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory @Override public Deflater getDeflater(Request request, long contentLength) { - String ua = request.getHttpFields().get(HttpHeader.USER_AGENT); + HttpFields httpFields = request.getHttpFields(); + String ua = httpFields.get(HttpHeader.USER_AGENT); if (ua != null && !isAgentGzipable(ua)) { LOG.debug("{} excluded user agent {}", this, request); @@ -436,16 +436,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } // check the accept encoding header - HttpField accept = request.getHttpFields().getField(HttpHeader.ACCEPT_ENCODING); - - if (accept == null) - { - LOG.debug("{} excluded !accept {}", this, request); - return null; - } - boolean gzip = accept.contains("gzip"); - - if (!gzip) + if (!httpFields.contains(HttpHeader.ACCEPT_ENCODING, "gzip")) { LOG.debug("{} excluded not gzip accept {}", this, request); return null; @@ -633,6 +624,9 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory if (inflate) { + if (LOG.isDebugEnabled()) + LOG.debug("{} inflate {}", this, request); + baseRequest.getHttpInput().addInterceptor(new GzipHttpInputInterceptor(baseRequest.getHttpChannel().getByteBufferPool(), _inflateBufferSize)); for (ListIterator i = baseRequest.getHttpFields().listIterator(); i.hasNext(); ) @@ -881,13 +875,19 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * Set the minimum response size to trigger dynamic compression + * Set the minimum response size to trigger dynamic compression. + *

      + * Sizes below {@link #BREAK_EVEN_GZIP_SIZE} will result a compressed response that is larger than the + * original data. + *

      * - * @param minGzipSize minimum response size in bytes + * @param minGzipSize minimum response size in bytes (not allowed to be lower then {@link #BREAK_EVEN_GZIP_SIZE}) */ public void setMinGzipSize(int minGzipSize) { - _minGzipSize = minGzipSize; + if (minGzipSize < BREAK_EVEN_GZIP_SIZE) + LOG.warn("minGzipSize of {} is inefficient for short content, break even is size {}", minGzipSize, BREAK_EVEN_GZIP_SIZE); + _minGzipSize = Math.max(0, minGzipSize); } /** @@ -959,4 +959,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory { return new DeflaterPool(capacity, Deflater.DEFAULT_COMPRESSION, true); } + + @Override + public String toString() + { + return String.format("%s@%x{%s,min=%s,inflate=%s}", getClass().getSimpleName(), hashCode(), getState(), _minGzipSize, _inflateBufferSize); + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpInputInterceptor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpInputInterceptor.java index 9fedb2b3938..f176a30164e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpInputInterceptor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpInputInterceptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler.gzip; @@ -27,7 +27,7 @@ import org.eclipse.jetty.server.HttpInput.Content; import org.eclipse.jetty.util.component.Destroyable; /** - * A HttpInput Interceptor that inflates GZIP encoded request content. + * An HttpInput Interceptor that inflates GZIP encoded request content. */ public class GzipHttpInputInterceptor implements HttpInput.Interceptor, Destroyable { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java index 4a582348277..3ec13e3a46b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler.gzip; @@ -36,14 +36,14 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingNestedCallback; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.http.CompressedContentFormat.GZIP; public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor { - public static Logger LOG = Log.getLogger(GzipHttpOutputInterceptor.class); + public static Logger LOG = LoggerFactory.getLogger(GzipHttpOutputInterceptor.class); private static final byte[] GZIP_HEADER = new byte[]{(byte)0x1f, (byte)0x8b, Deflater.DEFLATED, 0, 0, 0, 0, 0, 0, 0}; public static final HttpField VARY_ACCEPT_ENCODING_USER_AGENT = new PreEncodedHttpField(HttpHeader.VARY, HttpHeader.ACCEPT_ENCODING + ", " + HttpHeader.USER_AGENT); @@ -93,12 +93,6 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor return _interceptor; } - @Override - public boolean isOptimizedForDirectBuffers() - { - return false; // No point as deflator is in user space. - } - @Override public void write(ByteBuffer content, boolean complete, Callback callback) { @@ -128,20 +122,8 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor private void addTrailer() { - int i = _buffer.limit(); - _buffer.limit(i + 8); - - int v = (int)_crc.getValue(); - _buffer.put(i++, (byte)(v & 0xFF)); - _buffer.put(i++, (byte)((v >>> 8) & 0xFF)); - _buffer.put(i++, (byte)((v >>> 16) & 0xFF)); - _buffer.put(i++, (byte)((v >>> 24) & 0xFF)); - - v = _deflater.getTotalIn(); - _buffer.put(i++, (byte)(v & 0xFF)); - _buffer.put(i++, (byte)((v >>> 8) & 0xFF)); - _buffer.put(i++, (byte)((v >>> 16) & 0xFF)); - _buffer.put(i++, (byte)((v >>> 24) & 0xFF)); + BufferUtil.putIntLittleEndian(_buffer, (int)_crc.getValue()); + BufferUtil.putIntLittleEndian(_buffer, _deflater.getTotalIn()); } private void gzip(ByteBuffer content, boolean complete, final Callback callback) @@ -231,8 +213,6 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor fields.put(GZIP._contentEncoding); _crc.reset(); - _buffer = _channel.getByteBufferPool().acquire(_bufferSize, false); - BufferUtil.fill(_buffer, GZIP_HEADER, 0, GZIP_HEADER.length); // Adjust headers response.setContentLength(-1); @@ -325,82 +305,115 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor @Override protected Action process() throws Exception { + // If we have no deflator if (_deflater == null) - return Action.SUCCEEDED; - - if (_deflater.needsInput()) { - if (BufferUtil.isEmpty(_content)) + // then the trailer has been generated and written below. + // we have finished compressing the entire content, so + // cleanup and succeed. + if (_buffer != null) { - if (_deflater.finished()) - { - _factory.recycle(_deflater); - _deflater = null; - _channel.getByteBufferPool().release(_buffer); - _buffer = null; - if (_copy != null) - { - _channel.getByteBufferPool().release(_copy); - _copy = null; - } - return Action.SUCCEEDED; - } - - if (!_last) - { - return Action.SUCCEEDED; - } - - _deflater.finish(); + _channel.getByteBufferPool().release(_buffer); + _buffer = null; } - else if (_content.hasArray()) + if (_copy != null) { - byte[] array = _content.array(); - int off = _content.arrayOffset() + _content.position(); - int len = _content.remaining(); - BufferUtil.clear(_content); - - _crc.update(array, off, len); - _deflater.setInput(array, off, len); - if (_last) - _deflater.finish(); - } - else - { - if (_copy == null) - _copy = _channel.getByteBufferPool().acquire(_bufferSize, false); - BufferUtil.clearToFill(_copy); - int took = BufferUtil.put(_content, _copy); - BufferUtil.flipToFlush(_copy, 0); - if (took == 0) - throw new IllegalStateException(); - - byte[] array = _copy.array(); - int off = _copy.arrayOffset() + _copy.position(); - int len = _copy.remaining(); - - _crc.update(array, off, len); - _deflater.setInput(array, off, len); - if (_last && BufferUtil.isEmpty(_content)) - _deflater.finish(); + _channel.getByteBufferPool().release(_copy); + _copy = null; } + return Action.SUCCEEDED; } - BufferUtil.compact(_buffer); - int off = _buffer.arrayOffset() + _buffer.limit(); - int len = _buffer.capacity() - _buffer.limit() - (_last ? 8 : 0); - if (len > 0) + // If we have no buffer + if (_buffer == null) { + // allocate a buffer and add the gzip header + _buffer = _channel.getByteBufferPool().acquire(_bufferSize, false); + BufferUtil.fill(_buffer, GZIP_HEADER, 0, GZIP_HEADER.length); + } + else + { + // otherwise clear the buffer as previous writes will always fully consume. + BufferUtil.clear(_buffer); + } + + // If the deflator is not finished, then compress more data + if (!_deflater.finished()) + { + if (_deflater.needsInput()) + { + // if there is no more content available to compress + // then we are either finished all content or just the current write. + if (BufferUtil.isEmpty(_content)) + { + if (_last) + _deflater.finish(); + else + return Action.SUCCEEDED; + } + else + { + // If there is more content available to compress, we have to make sure + // it is available in an array for the current deflator API, maybe slicing + // of content. + ByteBuffer slice; + if (_content.hasArray()) + slice = _content; + else + { + if (_copy == null) + _copy = _channel.getByteBufferPool().acquire(_bufferSize, false); + else + BufferUtil.clear(_copy); + slice = _copy; + BufferUtil.append(_copy, _content); + } + + // transfer the data from the slice to the the deflator + byte[] array = slice.array(); + int off = slice.arrayOffset() + slice.position(); + int len = slice.remaining(); + _crc.update(array, off, len); + _deflater.setInput(array, off, len); // TODO use ByteBuffer API in Jetty-10 + slice.position(slice.position() + len); + if (_last && BufferUtil.isEmpty(_content)) + _deflater.finish(); + } + } + + // deflate the content into the available space in the buffer + int off = _buffer.arrayOffset() + _buffer.limit(); + int len = BufferUtil.space(_buffer); int produced = _deflater.deflate(_buffer.array(), off, len, _syncFlush ? Deflater.SYNC_FLUSH : Deflater.NO_FLUSH); _buffer.limit(_buffer.limit() + produced); } - boolean finished = _deflater.finished(); - if (finished) + // If we have finished deflation and there is room for the trailer. + if (_deflater.finished() && BufferUtil.space(_buffer) >= 8) + { + // add the trailer and recycle the deflator to flag that we will have had completeSuccess when + // the write below completes. addTrailer(); + _factory.recycle(_deflater); + _deflater = null; + } - _interceptor.write(_buffer, finished, this); + // write the compressed buffer. + _interceptor.write(_buffer, _deflater == null, this); return Action.SCHEDULED; } + + @Override + public String toString() + { + return String.format("%s[content=%s last=%b copy=%s buffer=%s deflate=%s", + super.toString(), + BufferUtil.toDetailString(_content), + _last, + BufferUtil.toDetailString(_copy), + BufferUtil.toDetailString(_buffer), + _deflater, + _deflater != null && _deflater.finished() ? "(finished)" : ""); + } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/package-info.java index 6f3e13b255b..c0ab4c26fdb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java index 0e0b18baa31..bcbd95d7d0c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler.jmx; @@ -25,12 +25,12 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandlerContainer; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class AbstractHandlerMBean extends ObjectMBean { - private static final Logger LOG = Log.getLogger(AbstractHandlerMBean.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractHandlerMBean.class); public AbstractHandlerMBean(Object managedObject) { @@ -93,7 +93,7 @@ public class AbstractHandlerMBean extends ObjectMBean } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); name = context.getBaseResource().getName(); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java index e7a9b3f0a53..7032572cb65 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.handler.jmx; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/package-info.java index b4b9a8b0d34..e776cd18b1d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/package-info.java index 819ece8c1af..d6d60860a47 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractConnectorMBean.java b/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractConnectorMBean.java index a094a40f6e2..afc1203b58d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractConnectorMBean.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractConnectorMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.jmx; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/ServerMBean.java b/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/ServerMBean.java index 876c9883f29..98243c5922b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/ServerMBean.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/ServerMBean.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.jmx; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/package-info.java index 7c707a93f85..a6b90318ddc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/package-info.java index 61933a3948b..e0922dc6709 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/package-info.java index 307d4a04fe7..e1ac75e1818 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/ByteBufferRangeWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/ByteBufferRangeWriter.java index 8593fa5a94a..2ea010ddaf1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/ByteBufferRangeWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/ByteBufferRangeWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.resource; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/HttpContentRangeWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/HttpContentRangeWriter.java index 08a5c3805c6..d47247a0a66 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/HttpContentRangeWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/HttpContentRangeWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.resource; @@ -25,15 +25,15 @@ import java.nio.channels.SeekableByteChannel; import java.util.Objects; import org.eclipse.jetty.http.HttpContent; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Range Writer selection for HttpContent */ public class HttpContentRangeWriter { - private static final Logger LOG = Log.getLogger(HttpContentRangeWriter.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpContentRangeWriter.class); /** * Obtain a new RangeWriter for the supplied HttpContent. @@ -64,7 +64,7 @@ public class HttpContentRangeWriter if (channel instanceof SeekableByteChannel) { SeekableByteChannel seekableByteChannel = (SeekableByteChannel)channel; - return new SeekableByteChannelRangeWriter(seekableByteChannel); + return new SeekableByteChannelRangeWriter(seekableByteChannel, () -> (SeekableByteChannel)content.getReadableByteChannel()); } if (LOG.isDebugEnabled()) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/InputStreamRangeWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/InputStreamRangeWriter.java index d2bc2eaf8c9..198f0212164 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/InputStreamRangeWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/InputStreamRangeWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.resource; @@ -43,7 +43,7 @@ public class InputStreamRangeWriter implements RangeWriter private long pos; /** - * Create InputStremRangeWriter + * Create InputStreamRangeWriter * * @param inputStreamSupplier Supplier of the InputStream. If the stream needs to be regenerated, such as the next * requested range being before the current position, then the current InputStream is closed and a new one obtained diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/RangeWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/RangeWriter.java index 80cb9c6b606..2c2945be1fb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/RangeWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/RangeWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.resource; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/SeekableByteChannelRangeWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/SeekableByteChannelRangeWriter.java index 3388191c611..9ea6c4df73d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/resource/SeekableByteChannelRangeWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/resource/SeekableByteChannelRangeWriter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.resource; @@ -28,13 +28,29 @@ import org.eclipse.jetty.util.IO; public class SeekableByteChannelRangeWriter implements RangeWriter { - private final SeekableByteChannel channel; + public static final int NO_PROGRESS_LIMIT = 3; + + public interface ChannelSupplier + { + SeekableByteChannel newSeekableByteChannel() throws IOException; + } + + private final ChannelSupplier channelSupplier; private final int bufSize; private final ByteBuffer buffer; + private SeekableByteChannel channel; + private long pos; + private boolean defaultSeekMode = true; - public SeekableByteChannelRangeWriter(SeekableByteChannel seekableByteChannel) + public SeekableByteChannelRangeWriter(SeekableByteChannelRangeWriter.ChannelSupplier channelSupplier) { - this.channel = seekableByteChannel; + this(null, channelSupplier); + } + + public SeekableByteChannelRangeWriter(SeekableByteChannel initialChannel, SeekableByteChannelRangeWriter.ChannelSupplier channelSupplier) + { + this.channel = initialChannel; + this.channelSupplier = channelSupplier; this.bufSize = IO.bufferSize; this.buffer = BufferUtil.allocate(this.bufSize); } @@ -42,13 +58,16 @@ public class SeekableByteChannelRangeWriter implements RangeWriter @Override public void close() throws IOException { - this.channel.close(); + if (this.channel != null) + { + this.channel.close(); + } } @Override public void writeTo(OutputStream outputStream, long skipTo, long length) throws IOException { - this.channel.position(skipTo); + skipTo(skipTo); // copy from channel to output stream long readTotal = 0; @@ -61,6 +80,87 @@ public class SeekableByteChannelRangeWriter implements RangeWriter BufferUtil.flipToFlush(buffer, 0); BufferUtil.writeTo(buffer, outputStream); readTotal += readLen; + pos += readLen; + } + } + + private void skipTo(long skipTo) throws IOException + { + if (channel == null) + { + channel = channelSupplier.newSeekableByteChannel(); + pos = 0; + } + + if (defaultSeekMode) + { + try + { + if (channel.position() != skipTo) + { + channel.position(skipTo); + pos = skipTo; + return; + } + } + catch (UnsupportedOperationException e) + { + defaultSeekMode = false; + fallbackSkipTo(skipTo); + } + } + else + { + // Fallback mode + fallbackSkipTo(skipTo); + } + } + + private void fallbackSkipTo(long skipTo) throws IOException + { + if (skipTo < pos) + { + channel.close(); + channel = channelSupplier.newSeekableByteChannel(); + pos = 0; + } + + if (pos < skipTo) + { + long skipSoFar = pos; + long actualSkipped; + int noProgressLoopLimit = NO_PROGRESS_LIMIT; + // loop till we reach desired point, break out on lack of progress. + while (noProgressLoopLimit > 0 && skipSoFar < skipTo) + { + BufferUtil.clearToFill(buffer); + int len = (int)Math.min(bufSize, (skipTo - skipSoFar)); + buffer.limit(len); + actualSkipped = channel.read(buffer); + if (actualSkipped == 0) + { + noProgressLoopLimit--; + } + else if (actualSkipped > 0) + { + skipSoFar += actualSkipped; + noProgressLoopLimit = NO_PROGRESS_LIMIT; + } + else + { + // negative values means the stream was closed or reached EOF + // either way, we've hit a state where we can no longer + // fulfill the requested range write. + throw new IOException("EOF reached before SeekableByteChannel skip destination"); + } + } + + if (noProgressLoopLimit <= 0) + { + throw new IOException("No progress made to reach SeekableByteChannel skip position " + (skipTo - pos)); + } + + pos = skipTo; } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCache.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCache.java index 62830cd60fe..a50daf4e2d8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCache.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCache.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -21,15 +21,17 @@ package org.eclipse.jetty.server.session; import java.util.Collections; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Locker.Lock; +import org.eclipse.jetty.util.thread.AutoLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractSessionCache @@ -53,7 +55,7 @@ import org.eclipse.jetty.util.thread.Locker.Lock; @ManagedObject public abstract class AbstractSessionCache extends ContainerLifeCycle implements SessionCache { - static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(AbstractSessionCache.class); /** * The authoritative source of session data @@ -91,6 +93,12 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements * deleted from the SessionDataStore. */ protected boolean _removeUnloadableSessions; + + /** + * If true, when a response is about to be committed back to the client, + * a dirty session will be flushed to the session store. + */ + protected boolean _flushOnResponseCommit; /** * Create a new Session object from pre-existing session data @@ -111,34 +119,13 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements public abstract Session newSession(HttpServletRequest request, SessionData data); /** - * @see org.eclipse.jetty.server.session.SessionCache#newSession(javax.servlet.http.HttpServletRequest, java.lang.String, long, long) - */ - @Override - public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs) - { - if (LOG.isDebugEnabled()) - LOG.debug("Creating new session id=" + id); - Session session = newSession(request, _sessionDataStore.newSessionData(id, time, time, time, maxInactiveMs)); - session.getSessionData().setLastNode(_context.getWorkerName()); - try - { - if (isSaveOnCreate() && _sessionDataStore != null) - _sessionDataStore.store(id, session.getSessionData()); - } - catch (Exception e) - { - LOG.warn("Save of new session {} failed", id, e); - } - return session; - } - - /** - * Get the session matching the key + * Get the session matching the key from the cache. Does not load + * the session. * * @param id session id * @return the Session object matching the id */ - public abstract Session doGet(String id); + protected abstract Session doGet(String id); /** * Put the session into the map if it wasn't already there @@ -147,7 +134,19 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements * @param session the session object * @return null if the session wasn't already in the map, or the existing entry otherwise */ - public abstract Session doPutIfAbsent(String id, Session session); + protected abstract Session doPutIfAbsent(String id, Session session); + + /** + * Compute the mappingFunction to create a Session object iff the session + * with the given id isn't already in the map, otherwise return the existing Session. + * This method is expected to have precisely the same behaviour as + * {@link java.util.concurrent.ConcurrentHashMap#computeIfAbsent} + * + * @param id the session id + * @param mappingFunction the function to load the data for the session + * @return an existing Session from the cache + */ + protected abstract Session doComputeIfAbsent(String id, Function mappingFunction); /** * Replace the mapping from id to oldValue with newValue @@ -157,7 +156,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements * @param newValue the new value * @return true if replacement was done */ - public abstract boolean doReplace(String id, Session oldValue, Session newValue); + protected abstract boolean doReplace(String id, Session oldValue, Session newValue); /** * Remove the session with this identity from the store @@ -167,22 +166,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements */ public abstract Session doDelete(String id); - /** - * PlaceHolder - */ - protected class PlaceHolderSession extends Session - { - - /** - * @param handler SessionHandler to which this session belongs - * @param data the session data - */ - public PlaceHolderSession(SessionHandler handler, SessionData data) - { - super(handler, data); - } - } - /** * @param handler the {@link SessionHandler} to use */ @@ -200,9 +183,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements return _handler; } - /** - * @see org.eclipse.jetty.server.session.SessionCache#initialize(org.eclipse.jetty.server.session.SessionContext) - */ @Override public void initialize(SessionContext context) { @@ -211,9 +191,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements _context = context; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -230,9 +207,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements super.doStart(); } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -249,9 +223,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements return _sessionDataStore; } - /** - * @see org.eclipse.jetty.server.session.SessionCache#setSessionDataStore(org.eclipse.jetty.server.session.SessionDataStore) - */ @Override public void setSessionDataStore(SessionDataStore sessionStore) { @@ -317,119 +288,99 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements _removeUnloadableSessions = removeUnloadableSessions; } + @Override + public void setFlushOnResponseCommit(boolean flushOnResponseCommit) + { + _flushOnResponseCommit = flushOnResponseCommit; + } + + @Override + public boolean isFlushOnResponseCommit() + { + return _flushOnResponseCommit; + } + /** * Get a session object. * * If the session object is not in this session store, try getting * the data for it from a SessionDataStore associated with the - * session manager. + * session manager. The usage count of the session is incremented. * * @see org.eclipse.jetty.server.session.SessionCache#get(java.lang.String) */ @Override public Session get(String id) throws Exception + { + return getAndEnter(id, true); + } + + /** Get a session object. + * + * If the session object is not in this session store, try getting + * the data for it from a SessionDataStore associated with the + * session manager. + * + * @param id The session to retrieve + * @param enter if true, the usage count of the session will be incremented + * @return the session if it exists, null otherwise + * @throws Exception if the session cannot be loaded + */ + protected Session getAndEnter(String id, boolean enter) throws Exception { Session session = null; - Exception ex = null; + AtomicReference exception = new AtomicReference(); - while (true) + session = doComputeIfAbsent(id, k -> { - session = doGet(id); + if (LOG.isDebugEnabled()) + LOG.debug("Session {} not found locally in {}, attempting to load", id, this); - if (_sessionDataStore == null) - break; //can't load any session data so just return null or the session object - - if (session == null) + try { - if (LOG.isDebugEnabled()) - LOG.debug("Session {} not found locally, attempting to load", id); - - //didn't get a session, try and create one and put in a placeholder for it - PlaceHolderSession phs = new PlaceHolderSession(_handler, new SessionData(id, null, null, 0, 0, 0, 0)); - Lock phsLock = phs.lock(); - Session s = doPutIfAbsent(id, phs); - if (s == null) + Session s = loadSession(k); + if (s != null) { - //My placeholder won, go ahead and load the full session data - try + try (AutoLock lock = s.lock()) { - session = loadSession(id); - if (session == null) - { - //session does not exist, remove the placeholder - doDelete(id); - phsLock.close(); - break; - } - - try (Lock lock = session.lock()) - { - //swap it in instead of the placeholder - boolean success = doReplace(id, phs, session); - if (!success) - { - //something has gone wrong, it should have been our placeholder - doDelete(id); - session = null; - LOG.warn("Replacement of placeholder for session {} failed", id); - phsLock.close(); - break; - } - else - { - //successfully swapped in the session - session.setResident(true); - phsLock.close(); - break; - } - } - } - catch (Exception e) - { - ex = e; //remember a problem happened loading the session - doDelete(id); //remove the placeholder - phsLock.close(); - session = null; - break; + s.setResident(true); //ensure freshly loaded session is resident } } else { - //my placeholder didn't win, check the session returned - phsLock.close(); - try (Lock lock = s.lock()) - { - //is it a placeholder? or is a non-resident session? In both cases, chuck it away and start again - if (!s.isResident() || s instanceof PlaceHolderSession) - { - session = null; - continue; - } - session = s; - break; - } + if (LOG.isDebugEnabled()) + LOG.debug("Session {} not loaded by store", id); } + return s; } - else + catch (Exception e) { - //check the session returned - try (Lock lock = session.lock()) - { - //is it a placeholder? or is it passivated? In both cases, chuck it away and start again - if (!session.isResident() || session instanceof PlaceHolderSession) - { - session = null; - continue; - } + exception.set(e); + return null; + } + }); - //got the session - break; + Exception ex = exception.get(); + if (ex != null) + throw ex; + + if (session != null) + { + try (AutoLock lock = session.lock()) + { + if (!session.isResident()) //session isn't marked as resident in cache + { + if (LOG.isDebugEnabled()) + LOG.debug("Non-resident session {} in cache", id); + return null; + } + else if (enter) + { + session.use(); } } } - if (ex != null) - throw ex; return session; } @@ -469,7 +420,84 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements } /** - * Put the Session object back into the session store. + * Add an entirely new session (created by the application calling Request.getSession(true)) + * to the cache. The usage count of the fresh session is incremented. + * + * @param id the id + * @param session + */ + @Override + public void add(String id, Session session) throws Exception + { + if (id == null || session == null) + throw new IllegalArgumentException("Add key=" + id + " session=" + (session == null ? "null" : session.getId())); + + try (AutoLock lock = session.lock()) + { + if (session.getSessionHandler() == null) + throw new IllegalStateException("Session " + id + " is not managed"); + + if (!session.isValid()) + throw new IllegalStateException("Session " + id + " is not valid"); + + if (doPutIfAbsent(id, session) == null) + { + session.setResident(true); //its in the cache + session.use(); //the request is using it + } + else + throw new IllegalStateException("Session " + id + " already in cache"); + } + } + + /** + * A response that has accessed this session is about to + * be returned to the client. Pass the session to the store + * to persist, so that any changes will be visible to + * subsequent requests on the same node (if using NullSessionCache), + * or on other nodes. + */ + @Override + public void commit(Session session) throws Exception + { + if (session == null) + return; + + try (AutoLock lock = session.lock()) + { + //only write the session out at this point if the attributes changed. If only + //the lastAccess/expiry time changed defer the write until the last request exits + if (session.getSessionData().isDirty() && _flushOnResponseCommit) + { + if (LOG.isDebugEnabled()) + LOG.debug("Flush session {} on response commit", session); + //save the session + if (!_sessionDataStore.isPassivating()) + { + _sessionDataStore.store(session.getId(), session.getSessionData()); + } + else + { + session.willPassivate(); + _sessionDataStore.store(session.getId(), session.getSessionData()); + session.didActivate(); + } + } + } + } + + /** + * @deprecated use {@link #release(String, Session)} instead + */ + @Override + @Deprecated + public void put(String id, Session session) throws Exception + { + release(id, session); + } + + /** + * Finish using the Session object. * * This should be called when a request exists the session. Only when the last * simultaneous request exists the session will any action be taken. @@ -481,22 +509,24 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements * If the evictionPolicy == SessionCache.EVICT_ON_SESSION_EXIT then after we have saved * the session, we evict it from the cache. * - * @see org.eclipse.jetty.server.session.SessionCache#put(java.lang.String, org.eclipse.jetty.server.session.Session) + * @see org.eclipse.jetty.server.session.SessionCache#release(java.lang.String, org.eclipse.jetty.server.session.Session) */ @Override - public void put(String id, Session session) throws Exception + public void release(String id, Session session) throws Exception { if (id == null || session == null) throw new IllegalArgumentException("Put key=" + id + " session=" + (session == null ? "null" : session.getId())); - try (Lock lock = session.lock()) + try (AutoLock lock = session.lock()) { if (session.getSessionHandler() == null) throw new IllegalStateException("Session " + id + " is not managed"); - if (!session.isValid()) + if (session.isInvalid()) return; + session.complete(); + //don't do anything with the session until the last request for it has finished if ((session.getRequests() <= 0)) { @@ -575,7 +605,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements Session s = doGet(id); if (s != null) { - try (Lock lock = s.lock()) + try (AutoLock lock = s.lock()) { //wait for the lock and check the validity of the session return s.isValid(); @@ -608,7 +638,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements public Session delete(String id) throws Exception { //get the session, if its not in memory, this will load it - Session session = get(id); + Session session = getAndEnter(id, false); //Always delete it from the backing data store if (_sessionDataStore != null) @@ -627,9 +657,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements return doDelete(id); } - /** - * @see org.eclipse.jetty.server.session.SessionCache#checkExpiration(Set) - */ @Override public Set checkExpiration(Set candidates) { @@ -677,9 +704,10 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements if (LOG.isDebugEnabled()) LOG.debug("Checking for idle {}", session.getId()); - try (Lock s = session.lock()) + try (AutoLock s = session.lock()) { - if (getEvictionPolicy() > 0 && session.isIdleLongerThan(getEvictionPolicy()) && session.isValid() && session.isResident() && session.getRequests() <= 0) + if (getEvictionPolicy() > 0 && session.isIdleLongerThan(getEvictionPolicy()) && + session.isValid() && session.isResident() && session.getRequests() <= 0) { //Be careful with saveOnInactiveEviction - you may be able to re-animate a session that was //being managed on another node and has expired. @@ -694,6 +722,8 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements if (_sessionDataStore.isPassivating()) session.willPassivate(); + //Fake being dirty to force the write + session.getSessionData().setDirty(true); _sessionDataStore.store(session.getId(), session.getSessionData()); } @@ -703,7 +733,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements catch (Exception e) { LOG.warn("Passivation of idle session {} failed", session.getId(), e); - //session.updateInactivityTimer(); } } } @@ -718,7 +747,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements if (StringUtil.isBlank(newId)) throw new IllegalArgumentException("New session id is null"); - Session session = get(oldId); + Session session = getAndEnter(oldId, true); renewSessionId(session, newId, newExtendedId); return session; @@ -738,9 +767,9 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements if (session == null) return; - try (Lock lock = session.lock()) + try (AutoLock lock = session.lock()) { - final String oldId = session.getId(); + String oldId = session.getId(); session.checkValidForWrite(); //can't change id on invalid session session.getSessionData().setId(newId); session.getSessionData().setLastSaved(0); //pretend that the session has never been saved before to get a full save @@ -761,9 +790,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements } } - /** - * @see org.eclipse.jetty.server.session.SessionCache#setSaveOnInactiveEviction(boolean) - */ @Override public void setSaveOnInactiveEviction(boolean saveOnEvict) { @@ -783,10 +809,30 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements return _saveOnInactiveEviction; } + @Override + public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs) + { + if (LOG.isDebugEnabled()) + LOG.debug("Creating new session id=" + id); + Session session = newSession(request, _sessionDataStore.newSessionData(id, time, time, time, maxInactiveMs)); + session.getSessionData().setLastNode(_context.getWorkerName()); + try + { + if (isSaveOnCreate() && _sessionDataStore != null) + _sessionDataStore.store(id, session.getSessionData()); + } + catch (Exception e) + { + LOG.warn("Save of new session {} failed", id, e); + } + return session; + } + @Override public String toString() { return String.format("%s@%x[evict=%d,removeUnloadable=%b,saveOnCreate=%b,saveOnInactiveEvict=%b]", - this.getClass().getName(), this.hashCode(), _evictionPolicy, _removeUnloadableSessions, _saveOnCreate, _saveOnInactiveEviction); + this.getClass().getName(), this.hashCode(), _evictionPolicy, + _removeUnloadableSessions, _saveOnCreate, _saveOnInactiveEviction); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCacheFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCacheFactory.java new file mode 100644 index 00000000000..92bfb93f844 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionCacheFactory.java @@ -0,0 +1,114 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +/** + * AbstractSessionCacheFactory + * + * Base class for SessionCacheFactories. + * + */ +public abstract class AbstractSessionCacheFactory implements SessionCacheFactory +{ + int _evictionPolicy; + boolean _saveOnInactiveEvict; + boolean _saveOnCreate; + boolean _removeUnloadableSessions; + boolean _flushOnResponseCommit; + + /** + * @return the flushOnResponseCommit + */ + public boolean isFlushOnResponseCommit() + { + return _flushOnResponseCommit; + } + + /** + * @param flushOnResponseCommit the flushOnResponseCommit to set + */ + public void setFlushOnResponseCommit(boolean flushOnResponseCommit) + { + _flushOnResponseCommit = flushOnResponseCommit; + } + + /** + * @return the saveOnCreate + */ + public boolean isSaveOnCreate() + { + return _saveOnCreate; + } + + /** + * @param saveOnCreate the saveOnCreate to set + */ + public void setSaveOnCreate(boolean saveOnCreate) + { + _saveOnCreate = saveOnCreate; + } + + /** + * @return the removeUnloadableSessions + */ + public boolean isRemoveUnloadableSessions() + { + return _removeUnloadableSessions; + } + + /** + * @param removeUnloadableSessions the removeUnloadableSessions to set + */ + public void setRemoveUnloadableSessions(boolean removeUnloadableSessions) + { + _removeUnloadableSessions = removeUnloadableSessions; + } + + /** + * @return the evictionPolicy + */ + public int getEvictionPolicy() + { + return _evictionPolicy; + } + + /** + * @param evictionPolicy the evictionPolicy to set + */ + public void setEvictionPolicy(int evictionPolicy) + { + _evictionPolicy = evictionPolicy; + } + + /** + * @return the saveOnInactiveEvict + */ + public boolean isSaveOnInactiveEvict() + { + return _saveOnInactiveEvict; + } + + /** + * @param saveOnInactiveEvict the saveOnInactiveEvict to set + */ + public void setSaveOnInactiveEvict(boolean saveOnInactiveEvict) + { + _saveOnInactiveEvict = saveOnInactiveEvict; + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java index b89ba6c060b..cf066e2a7d2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -25,8 +25,8 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AbstractSessionDataStore @@ -34,7 +34,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public abstract class AbstractSessionDataStore extends ContainerLifeCycle implements SessionDataStore { - static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(AbstractSessionDataStore.class); protected SessionContext _context; //context associated with this session data store protected int _gracePeriodSec = 60 * 60; //default of 1hr @@ -80,22 +80,21 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem @Override public SessionData load(String id) throws Exception { + if (!isStarted()) + throw new IllegalStateException("Not started"); + final AtomicReference reference = new AtomicReference(); final AtomicReference exception = new AtomicReference(); - Runnable r = new Runnable() + Runnable r = () -> { - @Override - public void run() + try { - try - { - reference.set(doLoad(id)); - } - catch (Exception e) - { - exception.set(e); - } + reference.set(doLoad(id)); + } + catch (Exception e) + { + exception.set(e); } }; @@ -109,6 +108,9 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem @Override public void store(String id, SessionData data) throws Exception { + if (!isStarted()) + throw new IllegalStateException("Not started"); + if (data == null) return; @@ -123,10 +125,14 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem long savePeriodMs = (_savePeriodSec <= 0 ? 0 : TimeUnit.SECONDS.toMillis(_savePeriodSec)); if (LOG.isDebugEnabled()) - LOG.debug("Store: id={}, dirty={}, lsave={}, period={}, elapsed={}", id, data.isDirty(), data.getLastSaved(), savePeriodMs, (System.currentTimeMillis() - lastSave)); + { + LOG.debug("Store: id={}, mdirty={}, dirty={}, lsave={}, period={}, elapsed={}", id, data.isMetaDataDirty(), + data.isDirty(), data.getLastSaved(), savePeriodMs, (System.currentTimeMillis() - lastSave)); + } - //save session if attribute changed or never been saved or time between saves exceeds threshold - if (data.isDirty() || (lastSave <= 0) || ((System.currentTimeMillis() - lastSave) > savePeriodMs)) + //save session if attribute changed, never been saved or metadata changed (eg expiry time) and save interval exceeded + if (data.isDirty() || (lastSave <= 0) || + (data.isMetaDataDirty() && ((System.currentTimeMillis() - lastSave) >= savePeriodMs))) { //set the last saved time to now data.setLastSaved(System.currentTimeMillis()); @@ -134,7 +140,7 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem { //call the specific store method, passing in previous save time doStore(id, data, lastSave); - data.setDirty(false); //only undo the dirty setting if we saved it + data.clean(); //unset all dirty flags } catch (Exception e) { @@ -156,6 +162,9 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem @Override public Set getExpired(Set candidates) { + if (!isStarted()) + throw new IllegalStateException("Not started"); + try { return doGetExpired(candidates); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreFactory.java index 3d8ed3add84..0042772e6d1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java index eed82269dac..b6c10595b4b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -21,8 +21,8 @@ package org.eclipse.jetty.server.session; import java.util.Set; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * CachingSessionDataStore @@ -44,7 +44,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class CachingSessionDataStore extends ContainerLifeCycle implements SessionDataStore { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(CachingSessionDataStore.class); /** * The actual store for the session data */ @@ -83,9 +83,6 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi return _cache; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String) - */ @Override public SessionData load(String id) throws Exception { @@ -98,7 +95,7 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to load id {}", id, e); } if (d != null) @@ -110,9 +107,6 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi return d; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String) - */ @Override public boolean delete(String id) throws Exception { @@ -124,9 +118,6 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi return deleted; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set) - */ @Override public Set getExpired(Set candidates) { @@ -134,9 +125,6 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi return _store.getExpired(candidates); } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData) - */ @Override public void store(String id, SessionData data) throws Exception { @@ -162,18 +150,12 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi super.doStop(); } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating() - */ @Override public boolean isPassivating() { return _store.isPassivating(); } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) - */ @Override public boolean exists(String id) throws Exception { @@ -186,16 +168,13 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable test exists on {}", id, e); } //then the delegate store return _store.exists(id); } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#initialize(org.eclipse.jetty.server.session.SessionContext) - */ @Override public void initialize(SessionContext context) throws Exception { @@ -204,9 +183,6 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi _cache.initialize(context); } - /** - * @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(java.lang.String, long, long, long, long) - */ @Override public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStoreFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStoreFactory.java index e1a22b36599..0236e5e6fd2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStoreFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -56,9 +56,6 @@ public class CachingSessionDataStoreFactory extends AbstractSessionDataStoreFact _sessionStoreFactory = factory; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java index b01556c4034..1a587bf31fd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -33,8 +33,8 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DatabaseAdaptor @@ -47,7 +47,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class DatabaseAdaptor { - static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + static final Logger LOG = LoggerFactory.getLogger(DatabaseAdaptor.class); String _dbName; boolean _isLower; @@ -305,9 +305,6 @@ public class DatabaseAdaptor return DriverManager.getConnection(_connectionUrl); } - /** - * @see java.lang.Object#toString() - */ @Override public String toString() { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCache.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCache.java index ef00dd46edf..aebc561d1ae 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCache.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCache.java @@ -1,32 +1,33 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.CounterStatistic; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DefaultSessionCache @@ -36,7 +37,7 @@ import org.eclipse.jetty.util.statistic.CounterStatistic; @ManagedObject public class DefaultSessionCache extends AbstractSessionCache { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(DefaultSessionCache.class); /** * The cache of sessions in a hashmap @@ -80,18 +81,12 @@ public class DefaultSessionCache extends AbstractSessionCache return _stats.getTotal(); } - /** - * - */ @ManagedOperation(value = "reset statistics", impact = "ACTION") public void resetStats() { _stats.reset(); } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doGet(java.lang.String) - */ @Override public Session doGet(String id) { @@ -103,26 +98,32 @@ public class DefaultSessionCache extends AbstractSessionCache return session; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session) - */ @Override public Session doPutIfAbsent(String id, Session session) { Session s = _sessions.putIfAbsent(id, session); - if (s == null && !(session instanceof PlaceHolderSession)) + if (s == null) _stats.increment(); return s; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doDelete(java.lang.String) - */ + @Override + protected Session doComputeIfAbsent(String id, Function mappingFunction) + { + return _sessions.computeIfAbsent(id, k -> + { + Session s = mappingFunction.apply(k); + if (s != null) + _stats.increment(); + return s; + }); + } + @Override public Session doDelete(String id) { Session s = _sessions.remove(id); - if (s != null && !(s instanceof PlaceHolderSession)) + if (s != null) _stats.decrement(); return s; } @@ -147,7 +148,7 @@ public class DefaultSessionCache extends AbstractSessionCache } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to store {}", session, e); } doDelete(session.getId()); //remove from memory session.setResident(false); @@ -161,16 +162,13 @@ public class DefaultSessionCache extends AbstractSessionCache } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } } } } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData) - */ @Override public Session newSession(HttpServletRequest request, SessionData data) { @@ -178,9 +176,6 @@ public class DefaultSessionCache extends AbstractSessionCache return s; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(org.eclipse.jetty.server.session.SessionData) - */ @Override public Session newSession(SessionData data) { @@ -188,15 +183,10 @@ public class DefaultSessionCache extends AbstractSessionCache return s; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session) - */ @Override public boolean doReplace(String id, Session oldValue, Session newValue) { boolean result = _sessions.replace(id, oldValue, newValue); - if (result && (oldValue instanceof PlaceHolderSession)) - _stats.increment(); return result; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCacheFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCacheFactory.java index b1261647414..3e629745086 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCacheFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionCacheFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -23,80 +23,8 @@ package org.eclipse.jetty.server.session; * * Factory for creating new DefaultSessionCaches. */ -public class DefaultSessionCacheFactory implements SessionCacheFactory +public class DefaultSessionCacheFactory extends AbstractSessionCacheFactory { - int _evictionPolicy; - boolean _saveOnInactiveEvict; - boolean _saveOnCreate; - boolean _removeUnloadableSessions; - - /** - * @return the saveOnCreate - */ - public boolean isSaveOnCreate() - { - return _saveOnCreate; - } - - /** - * @param saveOnCreate the saveOnCreate to set - */ - public void setSaveOnCreate(boolean saveOnCreate) - { - _saveOnCreate = saveOnCreate; - } - - /** - * @return the removeUnloadableSessions - */ - public boolean isRemoveUnloadableSessions() - { - return _removeUnloadableSessions; - } - - /** - * @param removeUnloadableSessions the removeUnloadableSessions to set - */ - public void setRemoveUnloadableSessions(boolean removeUnloadableSessions) - { - _removeUnloadableSessions = removeUnloadableSessions; - } - - /** - * @return the evictionPolicy - */ - public int getEvictionPolicy() - { - return _evictionPolicy; - } - - /** - * @param evictionPolicy the evictionPolicy to set - */ - public void setEvictionPolicy(int evictionPolicy) - { - _evictionPolicy = evictionPolicy; - } - - /** - * @return the saveOnInactiveEvict - */ - public boolean isSaveOnInactiveEvict() - { - return _saveOnInactiveEvict; - } - - /** - * @param saveOnInactiveEvict the saveOnInactiveEvict to set - */ - public void setSaveOnInactiveEvict(boolean saveOnInactiveEvict) - { - _saveOnInactiveEvict = saveOnInactiveEvict; - } - - /** - * @see org.eclipse.jetty.server.session.SessionCacheFactory#getSessionCache(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionCache getSessionCache(SessionHandler handler) { @@ -105,6 +33,7 @@ public class DefaultSessionCacheFactory implements SessionCacheFactory cache.setSaveOnInactiveEviction(isSaveOnInactiveEvict()); cache.setSaveOnCreate(isSaveOnCreate()); cache.setRemoveUnloadableSessions(isRemoveUnloadableSessions()); + cache.setFlushOnResponseCommit(isFlushOnResponseCommit()); return cache; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java index 688340ddc3b..b59836fc5f1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -32,8 +32,8 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DefaultSessionIdManager @@ -50,7 +50,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public class DefaultSessionIdManager extends ContainerLifeCycle implements SessionIdManager { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(DefaultSessionIdManager.class); public static final String __NEW_SESSION_ID = "org.eclipse.jetty.server.newSessionId"; @@ -274,9 +274,6 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi return id; } - /** - * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String) - */ @Override public boolean isIdInUse(String id) { @@ -301,7 +298,7 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi } if (LOG.isDebugEnabled()) - LOG.debug("Checked {}, in use:", id, inUse); + LOG.debug("Checked {}, in use: {}", id, inUse); return inUse; } catch (Exception e) @@ -311,9 +308,6 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi } } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -343,9 +337,6 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi _houseKeeper.start(); } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -467,9 +458,9 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi } /** - * Get SessionManager for every context. + * Get SessionHandler for every context. * - * @return all session managers + * @return all SessionHandlers that are running */ @Override public Set getSessionHandlers() @@ -480,15 +471,13 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi { for (Handler h : tmp) { - handlers.add((SessionHandler)h); + if (h.isStarted()) + handlers.add((SessionHandler)h); } } return handlers; } - /** - * @see java.lang.Object#toString() - */ @Override public String toString() { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java index b0f9c7df8af..ee2201af200 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -41,8 +41,8 @@ import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * FileSessionDataStore @@ -52,7 +52,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public class FileSessionDataStore extends AbstractSessionDataStore { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(FileSessionDataStore.class); protected File _storeDir; protected boolean _deleteUnrestorableFiles = false; protected Map _sessionFileMap = new ConcurrentHashMap<>(); @@ -166,7 +166,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get expired for {}", filename, e); } } @@ -220,13 +220,13 @@ public class FileSessionDataStore extends AbstractSessionDataStore } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to sweep file {}", p, e); } }); } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to walk path {}", _storeDir, e); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStoreFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStoreFactory.java index 73ae2681a07..2f386528d76 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStoreFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -60,9 +60,6 @@ public class FileSessionDataStoreFactory extends AbstractSessionDataStoreFactory _storeDir = storeDir; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HouseKeeper.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HouseKeeper.java index fcb8f6ec75c..3179e7771f5 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HouseKeeper.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HouseKeeper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -24,10 +24,10 @@ import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * HouseKeeper @@ -37,7 +37,7 @@ import org.eclipse.jetty.util.thread.Scheduler; @ManagedObject public class HouseKeeper extends AbstractLifeCycle { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(HouseKeeper.class); public static final long DEFAULT_PERIOD_MS = 1000L * 60 * 10; protected SessionIdManager _sessionIdManager; @@ -78,9 +78,6 @@ public class HouseKeeper extends AbstractLifeCycle _sessionIdManager = sessionIdManager; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -158,8 +155,9 @@ public class HouseKeeper extends AbstractLifeCycle LOG.info("{} Stopped scavenging", _sessionIdManager.getWorkerName()); } _task = null; - if (_ownScheduler) + if (_ownScheduler && _scheduler != null) { + _ownScheduler = false; _scheduler.stop(); _scheduler = null; } @@ -167,9 +165,6 @@ public class HouseKeeper extends AbstractLifeCycle _runner = null; } - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -257,15 +252,12 @@ public class HouseKeeper extends AbstractLifeCycle } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to scavenge", e); } } } } - /** - * @see java.lang.Object#toString() - */ @Override public String toString() { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java index 155ada9009e..248eec4402a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -35,8 +35,8 @@ import org.eclipse.jetty.util.ClassLoadingObjectInputStream; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JDBCSessionDataStore @@ -46,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public class JDBCSessionDataStore extends AbstractSessionDataStore { - static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(JDBCSessionDataStore.class); /** * Used for Oracle and other databases where "" is treated as NULL @@ -58,6 +58,8 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore protected SessionTableSchema _sessionTableSchema; protected boolean _schemaProvided; + private static final ByteArrayInputStream EMPTY = new ByteArrayInputStream(new byte[0]); + /** * SessionTableSchema */ @@ -707,17 +709,24 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore statement.setLong(10, data.getExpiry()); statement.setLong(11, data.getMaxInactiveMs()); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos)) + if (!data.getAllAttributes().isEmpty()) { - SessionData.serializeAttributes(data, oos); - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob - statement.executeUpdate(); - if (LOG.isDebugEnabled()) - LOG.debug("Inserted session " + data); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos)) + { + SessionData.serializeAttributes(data, oos); + byte[] bytes = baos.toByteArray(); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob + } } + else + { + statement.setBinaryStream(12, EMPTY, 0); + } + statement.executeUpdate(); + if (LOG.isDebugEnabled()) + LOG.debug("Inserted session " + data); } } } @@ -737,20 +746,27 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore statement.setLong(5, data.getExpiry()); statement.setLong(6, data.getMaxInactiveMs()); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos)) + if (!data.getAllAttributes().isEmpty()) { - SessionData.serializeAttributes(data, oos); - byte[] bytes = baos.toByteArray(); - try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos)) { - statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob - statement.executeUpdate(); - - if (LOG.isDebugEnabled()) - LOG.debug("Updated session " + data); + SessionData.serializeAttributes(data, oos); + byte[] bytes = baos.toByteArray(); + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) + { + statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob + } } } + else + { + statement.setBinaryStream(7, EMPTY, 0); + } + statement.executeUpdate(); + + if (LOG.isDebugEnabled()) + LOG.debug("Updated session " + data); } } } @@ -859,7 +875,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get expired sessions", e); return expiredSessionKeys; //return whatever we got } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreFactory.java index c51d2092bb7..14a903f0cc1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -34,9 +34,6 @@ public class JDBCSessionDataStoreFactory extends AbstractSessionDataStoreFactory */ JDBCSessionDataStore.SessionTableSchema _schema; - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCache.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCache.java index 5d93456dd24..437e469d61f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCache.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCache.java @@ -1,25 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; +import java.util.function.Function; import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * NullSessionCache * @@ -30,6 +34,7 @@ import javax.servlet.http.HttpServletRequest; */ public class NullSessionCache extends AbstractSessionCache { + private static final Logger LOG = LoggerFactory.getLogger(NullSessionCache.class); /** * @param handler The SessionHandler related to this SessionCache @@ -40,35 +45,23 @@ public class NullSessionCache extends AbstractSessionCache super.setEvictionPolicy(EVICT_ON_SESSION_EXIT); } - /** - * @see org.eclipse.jetty.server.session.SessionCache#shutdown() - */ @Override public void shutdown() { } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(org.eclipse.jetty.server.session.SessionData) - */ @Override public Session newSession(SessionData data) { return new Session(getSessionHandler(), data); } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData) - */ @Override public Session newSession(HttpServletRequest request, SessionData data) { return new Session(getSessionHandler(), request, data); } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doGet(java.lang.String) - */ @Override public Session doGet(String id) { @@ -76,9 +69,6 @@ public class NullSessionCache extends AbstractSessionCache return null; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session) - */ @Override public Session doPutIfAbsent(String id, Session session) { @@ -86,9 +76,6 @@ public class NullSessionCache extends AbstractSessionCache return null; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session) - */ @Override public boolean doReplace(String id, Session oldValue, Session newValue) { @@ -96,21 +83,21 @@ public class NullSessionCache extends AbstractSessionCache return true; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#doDelete(java.lang.String) - */ @Override public Session doDelete(String id) { return null; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionCache#setEvictionPolicy(int) - */ @Override public void setEvictionPolicy(int evictionTimeout) { - LOG.warn("Ignoring eviction setting:" + evictionTimeout); + LOG.warn("Ignoring eviction setting: {}", evictionTimeout); + } + + @Override + protected Session doComputeIfAbsent(String id, Function mappingFunction) + { + return mappingFunction.apply(id); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCacheFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCacheFactory.java index 7d0886148d8..fdf31c7fe1f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCacheFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionCacheFactory.java @@ -1,74 +1,68 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * NullSessionCacheFactory * * Factory for NullSessionCaches. */ -public class NullSessionCacheFactory implements SessionCacheFactory +public class NullSessionCacheFactory extends AbstractSessionCacheFactory { - boolean _saveOnCreate; - boolean _removeUnloadableSessions; - - /** - * @return the saveOnCreate - */ - public boolean isSaveOnCreate() + private static final Logger LOG = LoggerFactory.getLogger(NullSessionCacheFactory.class); + + @Override + public int getEvictionPolicy() { - return _saveOnCreate; + return SessionCache.EVICT_ON_SESSION_EXIT; //never actually stored } - /** - * @param saveOnCreate the saveOnCreate to set - */ - public void setSaveOnCreate(boolean saveOnCreate) + @Override + public void setEvictionPolicy(int evictionPolicy) { - _saveOnCreate = saveOnCreate; + if (LOG.isDebugEnabled()) + LOG.debug("Ignoring eviction policy setting for NullSessionCaches"); } - /** - * @return the removeUnloadableSessions - */ - public boolean isRemoveUnloadableSessions() + @Override + public boolean isSaveOnInactiveEvict() { - return _removeUnloadableSessions; + return false; //never kept in cache } - /** - * @param removeUnloadableSessions the removeUnloadableSessions to set - */ - public void setRemoveUnloadableSessions(boolean removeUnloadableSessions) + @Override + public void setSaveOnInactiveEvict(boolean saveOnInactiveEvict) { - _removeUnloadableSessions = removeUnloadableSessions; + if (LOG.isDebugEnabled()) + LOG.debug("Ignoring eviction policy setting for NullSessionCaches"); } - /** - * @see org.eclipse.jetty.server.session.SessionCacheFactory#getSessionCache(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionCache getSessionCache(SessionHandler handler) { NullSessionCache cache = new NullSessionCache(handler); cache.setSaveOnCreate(isSaveOnCreate()); cache.setRemoveUnloadableSessions(isRemoveUnloadableSessions()); + cache.setFlushOnResponseCommit(isFlushOnResponseCommit()); return cache; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java index f64c88e0e2b..aac6bb07a73 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStoreFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStoreFactory.java index 919824d3b72..a8e083cdf24 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStoreFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -24,9 +24,6 @@ package org.eclipse.jetty.server.session; public class NullSessionDataStoreFactory extends AbstractSessionDataStoreFactory { - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java index 61ccb44ecd7..2ab519ca2b7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -34,15 +34,14 @@ import javax.servlet.http.HttpSessionContext; import javax.servlet.http.HttpSessionEvent; import org.eclipse.jetty.io.CyclicTimeout; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Locker; -import org.eclipse.jetty.util.thread.Locker.Lock; +import org.eclipse.jetty.util.thread.AutoLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Session * - * A heavy-weight Session object representing a HttpSession. Session objects + * A heavy-weight Session object representing an HttpSession. Session objects * relating to a context are kept in a {@link SessionCache}. The purpose of the * SessionCache is to keep the working set of Session objects in memory so that * they may be accessed quickly, and facilitate the sharing of a Session object @@ -56,7 +55,7 @@ import org.eclipse.jetty.util.thread.Locker.Lock; */ public class Session implements SessionHandler.SessionIf { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(Session.class); /** * @@ -73,21 +72,18 @@ public class Session implements SessionHandler.SessionIf VALID, INVALID, INVALIDATING, CHANGING } - ; - public enum IdState { SET, CHANGING } - ; - protected final SessionData _sessionData; // the actual data associated with // a session protected final SessionHandler _handler; // the manager of the session protected String _extendedId; // the _id plus the worker name + protected long _requests; protected boolean _idChanged; @@ -97,7 +93,7 @@ public class Session implements SessionHandler.SessionIf protected State _state = State.VALID; // state of the session:valid,invalid // or being invalidated - protected Locker _lock = new Locker(); // sync lock + protected AutoLock _lock = new AutoLock(); protected Condition _stateChangeCompleted = _lock.newCondition(); protected boolean _resident = false; protected final SessionInactivityTimer _sessionInactivityTimer; @@ -127,11 +123,12 @@ public class Session implements SessionHandler.SessionIf long now = System.currentTimeMillis(); //handle what to do with the session after the timer expired getSessionHandler().sessionInactivityTimerExpired(Session.this, now); - try (Lock lock = Session.this.lock()) + try (AutoLock lock = Session.this.lock()) { //grab the lock and check what happened to the session: if it didn't get evicted and //it hasn't expired, we need to reset the timer - if (Session.this.isResident() && Session.this.getRequests() <= 0 && Session.this.isValid() && !Session.this.isExpiredAt(now)) + if (Session.this.isResident() && Session.this.getRequests() <= 0 && Session.this.isValid() && + !Session.this.isExpiredAt(now)) { //session wasn't expired or evicted, we need to reset the timer SessionInactivityTimer.this.schedule(Session.this.calculateInactivityTimeout(now)); @@ -188,8 +185,6 @@ public class Session implements SessionHandler.SessionIf _sessionData = data; _newSession = true; _sessionData.setDirty(true); - _requests = 1; // access will not be called on this new session, but we - // are obviously in a request _sessionInactivityTimer = new SessionInactivityTimer(); } @@ -213,7 +208,7 @@ public class Session implements SessionHandler.SessionIf */ public long getRequests() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return _requests; } @@ -226,17 +221,30 @@ public class Session implements SessionHandler.SessionIf protected void cookieSet() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { _sessionData.setCookieSet(_sessionData.getAccessed()); } } + protected void use() + { + try (AutoLock lock = _lock.lock()) + { + _requests++; + + // temporarily stop the idle timer + if (LOG.isDebugEnabled()) + LOG.debug("Session {} in use, stopping timer, active requests={}", getId(), _requests); + _sessionInactivityTimer.cancel(); + } + } + protected boolean access(long time) { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { - if (!isValid()) + if (!isValid() || !isResident()) return false; _newSession = false; long lastAccessed = _sessionData.getAccessed(); @@ -248,20 +256,13 @@ public class Session implements SessionHandler.SessionIf invalidate(); return false; } - _requests++; - - // temporarily stop the idle timer - if (LOG.isDebugEnabled()) - LOG.debug("Session {} accessed, stopping timer, active requests={}", getId(), _requests); - _sessionInactivityTimer.cancel(); - return true; } } protected void complete() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { _requests--; @@ -288,7 +289,7 @@ public class Session implements SessionHandler.SessionIf */ protected boolean isExpiredAt(long time) { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return _sessionData.isExpiredAt(time); } @@ -303,7 +304,7 @@ public class Session implements SessionHandler.SessionIf protected boolean isIdleLongerThan(int sec) { long now = System.currentTimeMillis(); - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return ((_sessionData.getAccessed() + (sec * 1000)) <= now); } @@ -344,7 +345,7 @@ public class Session implements SessionHandler.SessionIf */ public void unbindValue(java.lang.String name, Object value) { - if (value != null && value instanceof HttpSessionBindingListener) + if (value instanceof HttpSessionBindingListener) ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this, name)); } @@ -357,7 +358,7 @@ public class Session implements SessionHandler.SessionIf */ public void bindValue(java.lang.String name, Object value) { - if (value != null && value instanceof HttpSessionBindingListener) + if (value instanceof HttpSessionBindingListener) ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this, name)); } @@ -366,16 +367,31 @@ public class Session implements SessionHandler.SessionIf */ public void didActivate() { - HttpSessionEvent event = new HttpSessionEvent(this); - for (Iterator iter = _sessionData.getKeys().iterator(); iter.hasNext(); ) + //A passivate listener might remove a non-serializable attribute that + //the activate listener might put back in again, which would spuriously + //set the dirty bit to true, causing another round of passivate/activate + //when the request exits. The store clears the dirty bit if it does a + //save, so ensure dirty flag is set to the value determined by the store, + //not a passivation listener. + boolean dirty = getSessionData().isDirty(); + + try { - Object value = _sessionData.getAttribute(iter.next()); - if (value instanceof HttpSessionActivationListener) + HttpSessionEvent event = new HttpSessionEvent(this); + for (String name : _sessionData.getKeys()) { - HttpSessionActivationListener listener = (HttpSessionActivationListener)value; - listener.sessionDidActivate(event); + Object value = _sessionData.getAttribute(name); + if (value instanceof HttpSessionActivationListener) + { + HttpSessionActivationListener listener = (HttpSessionActivationListener)value; + listener.sessionDidActivate(event); + } } } + finally + { + getSessionData().setDirty(dirty); + } } /** @@ -384,9 +400,9 @@ public class Session implements SessionHandler.SessionIf public void willPassivate() { HttpSessionEvent event = new HttpSessionEvent(this); - for (Iterator iter = _sessionData.getKeys().iterator(); iter.hasNext(); ) + for (String name : _sessionData.getKeys()) { - Object value = _sessionData.getAttribute(iter.next()); + Object value = _sessionData.getAttribute(name); if (value instanceof HttpSessionActivationListener) { HttpSessionActivationListener listener = (HttpSessionActivationListener)value; @@ -397,21 +413,23 @@ public class Session implements SessionHandler.SessionIf public boolean isValid() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return _state == State.VALID; } } - public boolean isChanging() + public boolean isInvalid() { - checkLocked(); - return _state == State.CHANGING; + try (AutoLock lock = _lock.lock()) + { + return _state == State.INVALID || _state == State.INVALIDATING; + } } public long getCookieSetTime() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return _sessionData.getCookieSet(); } @@ -420,20 +438,17 @@ public class Session implements SessionHandler.SessionIf @Override public long getCreationTime() throws IllegalStateException { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { checkValidForRead(); return _sessionData.getCreated(); } } - /** - * @see javax.servlet.http.HttpSession#getId() - */ @Override public String getId() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return _sessionData.getId(); } @@ -454,21 +469,19 @@ public class Session implements SessionHandler.SessionIf return _sessionData.getVhost(); } - /** - * @see javax.servlet.http.HttpSession#getLastAccessedTime() - */ @Override public long getLastAccessedTime() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { + if (isInvalid()) + { + throw new IllegalStateException("Session not valid"); + } return _sessionData.getLastAccessed(); } } - /** - * @see javax.servlet.http.HttpSession#getServletContext() - */ @Override public ServletContext getServletContext() { @@ -477,16 +490,17 @@ public class Session implements SessionHandler.SessionIf return _handler._context; } - /** - * @see javax.servlet.http.HttpSession#setMaxInactiveInterval(int) - */ @Override public void setMaxInactiveInterval(int secs) { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { _sessionData.setMaxInactiveMs((long)secs * 1000L); _sessionData.calcAndSetExpiry(); + //dirty metadata writes can be skipped, but changing the + //maxinactiveinterval should write the session out because + //it may affect the session on other nodes, or on the same + //node in the case of the nullsessioncache _sessionData.setDirty(true); if (LOG.isDebugEnabled()) @@ -512,7 +526,7 @@ public class Session implements SessionHandler.SessionIf { long time = 0; - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { long remaining = _sessionData.getExpiry() - now; long maxInactive = _sessionData.getMaxInactiveMs(); @@ -561,7 +575,8 @@ public class Session implements SessionHandler.SessionIf time = (remaining > 0 ? (Math.min(maxInactive, TimeUnit.SECONDS.toMillis(evictionPolicy))) : 0); if (LOG.isDebugEnabled()) - LOG.debug("Session {} timer set to lesser of maxInactive={} and inactivityEvict={}", getId(), maxInactive, evictionPolicy); + LOG.debug("Session {} timer set to lesser of maxInactive={} and inactivityEvict={}", getId(), + maxInactive, evictionPolicy); } } } @@ -569,22 +584,16 @@ public class Session implements SessionHandler.SessionIf return time; } - /** - * @see javax.servlet.http.HttpSession#getMaxInactiveInterval() - */ @Override public int getMaxInactiveInterval() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { long maxInactiveMs = _sessionData.getMaxInactiveMs(); return (int)(maxInactiveMs < 0 ? -1 : maxInactiveMs / 1000); } } - /** - * @see javax.servlet.http.HttpSession#getSessionContext() - */ @Override @Deprecated(since = "Servlet API 2.1") public HttpSessionContext getSessionContext() @@ -605,8 +614,6 @@ public class Session implements SessionHandler.SessionIf */ protected void checkValidForWrite() throws IllegalStateException { - checkLocked(); - if (_state == State.INVALID) throw new IllegalStateException("Not valid for write: id=" + _sessionData.getId() + " created=" + _sessionData.getCreated() + @@ -630,8 +637,6 @@ public class Session implements SessionHandler.SessionIf */ protected void checkValidForRead() throws IllegalStateException { - checkLocked(); - if (_state == State.INVALID) throw new IllegalStateException("Invalid for read: id=" + _sessionData.getId() + " created=" + _sessionData.getCreated() + @@ -647,49 +652,35 @@ public class Session implements SessionHandler.SessionIf throw new IllegalStateException("Invalid for read: id=" + _sessionData.getId() + " not resident"); } - protected void checkLocked() throws IllegalStateException - { - if (!_lock.isLocked()) - throw new IllegalStateException("Session not locked"); - } - - /** - * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String) - */ @Override public Object getAttribute(String name) { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { checkValidForRead(); return _sessionData.getAttribute(name); } } - /** - * @see javax.servlet.http.HttpSession#getValue(java.lang.String) - */ @Override @Deprecated(since = "Servlet API 2.2") public Object getValue(String name) { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { + checkValidForRead(); return _sessionData.getAttribute(name); } } - /** - * @see javax.servlet.http.HttpSession#getAttributeNames() - */ @Override public Enumeration getAttributeNames() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { checkValidForRead(); final Iterator itor = _sessionData.getKeys().iterator(); - return new Enumeration() + return new Enumeration<>() { @Override @@ -725,7 +716,7 @@ public class Session implements SessionHandler.SessionIf @Deprecated(since = "Servlet API 2.2") public String[] getValueNames() throws IllegalStateException { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { checkValidForRead(); Iterator itor = _sessionData.getKeys().iterator(); @@ -740,15 +731,11 @@ public class Session implements SessionHandler.SessionIf } } - /** - * @see javax.servlet.http.HttpSession#setAttribute(java.lang.String, - * java.lang.Object) - */ @Override public void setAttribute(String name, Object value) { Object old = null; - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { // if session is not valid, don't accept the set checkValidForWrite(); @@ -760,10 +747,6 @@ public class Session implements SessionHandler.SessionIf callSessionAttributeListeners(name, value, old); } - /** - * @see javax.servlet.http.HttpSession#putValue(java.lang.String, - * java.lang.Object) - */ @Override @Deprecated(since = "Servlet API 2.2") public void putValue(String name, Object value) @@ -771,18 +754,12 @@ public class Session implements SessionHandler.SessionIf setAttribute(name, value); } - /** - * @see javax.servlet.http.HttpSession#removeAttribute(java.lang.String) - */ @Override public void removeAttribute(String name) { setAttribute(name, null); } - /** - * @see javax.servlet.http.HttpSession#removeValue(java.lang.String) - */ @Override @Deprecated(since = "Servlet API 2.1") public void removeValue(String name) @@ -802,7 +779,7 @@ public class Session implements SessionHandler.SessionIf String id = null; String extendedId = null; - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { while (true) { @@ -838,7 +815,7 @@ public class Session implements SessionHandler.SessionIf String newId = _handler._sessionIdManager.renewSessionId(id, extendedId, request); - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { switch (_state) { @@ -907,7 +884,7 @@ public class Session implements SessionHandler.SessionIf } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to invalidate Session {}", this, e); } } @@ -916,7 +893,7 @@ public class Session implements SessionHandler.SessionIf * * @return the lock */ - public Lock lock() + public AutoLock lock() { return _lock.lock(); } @@ -928,7 +905,7 @@ public class Session implements SessionHandler.SessionIf { boolean result = false; - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { while (true) @@ -952,6 +929,8 @@ public class Session implements SessionHandler.SessionIf { try { + if (LOG.isDebugEnabled()) + LOG.debug("Session {} waiting for id change to complete", _sessionData.getId()); _stateChangeCompleted.await(); } catch (InterruptedException e) @@ -985,7 +964,7 @@ public class Session implements SessionHandler.SessionIf */ protected void finishInvalidate() throws IllegalStateException { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { try { @@ -1023,7 +1002,7 @@ public class Session implements SessionHandler.SessionIf @Override public boolean isNew() throws IllegalStateException { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { checkValidForRead(); return _newSession; @@ -1032,7 +1011,7 @@ public class Session implements SessionHandler.SessionIf public void setIdChanged(boolean changed) { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { _idChanged = changed; } @@ -1040,7 +1019,7 @@ public class Session implements SessionHandler.SessionIf public boolean isIdChanged() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return _idChanged; } @@ -1058,9 +1037,6 @@ public class Session implements SessionHandler.SessionIf return _sessionData; } - /** - * - */ public void setResident(boolean resident) { _resident = resident; @@ -1077,7 +1053,7 @@ public class Session implements SessionHandler.SessionIf @Override public String toString() { - try (Lock lock = _lock.lock()) + try (AutoLock lock = _lock.lock()) { return String.format("%s@%x{id=%s,x=%s,req=%d,res=%b}", getClass().getSimpleName(), diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCache.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCache.java index b71a55f25b1..e134005c92c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCache.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCache.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -96,6 +96,16 @@ public interface SessionCache extends LifeCycle * @throws Exception if any error occurred */ Session renewSessionId(String oldId, String newId, String oldExtendedId, String newExtendedId) throws Exception; + + /** + * Adds a new Session, with a never-before-used id, + * to the cache. + * + * @param id + * @param session + * @throws Exception + */ + void add(String id, Session session) throws Exception; /** * Get an existing Session. If necessary, the cache will load the data for @@ -116,9 +126,34 @@ public interface SessionCache extends LifeCycle * @param id the session id * @param session the current session object * @throws Exception if any error occurred + * @deprecated use {@link #release(String, Session)} instead */ + @Deprecated void put(String id, Session session) throws Exception; + /** + * Finish using a Session. This is called by the SessionHandler + * once a request is finished with a Session. SessionCache + * implementations may want to delay writing out Session contents + * until the last request exits a Session. + * + * @param id the session id + * @param session the current session object + * @throws Exception if any error occurred + */ + void release(String id, Session session) throws Exception; + + /** + * Called when a response is about to be committed. The + * cache can write the session to ensure that the + * SessionDataStore contains changes to the session + * that occurred during the lifetime of the request. This + * can help ensure that if a subsequent request goes to a + * different server, it will be able to see the session + * changes via the shared store. + */ + void commit(Session session) throws Exception; + /** * Check to see if a Session is in the cache. Does NOT consult * the SessionDataStore. @@ -241,4 +276,18 @@ public interface SessionCache extends LifeCycle * @return if true unloadable session will be deleted */ boolean isRemoveUnloadableSessions(); + + /** + * If true, a dirty session will be written to the SessionDataStore + * just before a response is returned to the client. This ensures + * that subsequent requests to either the same node or a different + * node see the changed session data. + */ + void setFlushOnResponseCommit(boolean flushOnResponse); + + /** + * @return true if dirty sessions should be written + * before the response is committed. + */ + boolean isFlushOnResponseCommit(); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCacheFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCacheFactory.java index 2bd63588b7d..503abe64b3a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCacheFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionCacheFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java index 1e4a506781c..8c6b681fa8c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java index 57a041c9ccc..63c5af54d5b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -28,8 +28,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jetty.util.ClassLoadingObjectInputStream; import org.eclipse.jetty.util.ClassVisibilityChecker; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SessionData @@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class SessionData implements Serializable { - private static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(SessionData.class); private static final long serialVersionUID = 1L; @@ -58,6 +58,7 @@ public class SessionData implements Serializable protected Map _attributes; protected boolean _dirty; protected long _lastSaved; //time in msec since last save + protected boolean _metaDataDirty; //non-attribute data has changed /** * Serialize the attribute map of the session. @@ -155,17 +156,12 @@ public class SessionData implements Serializable LOG.info("Legacy serialization detected for {}", data.getId()); //legacy serialization was used, we have just deserialized the //entire attribute map - data._attributes = new ConcurrentHashMap(); + data._attributes = new ConcurrentHashMap<>(); data.putAllAttributes((Map)o); } } public SessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs) - { - this(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs, new ConcurrentHashMap()); - } - - public SessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs, Map attributes) { _id = id; setContextPath(cpath); @@ -175,7 +171,13 @@ public class SessionData implements Serializable _lastAccessed = lastAccessed; _maxInactiveMs = maxInactiveMs; calcAndSetExpiry(); - _attributes = attributes; + _attributes = new ConcurrentHashMap<>(); + } + + public SessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs, Map attributes) + { + this(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs); + putAllAttributes(attributes); } /** @@ -239,6 +241,22 @@ public class SessionData implements Serializable setDirty(true); } + /** + * @return the metaDataDirty + */ + public boolean isMetaDataDirty() + { + return _metaDataDirty; + } + + /** + * @param metaDataDirty true means non-attribute data has changed + */ + public void setMetaDataDirty(boolean metaDataDirty) + { + _metaDataDirty = metaDataDirty; + } + /** * @param name the name of the attribute * @return the value of the attribute named @@ -266,6 +284,15 @@ public class SessionData implements Serializable return old; } + /** + * Clear all dirty flags. + */ + public void clean() + { + setDirty(false); + setMetaDataDirty(false); + } + public void putAllAttributes(Map attributes) { _attributes.putAll(attributes); @@ -365,11 +392,13 @@ public class SessionData implements Serializable public void calcAndSetExpiry(long time) { setExpiry(calcExpiry(time)); + setMetaDataDirty(true); } public void calcAndSetExpiry() { setExpiry(calcExpiry()); + setMetaDataDirty(true); } public long getCreated() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMap.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMap.java index e8ee920a9dd..d6b2ee55f35 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMap.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMap.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMapFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMapFactory.java index 560a127acaf..a248a61d1ec 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMapFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataMapFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java index 05a80290c8b..55cbf65b965 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStoreFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStoreFactory.java index b70dda99279..904ee58026f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStoreFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index 4357403c527..a3d624e5163 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -26,11 +26,11 @@ import java.util.Enumeration; import java.util.EventListener; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; +import java.util.stream.Collectors; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; @@ -46,6 +46,7 @@ import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionIdListener; import javax.servlet.http.HttpSessionListener; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; @@ -56,13 +57,13 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.util.statistic.SampleStatistic; -import org.eclipse.jetty.util.thread.Locker.Lock; +import org.eclipse.jetty.util.thread.AutoLock; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.lang.Math.round; @@ -72,9 +73,10 @@ import static java.lang.Math.round; @ManagedObject public class SessionHandler extends ScopedHandler { - static final Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); + private static final Logger LOG = LoggerFactory.getLogger(SessionHandler.class); - public static final EnumSet DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE, SessionTrackingMode.URL); + public static final EnumSet DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE, + SessionTrackingMode.URL); /** * Session cookie name. @@ -123,70 +125,16 @@ public class SessionHandler extends ScopedHandler public static final Set DEFAULT_SESSION_TRACKING_MODES = Collections.unmodifiableSet( new HashSet<>( - Arrays.asList(new SessionTrackingMode[]{SessionTrackingMode.COOKIE, SessionTrackingMode.URL}))); + Arrays.asList(SessionTrackingMode.COOKIE, SessionTrackingMode.URL))); @SuppressWarnings("unchecked") public static final Class[] SESSION_LISTENER_TYPES = - new Class[]{ - HttpSessionAttributeListener.class, - HttpSessionIdListener.class, - HttpSessionListener.class - }; - - /** - * Web.xml session-timeout is set in minutes, but is stored as an int in seconds by HttpSession and - * the sessionmanager. Thus MAX_INT is the max number of seconds that can be set, and MAX_INT/60 is the - * max number of minutes that you can set. - */ - public static final java.math.BigDecimal MAX_INACTIVE_MINUTES = new java.math.BigDecimal(Integer.MAX_VALUE / 60); - - /** - * SessionAsyncListener - * - * Used to ensure that a request for which async has been started - * has its session completed as the request exits the context. - */ - public class SessionAsyncListener implements AsyncListener - { - @Override - public void onComplete(AsyncEvent event) throws IOException - { - // An async request has completed, so we can complete the session, - // but we must locate the session instance for this context - Request request = Request.getBaseRequest(event.getAsyncContext().getRequest()); - HttpSession session = request.getSession(false); - String id; - if (session != null) - id = session.getId(); - else + new Class[] { - id = (String)request.getAttribute(DefaultSessionIdManager.__NEW_SESSION_ID); - if (id == null) - id = request.getRequestedSessionId(); - } - - if (id != null) - complete(getSession(id)); - } - - @Override - public void onTimeout(AsyncEvent event) throws IOException - { - - } - - @Override - public void onError(AsyncEvent event) throws IOException - { - complete(Request.getBaseRequest(event.getAsyncContext().getRequest()).getSession(false)); - } - - @Override - public void onStartAsync(AsyncEvent event) throws IOException - { - event.getAsyncContext().addListener(this); - } - } + HttpSessionAttributeListener.class, + HttpSessionIdListener.class, + HttpSessionListener.class + }; @Deprecated(since = "Servlet API 2.1") static final HttpSessionContext __nullSessionContext = new HttpSessionContext() @@ -246,7 +194,6 @@ public class SessionHandler extends ScopedHandler protected Scheduler _scheduler; protected boolean _ownScheduler = false; - protected final SessionAsyncListener _sessionAsyncListener = new SessionAsyncListener(); /** * Constructor. @@ -271,6 +218,8 @@ public class SessionHandler extends ScopedHandler /** * Called by the {@link SessionHandler} when a session is first accessed by a request. * + * Updates the last access time for the session and generates a fresh cookie if necessary. + * * @param session the session object * @param secure whether the request is secure or not * @return the session cookie. If not null, this cookie should be set on the response to either migrate @@ -288,9 +237,8 @@ public class SessionHandler extends ScopedHandler // Do we need to refresh the cookie? if (isUsingCookies() && (s.isIdChanged() || - (getSessionCookieConfig().getMaxAge() > 0 && getRefreshCookieAge() > 0 && ((now - s.getCookieSetTime()) / 1000 > getRefreshCookieAge())) - ) - ) + (getSessionCookieConfig().getMaxAge() > 0 && getRefreshCookieAge() > 0 && + ((now - s.getCookieSetTime()) / 1000 > getRefreshCookieAge())))) { HttpCookie cookie = getSessionCookie(session, _context == null ? "/" : (_context.getContextPath()), secure); s.cookieSet(); @@ -308,33 +256,26 @@ public class SessionHandler extends ScopedHandler * Individual SessionManagers implementations may accept arbitrary listener types, * but they are expected to at least handle HttpSessionActivationListener, * HttpSessionAttributeListener, HttpSessionBindingListener and HttpSessionListener. + * @return true if the listener was added * @see #removeEventListener(EventListener) + * @see HttpSessionAttributeListener + * @see HttpSessionListener + * @see HttpSessionIdListener */ - public void addEventListener(EventListener listener) + @Override + public boolean addEventListener(EventListener listener) { - if (listener instanceof HttpSessionAttributeListener) - _sessionAttributeListeners.add((HttpSessionAttributeListener)listener); - if (listener instanceof HttpSessionListener) - _sessionListeners.add((HttpSessionListener)listener); - if (listener instanceof HttpSessionIdListener) - _sessionIdListeners.add((HttpSessionIdListener)listener); - addBean(listener, false); - } - - /** - * Removes all event listeners for session-related events. - * - * @see #removeEventListener(EventListener) - */ - public void clearEventListeners() - { - for (EventListener e : getBeans(EventListener.class)) + if (super.addEventListener(listener)) { - removeBean(e); + if (listener instanceof HttpSessionAttributeListener) + _sessionAttributeListeners.add((HttpSessionAttributeListener)listener); + if (listener instanceof HttpSessionListener) + _sessionListeners.add((HttpSessionListener)listener); + if (listener instanceof HttpSessionIdListener) + _sessionIdListeners.add((HttpSessionIdListener)listener); + return true; } - _sessionAttributeListeners.clear(); - _sessionListeners.clear(); - _sessionIdListeners.clear(); + return false; } /** @@ -402,10 +343,9 @@ public class SessionHandler extends ScopedHandler } /** - * Called by the {@link SessionHandler} when a session is last accessed by a request. + * Called when a request is finally leaving a session. * * @param session the session object - * @see #access(HttpSession, boolean) */ public void complete(HttpSession session) { @@ -416,36 +356,38 @@ public class SessionHandler extends ScopedHandler return; Session s = ((SessionIf)session).getSession(); - try { - s.complete(); - _sessionCache.put(s.getId(), s); + _sessionCache.release(s.getId(), s); } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to release Session {}", s, e); } } - private void ensureCompletion(Request baseRequest) - { - if (baseRequest.isAsyncStarted()) - { - if (LOG.isDebugEnabled()) - LOG.debug("Adding AsyncListener for {}", baseRequest); - if (!baseRequest.getHttpChannelState().hasListener(_sessionAsyncListener)) - baseRequest.getAsyncContext().addListener(_sessionAsyncListener); - } - else - { - complete(baseRequest.getSession(false)); - } - } - - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() + /** + * Called when a response is about to be committed. + * We might take this opportunity to persist the session + * so that any subsequent requests to other servers + * will see the modifications. */ + public void commit(HttpSession session) + { + if (session == null) + return; + + Session s = ((SessionIf)session).getSession(); + try + { + _sessionCache.commit(s); + } + catch (Exception e) + { + LOG.warn("Unable to commit Session {}", s, e); + } + } + @Override protected void doStart() throws Exception { @@ -546,9 +488,6 @@ public class SessionHandler extends ScopedHandler super.doStart(); } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ @Override protected void doStop() throws Exception { @@ -572,17 +511,27 @@ public class SessionHandler extends ScopedHandler return _httpOnly; } + /** + * @return The sameSite setting for session cookies or null for no setting + * @see HttpCookie#getSameSite() + */ + @ManagedAttribute("SameSite setting for session cookies") + public HttpCookie.SameSite getSameSite() + { + return HttpCookie.getSameSiteFromComment(_sessionComment); + } + /** * Returns the HttpSession with the given session id * * @param extendedId the session id * @return the HttpSession with the corresponding id or null if no session with the given id exists */ - public HttpSession getHttpSession(String extendedId) + protected HttpSession getHttpSession(String extendedId) { String id = getSessionIdManager().getId(extendedId); - Session session = getSession(id); + if (session != null && !session.getExtendedId().equals(extendedId)) session.setIdChanged(true); return session; @@ -618,7 +567,7 @@ public class SessionHandler extends ScopedHandler /** * @return same as SessionCookieConfig.getSecure(). If true, session * cookies are ALWAYS marked as secure. If false, a session cookie is - * ONLY marked as secure if _secureRequestOnly == true and it is a HTTPS request. + * ONLY marked as secure if _secureRequestOnly == true and it is an HTTPS request. */ @ManagedAttribute("if true, secure cookie flag is set on session cookies") public boolean getSecureCookies() @@ -692,30 +641,18 @@ public class SessionHandler extends ScopedHandler sessionPath = (StringUtil.isEmpty(sessionPath)) ? "/" : sessionPath; String id = getExtendedId(session); HttpCookie cookie = null; - if (_sessionComment == null) - { - cookie = new HttpCookie( - _cookieConfig.getName(), - id, - _cookieConfig.getDomain(), - sessionPath, - _cookieConfig.getMaxAge(), - _cookieConfig.isHttpOnly(), - _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure)); - } - else - { - cookie = new HttpCookie( - _cookieConfig.getName(), - id, - _cookieConfig.getDomain(), - sessionPath, - _cookieConfig.getMaxAge(), - _cookieConfig.isHttpOnly(), - _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure), - _sessionComment, - 1); - } + + cookie = new HttpCookie( + _cookieConfig.getName(), + id, + _cookieConfig.getDomain(), + sessionPath, + _cookieConfig.getMaxAge(), + _cookieConfig.isHttpOnly(), + _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure), + HttpCookie.getCommentWithoutAttributes(_cookieConfig.getComment()), + 0, + HttpCookie.getSameSiteFromComment(_cookieConfig.getComment())); return cookie; } @@ -810,7 +747,8 @@ public class SessionHandler extends ScopedHandler try { - _sessionCache.put(id, session); + _sessionCache.add(id, session); + Request.getBaseRequest(request).enterSession(session); _sessionsCreatedStats.increment(); if (request != null && request.isSecure()) @@ -822,26 +760,25 @@ public class SessionHandler extends ScopedHandler } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to add Session {}", id, e); return null; } } - /** - * Removes an event listener for for session-related events. - * - * @param listener the session event listener to remove - * @see #addEventListener(EventListener) - */ - public void removeEventListener(EventListener listener) + @Override + public boolean removeEventListener(EventListener listener) { - if (listener instanceof HttpSessionAttributeListener) - _sessionAttributeListeners.remove(listener); - if (listener instanceof HttpSessionListener) - _sessionListeners.remove(listener); - if (listener instanceof HttpSessionIdListener) - _sessionIdListeners.remove(listener); - removeBean(listener); + if (super.removeEventListener(listener)) + { + if (listener instanceof HttpSessionAttributeListener) + _sessionAttributeListeners.remove(listener); + if (listener instanceof HttpSessionListener) + _sessionListeners.remove(listener); + if (listener instanceof HttpSessionIdListener) + _sessionIdListeners.remove(listener); + return true; + } + return false; } /** @@ -855,13 +792,30 @@ public class SessionHandler extends ScopedHandler } /** - * @param httpOnly The httpOnly to set. + * Set if Session cookies should use HTTP Only + * + * @param httpOnly True if cookies should be HttpOnly. + * @see HttpCookie */ public void setHttpOnly(boolean httpOnly) { _httpOnly = httpOnly; } + /** + * Set Session cookie sameSite mode. + * Currently this is encoded in the session comment until sameSite is supported by {@link SessionCookieConfig} + * + * @param sameSite The sameSite setting for Session cookies (or null for no sameSite setting) + */ + public void setSameSite(HttpCookie.SameSite sameSite) + { + // Encode in comment whilst not supported by SessionConfig, so that it can be set/saved in + // web.xml and quickstart. + // Always pass false for httpOnly as it has it's own setter. + _sessionComment = HttpCookie.getCommentWithAttributes(_sessionComment, false, sameSite); + } + /** * @param metaManager The metaManager used for cross context session management. */ @@ -909,7 +863,8 @@ public class SessionHandler extends ScopedHandler public void setSessionIdPathParameterName(String param) { _sessionIdPathParameterName = (param == null || "none".equals(param)) ? null : param; - _sessionIdPathParameterNamePrefix = (param == null || "none".equals(param)) ? null : (";" + _sessionIdPathParameterName + "="); + _sessionIdPathParameterNamePrefix = (param == null || "none".equals(param)) + ? null : (";" + _sessionIdPathParameterName + "="); } /** @@ -950,13 +905,12 @@ public class SessionHandler extends ScopedHandler } session.setExtendedId(_sessionIdManager.getExtendedId(id, null)); - //session.getSessionData().setLastNode(_sessionIdManager.getWorkerName()); //TODO write through the change of node? } return session; } catch (UnreadableSessionDataException e) { - LOG.warn(e); + LOG.warn("Error loading session {}", id, e); try { //tell id mgr to remove session from all other contexts @@ -970,7 +924,7 @@ public class SessionHandler extends ScopedHandler } catch (Exception other) { - LOG.warn(other); + LOG.warn("Unable to get Session", other); return null; } } @@ -1055,7 +1009,7 @@ public class SessionHandler extends ScopedHandler } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to remove Session", e); return null; } } @@ -1081,6 +1035,12 @@ public class SessionHandler extends ScopedHandler public void setSessionTrackingModes(Set sessionTrackingModes) { + if (sessionTrackingModes != null && + sessionTrackingModes.size() > 1 && + sessionTrackingModes.contains(SessionTrackingMode.SSL)) + { + throw new IllegalArgumentException("sessionTrackingModes specifies a combination of SessionTrackingMode.SSL with a session tracking mode other than SessionTrackingMode.SSL"); + } _sessionTrackingModes = new HashSet<>(sessionTrackingModes); _usingCookies = _sessionTrackingModes.contains(SessionTrackingMode.COOKIE); _usingURLs = _sessionTrackingModes.contains(SessionTrackingMode.URL); @@ -1156,9 +1116,11 @@ public class SessionHandler extends ScopedHandler */ public void renewSessionId(String oldId, String oldExtendedId, String newId, String newExtendedId) { + Session session = null; try { - Session session = _sessionCache.renewSessionId(oldId, newId, oldExtendedId, newExtendedId); //swap the id over + //the use count for the session will be incremented in renewSessionId + session = _sessionCache.renewSessionId(oldId, newId, oldExtendedId, newExtendedId); //swap the id over if (session == null) { //session doesn't exist on this context @@ -1170,7 +1132,21 @@ public class SessionHandler extends ScopedHandler } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to renew Session Id {}:{} -> {}:{}", oldId, oldExtendedId, newId, newExtendedId, e); + } + finally + { + if (session != null) + { + try + { + _sessionCache.release(newId, session); + } + catch (Exception e) + { + LOG.warn("Unable to release {}", newId, e); + } + } } } @@ -1217,7 +1193,7 @@ public class SessionHandler extends ScopedHandler } catch (Exception e) { - LOG.warn("Session listener threw exception", e); + LOG.warn("Error during Session destroy listener", e); } //call the attribute removed listeners and finally mark it as invalid session.finishInvalidate(); @@ -1226,14 +1202,13 @@ public class SessionHandler extends ScopedHandler catch (IllegalStateException e) { if (LOG.isDebugEnabled()) - LOG.debug("Session {} already invalid", session); - LOG.ignore(e); + LOG.debug("Session {} already invalid", session, e); } } } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to delete Session {}", id, e); } } @@ -1268,13 +1243,15 @@ public class SessionHandler extends ScopedHandler } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to expire Session {}", id, e); } } } catch (Exception e) { - LOG.warn(e); + LOG.warn("Failed to check expiration on {}", + candidates.stream().map(Objects::toString).collect(Collectors.joining(", ", "[", "]")), + e); } } @@ -1305,7 +1282,7 @@ public class SessionHandler extends ScopedHandler //1. valid //2. expired //3. idle - try (Lock lock = session.lock()) + try (AutoLock lock = session.lock()) { if (session.getRequests() > 0) return; //session can't expire or be idle if there is a request in it @@ -1324,7 +1301,8 @@ public class SessionHandler extends ScopedHandler //most efficient if it can be done as a bulk operation to eg reduce //roundtrips to the persistent store. Only do this if the HouseKeeper that //does the scavenging is configured to actually scavenge - if (_sessionIdManager.getSessionHouseKeeper() != null && _sessionIdManager.getSessionHouseKeeper().getIntervalSec() > 0) + if (_sessionIdManager.getSessionHouseKeeper() != null && + _sessionIdManager.getSessionHouseKeeper().getIntervalSec() > 0) { _candidateSessionIdsForExpiry.add(session.getId()); if (LOG.isDebugEnabled()) @@ -1372,6 +1350,9 @@ public class SessionHandler extends ScopedHandler * CookieConfig * * Implementation of the javax.servlet.SessionCookieConfig. + * SameSite configuration can be achieved by using setComment + * + * @see HttpCookie */ public final class CookieConfig implements SessionCookieConfig { @@ -1492,11 +1473,9 @@ public class SessionHandler extends ScopedHandler } } - /* - * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override - public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { SessionHandler oldSessionHandler = null; HttpSession oldSession = null; @@ -1505,27 +1484,60 @@ public class SessionHandler extends ScopedHandler try { if (LOG.isDebugEnabled()) - LOG.debug("SessionHandler.doScope"); + LOG.debug("Entering scope {}, dispatch={} asyncstarted={}", this, baseRequest.getDispatcherType(), baseRequest + .isAsyncStarted()); - oldSessionHandler = baseRequest.getSessionHandler(); - oldSession = baseRequest.getSession(false); - - if (oldSessionHandler != this) + switch (baseRequest.getDispatcherType()) { - // new session context - baseRequest.setSessionHandler(this); - baseRequest.setSession(null); - checkRequestedSessionId(baseRequest, request); - } + case REQUEST: + { + //there are no previous sessionhandlers or sessions for dispatch=REQUEST + //look for a session for this context + baseRequest.setSession(null); + checkRequestedSessionId(baseRequest, request); + existingSession = baseRequest.getSession(false); + baseRequest.setSessionHandler(this); + baseRequest.setSession(existingSession); //can be null + break; + } + case ASYNC: + case ERROR: + case FORWARD: + case INCLUDE: + { + //remember previous sessionhandler and session + oldSessionHandler = baseRequest.getSessionHandler(); + oldSession = baseRequest.getSession(false); - // access any existing session for this context - existingSession = baseRequest.getSession(false); + if (oldSessionHandler != this) + { + //find any existing session for this request that has already been accessed + existingSession = baseRequest.getSession(this); + if (existingSession == null) + { + //session for this context has not been visited previously, + //try getting it + baseRequest.setSession(null); + checkRequestedSessionId(baseRequest, request); + existingSession = baseRequest.getSession(false); + } + + baseRequest.setSession(existingSession); + baseRequest.setSessionHandler(this); + } + break; + } + default: + break; + } if ((existingSession != null) && (oldSessionHandler != this)) { HttpCookie cookie = access(existingSession, request.isSecure()); // Handle changed ID or max-age refresh, but only if this is not a redispatched request - if ((cookie != null) && (request.getDispatcherType() == DispatcherType.ASYNC || request.getDispatcherType() == DispatcherType.REQUEST)) + if ((cookie != null) && + (request.getDispatcherType() == DispatcherType.ASYNC || + request.getDispatcherType() == DispatcherType.REQUEST)) baseRequest.getResponse().replaceCookie(cookie); } @@ -1541,13 +1553,10 @@ public class SessionHandler extends ScopedHandler } finally { - //if there is a session that was created during handling this context, then complete it if (LOG.isDebugEnabled()) - LOG.debug("FinalSession={}, old_session_handler={}, this={}, calling complete={}", baseRequest.getSession(false), oldSessionHandler, this, (oldSessionHandler != this)); - - // If we are leaving the scope of this session handler, ensure the session is completed - if (oldSessionHandler != this) - ensureCompletion(baseRequest); + LOG.debug("Leaving scope {} dispatch={}, async={}, session={}, oldsession={}, oldsessionhandler={}", + this, baseRequest.getDispatcherType(), baseRequest.isAsyncStarted(), baseRequest.getSession(false), + oldSession, oldSessionHandler); // revert the session handler to the previous, unless it was null, in which case remember it as // the first session handler encountered. @@ -1559,11 +1568,9 @@ public class SessionHandler extends ScopedHandler } } - /* - * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ @Override - public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { nextHandle(target, baseRequest, request, response); } @@ -1583,7 +1590,10 @@ public class SessionHandler extends ScopedHandler HttpSession session = getHttpSession(requestedSessionId); if (session != null && isValid(session)) + { + baseRequest.enterSession(session); //enter session for first time baseRequest.setSession(session); + } return; } else if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) @@ -1592,7 +1602,7 @@ public class SessionHandler extends ScopedHandler boolean requestedSessionIdFromCookie = false; HttpSession session = null; - // Look for session id cookie + //first try getting id from a cookie if (isUsingCookies()) { Cookie[] cookies = request.getCookies(); @@ -1603,33 +1613,44 @@ public class SessionHandler extends ScopedHandler { if (sessionCookie.equalsIgnoreCase(cookies[i].getName())) { - requestedSessionId = cookies[i].getValue(); + String id = cookies[i].getValue(); requestedSessionIdFromCookie = true; - if (LOG.isDebugEnabled()) - LOG.debug("Got Session ID {} from cookie", requestedSessionId); + LOG.debug("Got Session ID {} from cookie {}", id, sessionCookie); - if (requestedSessionId != null) + HttpSession s = getHttpSession(id); + + if (requestedSessionId == null) { - session = getHttpSession(requestedSessionId); - if (session != null && isValid(session)) - { - break; - } + //no previous id, always accept this one + requestedSessionId = id; + session = s; + } + else if (requestedSessionId.equals(id)) + { + //really a bad request, but will forgive the duplication + } + else if (session == null || !isValid(session)) + { + //no previous session or invalid, accept this one + requestedSessionId = id; + session = s; } else { - LOG.warn("null session id from cookie"); + //previous session is valid, use it unless both valid + if (s != null && isValid(s)) + throw new BadMessageException("Duplicate valid session cookies: " + requestedSessionId + "," + id); } } } } } - if (isUsingURLs() && (requestedSessionId == null || session == null)) + //try getting id from a url + if (isUsingURLs() && (requestedSessionId == null)) { String uri = request.getRequestURI(); - String prefix = getSessionIdPathParameterNamePrefix(); if (prefix != null) { @@ -1648,22 +1669,26 @@ public class SessionHandler extends ScopedHandler requestedSessionId = uri.substring(s, i); requestedSessionIdFromCookie = false; - session = getHttpSession(requestedSessionId); if (LOG.isDebugEnabled()) LOG.debug("Got Session ID {} from URL", requestedSessionId); + session = getHttpSession(requestedSessionId); } } } baseRequest.setRequestedSessionId(requestedSessionId); baseRequest.setRequestedSessionIdFromCookie(requestedSessionId != null && requestedSessionIdFromCookie); - if (session != null && isValid(session)) - baseRequest.setSession(session); + + if (requestedSessionId != null) + { + if (session != null && isValid(session)) + { + baseRequest.enterSession(session); //request enters this session for first time + baseRequest.setSession(session); //associate the session with the request + } + } } - /** - * @see java.lang.Object#toString() - */ @Override public String toString() { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java index 3fcb4964882..07691052b64 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java index 86a009407fa..995c22ec3c9 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/package-info.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/package-info.java index 4ca53199245..b75cf9f8ef7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/package-info.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-server/src/test/config/etc/keystore b/jetty-server/src/test/config/etc/keystore deleted file mode 100644 index d6592f95ee9..00000000000 Binary files a/jetty-server/src/test/config/etc/keystore and /dev/null differ diff --git a/jetty-server/src/test/config/etc/keystore.pkf b/jetty-server/src/test/config/etc/keystore.pkf deleted file mode 100644 index 443818e87df..00000000000 --- a/jetty-server/src/test/config/etc/keystore.pkf +++ /dev/null @@ -1,20 +0,0 @@ -Bag Attributes - friendlyName: jetty - localKeyID: 54 69 6D 65 20 31 34 32 33 31 39 38 30 39 33 31 31 35 -Key Attributes: ------BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIPh4Q0t4xklXTzX -N2VAb47r5n7idAupp4CTNEhhT6lS70iA+A8i4+0lSEHWAogvd9jl3H7SvScr30QM -4ieC0JCGSOwGc8f+yqKrO56PPd5OuqW380BJ0r74jJczU9CcsuavHD7e6mRLUnmj -xM20NSxrcicMiPUHY1mJZtN9swtxAgMBAAECgYADS9P6Jll0uXBZIu/pgfDH27GJ -HlPULstW9VbrMDNzgfUlFMQebLrRpIrnyleJ29Xc//HA4beEkR4lb0T/w88+pEkt -7fhYeqRLPIfpDOgzloynnsoPcd8f/PypbimQrNLmBiG1178nVcy4Yoh5lYVIJwtU -3VriqDlvAfTLrrx8AQJBAMLWuh27Hb8xs3LRg4UD7hcv8tJejstm08Y+czRz7cO0 -RENa3aDjGFSegc+IUfdez7BP8uDw+PwE+jybmTvaliECQQCtR/anCY1WS28/bKvy -lmIwoI15eraBdVFkN0Hfxh+9PfR3rMD5uyvukT5GgTtY/XxADyafSTaipDJiZHJI -EitRAkBjeCBYYVjUbVlBuvi8Bb+dktsSzzdzXDGtueAy3SR7jyJyiIcxRf775Fg9 -TUkbUwoQ5yAF+sACWcAvBPj796JBAkAEZEeHEkHnxv+pztpIyrDwZJFRW9/WRh/q -90+PGVlilXhltBYr/idt43Z9mPblGX+VrAyhitx8oMa6IauX0gYRAkEAgnyVeXrD -jDLUZRA3P8Gu27k1k6GjbTYiUz3HKCz2/6+MZ2MK2qqwafgqocji029Q6dHdPD7a -4QnRlvraUnyQLA== ------END PRIVATE KEY----- diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java index 120cf057662..fd694f3276d 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -33,8 +33,8 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.tools.HttpTester; import org.eclipse.jetty.io.ArrayByteBufferPool; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -84,11 +84,11 @@ public abstract class AbstractHttpTest HttpTester.Input input = HttpTester.from(socket.getInputStream()); HttpTester.parseResponse(input, response); - if (httpVersion.is("HTTP/1.1") - && response.isComplete() - && response.get("content-length") == null - && response.get("transfer-encoding") == null - && !__noBodyCodes.contains(response.getStatus())) + if (httpVersion.is("HTTP/1.1") && + response.isComplete() && + response.get("content-length") == null && + response.get("transfer-encoding") == null && + !__noBodyCodes.contains(response.getStatus())) assertThat("If HTTP/1.1 response doesn't contain transfer-encoding or content-length headers, " + "it should contain connection:close", response.get("connection"), is("close")); return response; @@ -104,7 +104,7 @@ public abstract class AbstractHttpTest } } - protected class ThrowExceptionOnDemandHandler extends AbstractHandler.ErrorDispatchHandler + protected class ThrowExceptionOnDemandHandler extends AbstractHandler { private final boolean throwException; private volatile Throwable failure; @@ -115,7 +115,7 @@ public abstract class AbstractHttpTest } @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (throwException) throw new TestCommitException(); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java new file mode 100644 index 00000000000..60291739302 --- /dev/null +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java @@ -0,0 +1,766 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Exchanger; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Stream; +import javax.servlet.AsyncContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.tools.HttpTester; +import org.eclipse.jetty.io.ChannelEndPoint; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.ManagedSelector; +import org.eclipse.jetty.io.SocketChannelEndPoint; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.thread.Scheduler; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +/** + * Extended Server Tester. + */ +public class AsyncCompletionTest extends HttpServerTestFixture +{ + private static final int POLL = 10; // milliseconds + private static final int WAIT = 10; // seconds + private static final String SMALL = "Now is the time for all good men to come to the aid of the party. "; + private static final String LARGE = SMALL + SMALL + SMALL + SMALL + SMALL; + private static final int BUFFER_SIZE = SMALL.length() * 3 / 2; + private static final BlockingQueue __queue = new BlockingArrayQueue<>(); + private static final AtomicBoolean __transportComplete = new AtomicBoolean(); + + private static class PendingCallback extends Callback.Nested + { + private CompletableFuture _pending = new CompletableFuture<>(); + + public PendingCallback(Callback callback) + { + super(callback); + } + + @Override + public void succeeded() + { + _pending.complete(null); + } + + @Override + public void failed(Throwable x) + { + _pending.completeExceptionally(x); + } + + public void proceed() + { + try + { + _pending.get(WAIT, TimeUnit.SECONDS); + getCallback().succeeded(); + } + catch (Throwable th) + { + th.printStackTrace(); + getCallback().failed(th); + } + } + } + + @BeforeEach + public void init() throws Exception + { + __transportComplete.set(false); + + startServer(new ServerConnector(_server, new HttpConnectionFactory() + { + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + getHttpConfiguration().setOutputBufferSize(BUFFER_SIZE); + getHttpConfiguration().setOutputAggregationSize(BUFFER_SIZE); + return configure(new ExtendedHttpConnection(getHttpConfiguration(), connector, endPoint), connector, endPoint); + } + }) + { + @Override + protected ChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException + { + return new ExtendedEndPoint(channel, selectSet, key, getScheduler()); + } + }); + } + + private static class ExtendedEndPoint extends SocketChannelEndPoint + { + public ExtendedEndPoint(SocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler) + { + super(channel, selector, key, scheduler); + } + + @Override + public void write(Callback callback, ByteBuffer... buffers) throws IllegalStateException + { + PendingCallback delay = new PendingCallback(callback); + super.write(delay, buffers); + __queue.offer(delay); + } + } + + private static class ExtendedHttpConnection extends HttpConnection + { + public ExtendedHttpConnection(HttpConfiguration config, Connector connector, EndPoint endPoint) + { + super(config, connector, endPoint, false); + } + + @Override + public void onCompleted() + { + __transportComplete.compareAndSet(false, true); + super.onCompleted(); + } + } + + enum WriteStyle + { + ARRAY, BUFFER, BYTE, BYTE_THEN_ARRAY, PRINT + } + + public static Stream asyncIOWriteTests() + { + List tests = new ArrayList<>(); + for (WriteStyle w : WriteStyle.values()) + { + for (boolean contentLength : new Boolean[]{true, false}) + { + for (boolean isReady : new Boolean[]{true, false}) + { + for (boolean flush : new Boolean[]{true, false}) + { + for (boolean close : new Boolean[]{true, false}) + { + for (String data : new String[]{SMALL, LARGE}) + { + tests.add(new Object[]{new AsyncIOWriteHandler(w, contentLength, isReady, flush, close, data)}); + } + } + } + } + } + } + return tests.stream().map(Arguments::of); + } + + @ParameterizedTest + @MethodSource("asyncIOWriteTests") + public void testAsyncIOWrite(AsyncIOWriteHandler handler) throws Exception + { + configureServer(handler); + + int base = _threadPool.getBusyThreads(); + try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort())) + { + OutputStream os = client.getOutputStream(); + InputStream in = client.getInputStream(); + + // write the request + os.write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + + // wait for OWP to execute (proves we do not block in write APIs) + boolean completeCalled = handler.waitForOWPExit(); + + while (true) + { + // wait for threads to return to base level (proves we are really async) + long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(WAIT); + while (_threadPool.getBusyThreads() != base) + { + if (System.nanoTime() > end) + throw new TimeoutException(); + Thread.sleep(POLL); + } + + if (completeCalled) + break; + + // We are now asynchronously waiting! + assertThat(__transportComplete.get(), is(false)); + + // If we are not complete, we must be waiting for one or more writes to complete + while (true) + { + PendingCallback delay = __queue.poll(POLL, TimeUnit.MILLISECONDS); + if (delay != null) + { + delay.proceed(); + continue; + } + // No delay callback found, have we finished OWP again? + Boolean c = handler.pollForOWPExit(); + + if (c == null) + // No we haven't, so look for another delay callback + continue; + + // We have a OWP result, so let's handle it. + completeCalled = c; + break; + } + } + + // Wait for full completion + long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(WAIT); + while (!__transportComplete.get()) + { + if (System.nanoTime() > end) + throw new TimeoutException(); + + // proceed with any delayCBs needed for completion + PendingCallback delay = __queue.poll(POLL, TimeUnit.MILLISECONDS); + if (delay != null) + delay.proceed(); + } + + // Check we got a response! + HttpTester.Response response = HttpTester.parseResponse(in); + assertThat(response, Matchers.notNullValue()); + assertThat(response.getStatus(), is(200)); + String content = response.getContent(); + assertThat(content, containsString(handler.getExpectedMessage())); + } + } + + private static class AsyncIOWriteHandler extends AbstractHandler + { + final WriteStyle _write; + final boolean _contentLength; + final boolean _isReady; + final boolean _flush; + final boolean _close; + final String _data; + final Exchanger _ready = new Exchanger<>(); + int _toWrite; + boolean _flushed; + boolean _closed; + + AsyncIOWriteHandler(WriteStyle write, boolean contentLength, boolean isReady, boolean flush, boolean close, String data) + { + _write = write; + _contentLength = contentLength; + _isReady = isReady; + _flush = flush; + _close = close; + _data = data; + _toWrite = data.length(); + } + + public String getExpectedMessage() + { + return SMALL; + } + + boolean waitForOWPExit() + { + try + { + return _ready.exchange(null); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + + Boolean pollForOWPExit() + { + try + { + return _ready.exchange(null, POLL, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + catch (TimeoutException e) + { + return null; + } + } + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + AsyncContext context = request.startAsync(); + ServletOutputStream out = response.getOutputStream(); + response.setContentType("text/plain"); + byte[] bytes = _data.getBytes(StandardCharsets.ISO_8859_1); + if (_contentLength) + response.setContentLength(bytes.length); + + out.setWriteListener(new WriteListener() + { + @Override + public void onWritePossible() throws IOException + { + try + { + if (out.isReady()) + { + if (_toWrite > 0) + { + switch (_write) + { + case ARRAY: + _toWrite = 0; + out.write(bytes, 0, bytes.length); + break; + + case BUFFER: + _toWrite = 0; + ((HttpOutput)out).write(BufferUtil.toBuffer(bytes)); + break; + + case BYTE: + for (int i = bytes.length - _toWrite; i < bytes.length; i++) + { + _toWrite--; + out.write(bytes[i]); + boolean ready = out.isReady(); + if (!ready) + { + _ready.exchange(Boolean.FALSE); + return; + } + } + break; + + case BYTE_THEN_ARRAY: + _toWrite = 0; + out.write(bytes[0]); // This should always aggregate + assertThat(out.isReady(), is(true)); + out.write(bytes, 1, bytes.length - 1); + break; + + case PRINT: + _toWrite = 0; + out.print(_data); + break; + } + } + + if (_flush && !_flushed) + { + boolean ready = out.isReady(); + if (!ready) + { + _ready.exchange(Boolean.FALSE); + return; + } + _flushed = true; + out.flush(); + } + + if (_close && !_closed) + { + if (_isReady) + { + boolean ready = out.isReady(); + if (!ready) + { + _ready.exchange(Boolean.FALSE); + return; + } + } + _closed = true; + out.close(); + } + + if (_isReady) + { + boolean ready = out.isReady(); + if (!ready) + { + _ready.exchange(Boolean.FALSE); + return; + } + } + context.complete(); + _ready.exchange(Boolean.TRUE); + } + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + + @Override + public void onError(Throwable t) + { + t.printStackTrace(); + } + }); + } + + @Override + public String toString() + { + return String.format("AWCH{w=%s,cl=%b,ir=%b,f=%b,c=%b,d=%d}", _write, _contentLength, _isReady, _flush, _close, _data.length()); + } + } + + public static Stream blockingWriteTests() + { + List tests = new ArrayList<>(); + for (WriteStyle w : WriteStyle.values()) + { + for (boolean contentLength : new Boolean[]{true, false}) + { + for (boolean flush : new Boolean[]{true, false}) + { + for (boolean close : new Boolean[]{true, false}) + { + for (String data : new String[]{SMALL, LARGE}) + { + tests.add(new Object[]{new BlockingWriteHandler(w, contentLength, flush, close, data)}); + } + } + } + } + } + return tests.stream().map(Arguments::of); + } + + @ParameterizedTest + @MethodSource("blockingWriteTests") + public void testBlockingWrite(BlockingWriteHandler handler) throws Exception + { + configureServer(handler); + + try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort())) + { + OutputStream os = client.getOutputStream(); + InputStream in = client.getInputStream(); + + // write the request + os.write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + + handler.wait4handle(); + + // Wait for full completion + long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(WAIT); + while (!__transportComplete.get()) + { + if (System.nanoTime() > end) + throw new TimeoutException(); + + // proceed with any delayCBs needed for completion + try + { + PendingCallback delay = __queue.poll(POLL, TimeUnit.MILLISECONDS); + if (delay != null) + delay.proceed(); + } + catch (Exception e) + { + // ignored + } + } + + // Check we got a response! + HttpTester.Response response = HttpTester.parseResponse(in); + assertThat(response, Matchers.notNullValue()); + assertThat(response.getStatus(), is(200)); + String content = response.getContent(); + assertThat(content, containsString(handler.getExpectedMessage())); + } + } + + private static class BlockingWriteHandler extends AbstractHandler + { + final WriteStyle _write; + final boolean _contentLength; + final boolean _flush; + final boolean _close; + final String _data; + final CountDownLatch _wait = new CountDownLatch(1); + + BlockingWriteHandler(WriteStyle write, boolean contentLength, boolean flush, boolean close, String data) + { + _write = write; + _contentLength = contentLength; + _flush = flush; + _close = close; + _data = data; + } + + public String getExpectedMessage() + { + return SMALL; + } + + public void wait4handle() + { + try + { + Assertions.assertTrue(_wait.await(WAIT, TimeUnit.SECONDS)); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + AsyncContext context = request.startAsync(); + ServletOutputStream out = response.getOutputStream(); + + context.start(() -> + { + try + { + _wait.countDown(); + + response.setContentType("text/plain"); + byte[] bytes = _data.getBytes(StandardCharsets.ISO_8859_1); + if (_contentLength) + response.setContentLength(bytes.length); + + switch (_write) + { + case ARRAY: + out.write(bytes, 0, bytes.length); + break; + + case BUFFER: + ((HttpOutput)out).write(BufferUtil.toBuffer(bytes)); + break; + + case BYTE: + for (byte b : bytes) + { + out.write(b); + } + break; + + case BYTE_THEN_ARRAY: + out.write(bytes[0]); // This should always aggregate + out.write(bytes, 1, bytes.length - 1); + break; + + case PRINT: + out.print(_data); + break; + } + + if (_flush) + out.flush(); + + if (_close) + out.close(); + + context.complete(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + }); + } + + @Override + public String toString() + { + return String.format("BWCH{w=%s,cl=%b,f=%b,c=%b,d=%d}", _write, _contentLength, _flush, _close, _data.length()); + } + } + + public static Stream sendContentTests() + { + List tests = new ArrayList<>(); + for (ContentStyle style : ContentStyle.values()) + { + for (String data : new String[]{SMALL, LARGE}) + { + tests.add(new Object[]{new SendContentHandler(style, data)}); + } + } + return tests.stream().map(Arguments::of); + } + + @ParameterizedTest + @MethodSource("sendContentTests") + public void testSendContent(SendContentHandler handler) throws Exception + { + configureServer(handler); + + int base = _threadPool.getBusyThreads(); + try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort())) + { + OutputStream os = client.getOutputStream(); + InputStream in = client.getInputStream(); + + // write the request + os.write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + + handler.wait4handle(); + + long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(WAIT); + while (_threadPool.getBusyThreads() != base) + { + if (System.nanoTime() > end) + throw new TimeoutException(); + Thread.sleep(POLL); + } + + // Wait for full completion + end = System.nanoTime() + TimeUnit.SECONDS.toNanos(WAIT); + while (!__transportComplete.get()) + { + if (System.nanoTime() > end) + throw new TimeoutException(); + + // proceed with any delayCBs needed for completion + try + { + PendingCallback delay = __queue.poll(POLL, TimeUnit.MILLISECONDS); + if (delay != null) + delay.proceed(); + } + catch (Exception e) + { + // ignored + } + } + + // Check we got a response! + HttpTester.Response response = HttpTester.parseResponse(in); + assertThat(response, Matchers.notNullValue()); + assertThat(response.getStatus(), is(200)); + String content = response.getContent(); + assertThat(content, containsString(handler.getExpectedMessage())); + } + } + + enum ContentStyle + { + BUFFER, STREAM + // TODO more types needed here + } + + private static class SendContentHandler extends AbstractHandler + { + final ContentStyle _style; + final String _data; + final CountDownLatch _wait = new CountDownLatch(1); + + SendContentHandler(ContentStyle style, String data) + { + _style = style; + _data = data; + } + + public String getExpectedMessage() + { + return SMALL; + } + + public void wait4handle() + { + try + { + Assertions.assertTrue(_wait.await(WAIT, TimeUnit.SECONDS)); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + AsyncContext context = request.startAsync(); + HttpOutput out = (HttpOutput)response.getOutputStream(); + + response.setContentType("text/plain"); + byte[] bytes = _data.getBytes(StandardCharsets.ISO_8859_1); + + switch (_style) + { + case BUFFER: + out.sendContent(BufferUtil.toBuffer(bytes), Callback.from(context::complete)); + break; + + case STREAM: + out.sendContent(new ByteArrayInputStream(bytes), Callback.from(context::complete)); + break; + } + + _wait.countDown(); + } + + @Override + public String toString() + { + return String.format("SCCH{w=%s,d=%d}", _style, _data.length()); + } + } +} diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java index 04418f01f2d..fbcb79f7103 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java index eaeb0f53a8a..17f07daaa05 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncStressTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -38,14 +38,14 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -53,7 +53,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @Tag("stress") public class AsyncStressTest { - private static final Logger LOG = Log.getLogger(AsyncStressTest.class); + private static final Logger LOG = LoggerFactory.getLogger(AsyncStressTest.class); protected QueuedThreadPool _threads = new QueuedThreadPool(); protected Server _server = new Server(_threads); @@ -70,7 +70,7 @@ public class AsyncStressTest {"/path?suspend=", "TIMEOUT"}, {"/path?suspend=60000&resume=", "RESUMED"}, {"/path?suspend=60000&complete=", "COMPLETED"}, - }; + }; @BeforeEach public void init() throws Exception @@ -188,33 +188,33 @@ public class AsyncStressTest @Override public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { - int read_before = 0; - long sleep_for = -1; - long suspend_for = -1; - long resume_after = -1; - long complete_after = -1; + int readBefore = 0; + long sleepFor = -1; + long suspendFor = -1; + long resumeAfter = -1; + long completeAfter = -1; final String uri = baseRequest.getHttpURI().toString(); if (request.getParameter("read") != null) - read_before = Integer.parseInt(request.getParameter("read")); + readBefore = Integer.parseInt(request.getParameter("read")); if (request.getParameter("sleep") != null) - sleep_for = Integer.parseInt(request.getParameter("sleep")); + sleepFor = Integer.parseInt(request.getParameter("sleep")); if (request.getParameter("suspend") != null) - suspend_for = Integer.parseInt(request.getParameter("suspend")); + suspendFor = Integer.parseInt(request.getParameter("suspend")); if (request.getParameter("resume") != null) - resume_after = Integer.parseInt(request.getParameter("resume")); + resumeAfter = Integer.parseInt(request.getParameter("resume")); if (request.getParameter("complete") != null) - complete_after = Integer.parseInt(request.getParameter("complete")); + completeAfter = Integer.parseInt(request.getParameter("complete")); if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) { - if (read_before > 0) + if (readBefore > 0) { - byte[] buf = new byte[read_before]; + byte[] buf = new byte[readBefore]; request.getInputStream().read(buf); } - else if (read_before < 0) + else if (readBefore < 0) { InputStream in = request.getInputStream(); int b = in.read(); @@ -224,13 +224,13 @@ public class AsyncStressTest } } - if (suspend_for >= 0) + if (suspendFor >= 0) { final AsyncContext asyncContext = baseRequest.startAsync(); asyncContext.addListener(__asyncListener); - if (suspend_for > 0) - asyncContext.setTimeout(suspend_for); - if (complete_after > 0) + if (suspendFor > 0) + asyncContext.setTimeout(suspendFor); + if (completeAfter > 0) { TimerTask complete = new TimerTask() { @@ -252,24 +252,25 @@ public class AsyncStressTest System.err.println(uri + "==" + br.getHttpURI()); System.err.println(asyncContext + "==" + br.getHttpChannelState()); - LOG.warn(e); + LOG.warn("Unable to complete async: request={}, uri={}, asyncContext={}", + br, br.getHttpURI(), br.getHttpChannelState(), e); System.exit(1); } } }; synchronized (_timer) { - _timer.schedule(complete, complete_after); + _timer.schedule(complete, completeAfter); } } - else if (complete_after == 0) + else if (completeAfter == 0) { response.setStatus(200); response.getOutputStream().println("COMPLETED " + request.getHeader("result")); baseRequest.setHandled(true); asyncContext.complete(); } - else if (resume_after > 0) + else if (resumeAfter > 0) { TimerTask resume = new TimerTask() { @@ -281,19 +282,19 @@ public class AsyncStressTest }; synchronized (_timer) { - _timer.schedule(resume, resume_after); + _timer.schedule(resume, resumeAfter); } } - else if (resume_after == 0) + else if (resumeAfter == 0) { asyncContext.dispatch(); } } - else if (sleep_for >= 0) + else if (sleepFor >= 0) { try { - Thread.sleep(sleep_for); + Thread.sleep(sleepFor); } catch (InterruptedException e) { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CharEncodingContextHandler.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CharEncodingContextHandler.java new file mode 100644 index 00000000000..41104d690cc --- /dev/null +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CharEncodingContextHandler.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import org.eclipse.jetty.server.handler.ContextHandler; + +/** + * ContextHandler for testing that implements some + * CharEncoding methods from the servlet spec. + */ +public class CharEncodingContextHandler extends ContextHandler +{ + class Context extends ContextHandler.Context + { + @Override + public String getRequestCharacterEncoding() + { + return getDefaultRequestCharacterEncoding(); + } + + @Override + public String getResponseCharacterEncoding() + { + return getDefaultResponseCharacterEncoding(); + } + } + + public CharEncodingContextHandler() + { + super(); + _scontext = new Context(); + } +} diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java index cd1c346c5a3..fcd0777cefa 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -41,10 +41,7 @@ public class CheckReverseProxyHeadersTest // Classic ProxyPass from example.com:80 to localhost:8080 testRequest("Host: localhost:8080\n" + "X-Forwarded-For: 10.20.30.40\n" + - "X-Forwarded-Host: example.com", new RequestValidator() - { - @Override - public void validate(HttpServletRequest request) + "X-Forwarded-Host: example.com", request -> { assertEquals("example.com", request.getServerName()); assertEquals(80, request.getServerPort()); @@ -53,16 +50,12 @@ public class CheckReverseProxyHeadersTest assertEquals("example.com", request.getHeader("Host")); assertEquals("http", request.getScheme()); assertFalse(request.isSecure()); - } - }); + }); // IPv6 ProxyPass from example.com:80 to localhost:8080 testRequest("Host: localhost:8080\n" + "X-Forwarded-For: 10.20.30.40\n" + - "X-Forwarded-Host: [::1]", new RequestValidator() - { - @Override - public void validate(HttpServletRequest request) + "X-Forwarded-Host: [::1]", request -> { assertEquals("[::1]", request.getServerName()); assertEquals(80, request.getServerPort()); @@ -71,16 +64,12 @@ public class CheckReverseProxyHeadersTest assertEquals("[::1]", request.getHeader("Host")); assertEquals("http", request.getScheme()); assertFalse(request.isSecure()); - } - }); + }); // IPv6 ProxyPass from example.com:80 to localhost:8080 testRequest("Host: localhost:8080\n" + "X-Forwarded-For: 10.20.30.40\n" + - "X-Forwarded-Host: [::1]:8888", new RequestValidator() - { - @Override - public void validate(HttpServletRequest request) + "X-Forwarded-Host: [::1]:8888", request -> { assertEquals("[::1]", request.getServerName()); assertEquals(8888, request.getServerPort()); @@ -89,18 +78,14 @@ public class CheckReverseProxyHeadersTest assertEquals("[::1]:8888", request.getHeader("Host")); assertEquals("http", request.getScheme()); assertFalse(request.isSecure()); - } - }); + }); // ProxyPass from example.com:81 to localhost:8080 testRequest("Host: localhost:8080\n" + "X-Forwarded-For: 10.20.30.40\n" + "X-Forwarded-Host: example.com:81\n" + "X-Forwarded-Server: example.com\n" + - "X-Forwarded-Proto: https", new RequestValidator() - { - @Override - public void validate(HttpServletRequest request) + "X-Forwarded-Proto: https", request -> { assertEquals("example.com", request.getServerName()); assertEquals(81, request.getServerPort()); @@ -109,18 +94,15 @@ public class CheckReverseProxyHeadersTest assertEquals("example.com:81", request.getHeader("Host")); assertEquals("https", request.getScheme()); assertTrue(request.isSecure()); - } - }); + + }); // Multiple ProxyPass from example.com:80 to rp.example.com:82 to localhost:8080 testRequest("Host: localhost:8080\n" + "X-Forwarded-For: 10.20.30.40, 10.0.0.1\n" + "X-Forwarded-Host: example.com, rp.example.com:82\n" + "X-Forwarded-Server: example.com, rp.example.com\n" + - "X-Forwarded-Proto: https, http", new RequestValidator() - { - @Override - public void validate(HttpServletRequest request) + "X-Forwarded-Proto: https, http", request -> { assertEquals("example.com", request.getServerName()); assertEquals(443, request.getServerPort()); @@ -129,8 +111,7 @@ public class CheckReverseProxyHeadersTest assertEquals("example.com", request.getHeader("Host")); assertEquals("https", request.getScheme()); assertTrue(request.isSecure()); - } - }); + }); } private void testRequest(String headers, RequestValidator requestValidator) throws Exception diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumpTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumpTest.java index 4be49bd5ac3..9410ee97677 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumpTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumpTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java index 512194a003c..7936a985478 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -170,10 +170,9 @@ public class ConnectionOpenCloseTest extends AbstractHttpTest public void testSSLOpenRequestClose() throws Exception { SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - File keystore = MavenTestingUtils.getTestResourceFile("keystore"); + File keystore = MavenTestingUtils.getTestResourceFile("keystore.p12"); sslContextFactory.setKeyStoreResource(Resource.newResource(keystore)); sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setKeyManagerPassword("keypwd"); server.addBean(sslContextFactory); server.removeConnector(connector); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java index 036781f945c..a2dc1a77357 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -59,10 +59,9 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture final CountDownLatch latch = new CountDownLatch(requestCount); configureServer(new HelloWorldHandler()); - URI uri = _server.getURI(); - Socket client = newSocket(uri.getHost(), uri.getPort()); - try + + try (Socket client = newSocket(uri.getHost(), uri.getPort())) { OutputStream os = client.getOutputStream(); @@ -119,10 +118,6 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture reader.setDone(); runner.join(); } - finally - { - client.close(); - } } private int iterations(int cnt) @@ -136,8 +131,8 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture configureServer(new EchoHandler()); URI uri = _server.getURI(); - Socket client = newSocket(uri.getHost(), uri.getPort()); - try + + try (Socket client = newSocket(uri.getHost(), uri.getPort())) { OutputStream os = client.getOutputStream(); @@ -181,10 +176,6 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture String in = reader.getResponse().toString(); assertTrue(in.indexOf(__content.substring(__length - 64)) > 0); } - finally - { - client.close(); - } } public class ResponseReader implements Runnable @@ -212,9 +203,6 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture return _response; } - /** - * @see java.lang.Runnable#run() - */ @Override public void run() { @@ -226,11 +214,9 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture count = doRead(); } } - catch (IOException ex) - { - } - catch (InterruptedException ex) + catch (IOException | InterruptedException e) { + // ignore } finally { @@ -240,6 +226,7 @@ public abstract class ConnectorCloseTestBase extends HttpServerTestFixture } catch (IOException e) { + // ignore } } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java index cf2b4d38901..4540da0d5b5 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -34,16 +34,18 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ssl.SslConnection; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.time.Duration.ofSeconds; import static org.hamcrest.MatcherAssert.assertThat; @@ -61,7 +63,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public abstract class ConnectorTimeoutTest extends HttpServerTestFixture { - protected static final Logger LOG = Log.getLogger(ConnectorTimeoutTest.class); + protected static final Logger LOG = LoggerFactory.getLogger(ConnectorTimeoutTest.class); protected static final int MAX_IDLE_TIME = 2000; private int sleepTime = MAX_IDLE_TIME + MAX_IDLE_TIME / 5; @@ -339,6 +341,62 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture }); } + @Test + @Tag("Unstable") + @Disabled // TODO make more stable + public void testBlockingTimeoutRead() throws Exception + { + configureServer(new EchoHandler()); + Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()); + client.setSoTimeout(10000); + InputStream is = client.getInputStream(); + assertFalse(client.isClosed()); + + OutputStream os = client.getOutputStream(); + + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + os.write(("GET / HTTP/1.1\r\n" + + "host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" + + "Transfer-Encoding: chunked\r\n" + + "Content-Type: text/plain\r\n" + + "Connection: close\r\n" + + "\r\n" + + "5\r\n" + + "LMNOP\r\n") + .getBytes("utf-8")); + os.flush(); + + try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) + { + Thread.sleep(300); + os.write("1".getBytes("utf-8")); + os.flush(); + Thread.sleep(300); + os.write("0".getBytes("utf-8")); + os.flush(); + Thread.sleep(300); + os.write("\r".getBytes("utf-8")); + os.flush(); + Thread.sleep(300); + os.write("\n".getBytes("utf-8")); + os.flush(); + Thread.sleep(300); + os.write("0123456789ABCDEF\r\n".getBytes("utf-8")); + os.write("0\r\n".getBytes("utf-8")); + os.write("\r\n".getBytes("utf-8")); + os.flush(); + } + + long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; + assertThat(duration, greaterThan(500L)); + + // read the response + String response = IO.toString(is); + assertThat(response, startsWith("HTTP/1.1 500 ")); + assertThat(response, containsString("InterruptedIOException")); + + } + @Test @Tag("Unstable") @Disabled // TODO make more stable @@ -382,6 +440,56 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture } } + @Test + @Tag("Unstable") + @Disabled // TODO make more stable + public void testBlockingTimeoutWrite() throws Exception + { + configureServer(new HugeResponseHandler()); + Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()); + client.setSoTimeout(10000); + + assertFalse(client.isClosed()); + + OutputStream os = client.getOutputStream(); + BufferedReader is = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.ISO_8859_1), 2048); + + os.write(( + "GET / HTTP/1.0\r\n" + + "host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" + + "connection: keep-alive\r\n" + + "Connection: close\r\n" + + "\r\n").getBytes("utf-8")); + os.flush(); + + // read the header + String line = is.readLine(); + assertThat(line, startsWith("HTTP/1.1 200 OK")); + while (line.length() != 0) + { + line = is.readLine(); + } + + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class, AbstractConnection.class)) + { + for (int i = 0; i < (128 * 1024); i++) + { + if (i % 1028 == 0) + { + Thread.sleep(20); + // System.err.println("read "+TimeUnit.NANOSECONDS.toMillis(System.nanoTime())); + } + line = is.readLine(); + if (line == null) + break; + } + } + long end = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + long duration = end - start; + assertThat(duration, lessThan(20L * 128L)); + } + @Test public void testMaxIdleNoRequest() throws Exception { @@ -432,9 +540,9 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture assertThat(response, is("")); assertEquals(-1, is.read()); } - catch (Exception e) + catch (IOException e) { - LOG.warn(e); + LOG.warn("Unable to read stream", e); } }); assertTrue(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start < maximumTestRuntime); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CookiesTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CookiesTest.java index 4125776138b..68c91971a22 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/CookiesTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CookiesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -163,8 +163,8 @@ public class CookiesTest new Cookie("nameA0", "A0"), new Cookie("nameA1", "A1"), new Cookie("nameB0", "B0"), - new Cookie("nameB1", "B1"), - }); + new Cookie("nameB1", "B1") + }); Cookie[] cookiesX = cutter.getCookies(); assertThat(cookiesX.length, is(4)); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java index ee51f8df28d..37b2ceed3ac 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -28,13 +28,13 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.TimerScheduler; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -132,7 +132,7 @@ public class CustomResourcesMonitorTest static class FileOnDirectoryMonitor implements LowResourceMonitor.LowResourceCheck { - private static final Logger LOG = Log.getLogger(FileOnDirectoryMonitor.class); + private static final Logger LOG = LoggerFactory.getLogger(FileOnDirectoryMonitor.class); private final Path _pathToMonitor; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/DelayedServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/DelayedServerTest.java new file mode 100644 index 00000000000..23f6a824d3d --- /dev/null +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/DelayedServerTest.java @@ -0,0 +1,113 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.thread.ThreadPool; +import org.junit.jupiter.api.BeforeEach; + +/** + * Extended Server Tester. + */ +public class DelayedServerTest extends HttpServerTestBase +{ + @BeforeEach + public void init() throws Exception + { + startServer(new ServerConnector(_server, new HttpConnectionFactory() + { + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + return configure(new DelayedHttpConnection(getHttpConfiguration(), connector, endPoint), connector, endPoint); + } + })); + } + + private static class DelayedHttpConnection extends HttpConnection + { + public DelayedHttpConnection(HttpConfiguration config, Connector connector, EndPoint endPoint) + { + super(config, connector, endPoint, false); + } + + @Override + public void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback) + { + DelayedCallback delay = new DelayedCallback(callback, getServer().getThreadPool()); + super.send(request, response, content, lastContent, delay); + } + } + + private static class DelayedCallback extends Callback.Nested + { + final ThreadPool pool; + + public DelayedCallback(Callback callback, ThreadPool threadPool) + { + super(callback); + pool = threadPool; + } + + @Override + public void succeeded() + { + pool.execute(() -> + { + try + { + Thread.sleep(10); + } + catch (InterruptedException ignored) + { + // ignored + } + finally + { + super.succeeded(); + } + }); + } + + @Override + public void failed(Throwable x) + { + pool.execute(() -> + { + try + { + Thread.sleep(20); + } + catch (InterruptedException ignored) + { + // ignored + } + finally + { + super.failed(x); + } + }); + } + } +} diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/DetectorConnectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/DetectorConnectionTest.java new file mode 100644 index 00000000000..d9e7e9e578d --- /dev/null +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/DetectorConnectionTest.java @@ -0,0 +1,708 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.Socket; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.net.ssl.SSLSocketFactory; + +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.AbstractConnection; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class DetectorConnectionTest +{ + private Server _server; + + private static String inputStreamToString(InputStream is) throws IOException + { + StringBuilder sb = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.US_ASCII)); + + while (true) + { + String line = reader.readLine(); + if (line == null) + { + // remove the last '\n' + if (sb.length() != 0) + sb.deleteCharAt(sb.length() - 1); + break; + } + sb.append(line).append('\n'); + } + + return sb.length() == 0 ? null : sb.toString(); + } + + private String getResponse(String request) throws Exception + { + return getResponse(request.getBytes(StandardCharsets.US_ASCII)); + } + + private String getResponse(byte[]... requests) throws Exception + { + try (Socket socket = new Socket(_server.getURI().getHost(), _server.getURI().getPort())) + { + for (byte[] request : requests) + { + socket.getOutputStream().write(request); + } + return inputStreamToString(socket.getInputStream()); + } + } + + private String getResponseOverSsl(String request) throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.start(); + + SSLSocketFactory socketFactory = sslContextFactory.getSslContext().getSocketFactory(); + try (Socket socket = socketFactory.createSocket(_server.getURI().getHost(), _server.getURI().getPort())) + { + socket.getOutputStream().write(request.getBytes(StandardCharsets.US_ASCII)); + return inputStreamToString(socket.getInputStream()); + } + finally + { + sslContextFactory.stop(); + } + } + + private void start(ConnectionFactory... connectionFactories) throws Exception + { + _server = new Server(); + _server.addConnector(new ServerConnector(_server, 1, 1, connectionFactories)); + _server.setHandler(new DumpHandler()); + _server.start(); + } + + @AfterEach + public void destroy() throws Exception + { + if (_server != null) + _server.stop(); + } + + @Test + public void testConnectionClosedDuringDetection() throws Exception + { + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy); + + start(detector, http); + + try (Socket socket = new Socket(_server.getURI().getHost(), _server.getURI().getPort())) + { + socket.getOutputStream().write("PR".getBytes(StandardCharsets.US_ASCII)); + Thread.sleep(100); // make sure the onFillable callback gets called + socket.getOutputStream().write("OX".getBytes(StandardCharsets.US_ASCII)); + socket.getOutputStream().close(); + + assertThrows(SocketException.class, () -> socket.getInputStream().read()); + } + } + + @Test + public void testConnectionClosedDuringProxyV1Handling() throws Exception + { + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy); + + start(detector, http); + + try (Socket socket = new Socket(_server.getURI().getHost(), _server.getURI().getPort())) + { + socket.getOutputStream().write("PROXY".getBytes(StandardCharsets.US_ASCII)); + Thread.sleep(100); // make sure the onFillable callback gets called + socket.getOutputStream().write(" ".getBytes(StandardCharsets.US_ASCII)); + socket.getOutputStream().close(); + + assertThrows(SocketException.class, () -> socket.getInputStream().read()); + } + } + + @Test + public void testConnectionClosedDuringProxyV2HandlingFixedLengthPart() throws Exception + { + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy); + + start(detector, http); + + try (Socket socket = new Socket(_server.getURI().getHost(), _server.getURI().getPort())) + { + socket.getOutputStream().write(TypeUtil.fromHexString("0D0A0D0A000D0A515549540A")); // proxy V2 Preamble + Thread.sleep(100); // make sure the onFillable callback gets called + socket.getOutputStream().write(TypeUtil.fromHexString("21")); // V2, PROXY + socket.getOutputStream().close(); + + assertThrows(SocketException.class, () -> socket.getInputStream().read()); + } + } + + @Test + public void testConnectionClosedDuringProxyV2HandlingDynamicLengthPart() throws Exception + { + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy); + + start(detector, http); + + try (Socket socket = new Socket(_server.getURI().getHost(), _server.getURI().getPort())) + { + socket.getOutputStream().write(TypeUtil.fromHexString( + // proxy V2 Preamble + "0D0A0D0A000D0A515549540A" + + // V2, PROXY + "21" + + // 0x1 : AF_INET 0x1 : STREAM. + "11" + + // Address length is 2*4 + 2*2 = 12 bytes. + // length of remaining header (4+4+2+2 = 12) + "000C" + )); + Thread.sleep(100); // make sure the onFillable callback gets called + socket.getOutputStream().write(TypeUtil.fromHexString( + // uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port; + "C0A80001" // 8080 + )); + socket.getOutputStream().close(); + + assertThrows(SocketException.class, () -> socket.getInputStream().read()); + } + } + + @Test + public void testDetectingSslProxyToHttpNoSslWithProxy() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl, proxy); + + start(detector, http); + + String request = "PROXY TCP 1.2.3.4 5.6.7.8 111 222\r\n" + + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(request); + + assertThat(response, Matchers.containsString("HTTP/1.1 200")); + assertThat(response, Matchers.containsString("pathInfo=/path")); + assertThat(response, Matchers.containsString("local=5.6.7.8:222")); + assertThat(response, Matchers.containsString("remote=1.2.3.4:111")); + } + + @Test + public void testDetectingSslProxyToHttpWithSslNoProxy() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl, proxy); + + start(detector, http); + + String request = "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponseOverSsl(request); + + assertThat(response, Matchers.containsString("HTTP/1.1 200")); + } + + @Test + public void testDetectingSslProxyToHttpWithSslWithProxy() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl, proxy); + + start(detector, http); + + String request = "PROXY TCP 1.2.3.4 5.6.7.8 111 222\r\n" + + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponseOverSsl(request); + + // SSL matched, so the upgrade was made to HTTP which does not understand the proxy request + assertThat(response, Matchers.containsString("HTTP/1.1 400")); + } + + @Test + public void testDetectionUnsuccessfulUpgradesToNextProtocol() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl, proxy); + + start(detector, http); + + String request = "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(request); + + assertThat(response, Matchers.containsString("HTTP/1.1 200")); + } + + @Test + public void testDetectorToNextDetector() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + DetectorConnectionFactory proxyDetector = new DetectorConnectionFactory(proxy); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, proxyDetector.getProtocol()); + DetectorConnectionFactory sslDetector = new DetectorConnectionFactory(ssl); + + start(sslDetector, proxyDetector, http); + + String request = "PROXY TCP 1.2.3.4 5.6.7.8 111 222\r\n" + + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponseOverSsl(request); + + // SSL matched, so the upgrade was made to proxy which itself upgraded to HTTP + assertThat(response, Matchers.containsString("HTTP/1.1 200")); + assertThat(response, Matchers.containsString("pathInfo=/path")); + assertThat(response, Matchers.containsString("local=5.6.7.8:222")); + assertThat(response, Matchers.containsString("remote=1.2.3.4:111")); + } + + @Test + public void testDetectorWithDetectionUnsuccessful() throws Exception + { + AtomicBoolean detectionSuccessful = new AtomicBoolean(true); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(HttpVersion.HTTP_1_1.asString()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy) + { + @Override + protected void nextProtocol(Connector connector, EndPoint endPoint, ByteBuffer buffer) + { + if (!detectionSuccessful.compareAndSet(true, false)) + throw new AssertionError("DetectionUnsuccessful callback should only have been called once"); + + // omitting this will leak the buffer + connector.getByteBufferPool().release(buffer); + + Callback.Completable completable = new Callback.Completable(); + endPoint.write(completable, ByteBuffer.wrap("No upgrade for you".getBytes(StandardCharsets.US_ASCII))); + completable.whenComplete((r, x) -> endPoint.close()); + } + }; + HttpConnectionFactory http = new HttpConnectionFactory(); + + start(detector, http); + + String request = "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(request); + + assertEquals("No upgrade for you", response); + assertFalse(detectionSuccessful.get()); + } + + @Test + public void testDetectorWithProxyThatHasNoNextProto() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl, proxy); + + start(detector, http); + + String request = "PROXY TCP 1.2.3.4 5.6.7.8 111 222\r\n" + + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(request); + + // ProxyConnectionFactory has no next protocol -> it cannot upgrade + assertThat(response, Matchers.nullValue()); + } + + @Test + public void testOptionalSsl() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + HttpConnectionFactory http = new HttpConnectionFactory(); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl); + + start(detector, http); + + String request = + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String clearTextResponse = getResponse(request); + String sslResponse = getResponseOverSsl(request); + + // both clear text and SSL can be responded to just fine + assertThat(clearTextResponse, Matchers.containsString("HTTP/1.1 200")); + assertThat(sslResponse, Matchers.containsString("HTTP/1.1 200")); + } + + @Test + public void testDetectorThatHasNoConfiguredNextProto() throws Exception + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(ssl); + + start(detector); + + String request = + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(request); + + assertThat(response, Matchers.nullValue()); + } + + @Test + public void testDetectorWithNextProtocolThatDoesNotExist() throws Exception + { + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory("does-not-exist"); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy); + + start(detector, http); + + String proxyReq = + // proxy V2 Preamble + "0D0A0D0A000D0A515549540A" + + // V2, PROXY + "21" + + // 0x1 : AF_INET 0x1 : STREAM. + "11" + + // Address length is 2*4 + 2*2 = 12 bytes. + // length of remaining header (4+4+2+2 = 12) + "000C" + + // uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port; + "C0A80001" + // 192.168.0.1 + "7f000001" + // 127.0.0.1 + "3039" + // 12345 + "1F90"; // 8080 + + String httpReq = + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(TypeUtil.fromHexString(proxyReq), httpReq.getBytes(StandardCharsets.US_ASCII)); + + assertThat(response, Matchers.nullValue()); + } + + @Test + public void testDetectingWithNextProtocolThatDoesNotImplementUpgradeTo() throws Exception + { + ConnectionFactory.Detecting noUpgradeTo = new ConnectionFactory.Detecting() + { + @Override + public Detection detect(ByteBuffer buffer) + { + return Detection.RECOGNIZED; + } + + @Override + public String getProtocol() + { + return "noUpgradeTo"; + } + + @Override + public List getProtocols() + { + return Collections.singletonList(getProtocol()); + } + + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + return new AbstractConnection(null, connector.getExecutor()) + { + @Override + public void onFillable() + { + } + }; + } + }; + + HttpConnectionFactory http = new HttpConnectionFactory(); + DetectorConnectionFactory detector = new DetectorConnectionFactory(noUpgradeTo); + + start(detector, http); + + String proxyReq = + // proxy V2 Preamble + "0D0A0D0A000D0A515549540A" + + // V2, PROXY + "21" + + // 0x1 : AF_INET 0x1 : STREAM. + "11" + + // Address length is 2*4 + 2*2 = 12 bytes. + // length of remaining header (4+4+2+2 = 12) + "000C" + + // uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port; + "C0A80001" + // 192.168.0.1 + "7f000001" + // 127.0.0.1 + "3039" + // 12345 + "1F90"; // 8080 + + String httpReq = + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(TypeUtil.fromHexString(proxyReq), httpReq.getBytes(StandardCharsets.US_ASCII)); + + assertThat(response, Matchers.nullValue()); + } + + @Test + public void testDetectorWithNextProtocolThatDoesNotImplementUpgradeTo() throws Exception + { + ConnectionFactory noUpgradeTo = new ConnectionFactory() + { + @Override + public String getProtocol() + { + return "noUpgradeTo"; + } + + @Override + public List getProtocols() + { + return Collections.singletonList(getProtocol()); + } + + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + return new AbstractConnection(null, connector.getExecutor()) + { + @Override + public void onFillable() + { + } + }; + } + }; + + HttpConnectionFactory http = new HttpConnectionFactory(); + ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); + DetectorConnectionFactory detector = new DetectorConnectionFactory(proxy); + + start(detector, noUpgradeTo); + + String request = + "GET /path HTTP/1.1\n" + + "Host: server:80\n" + + "Connection: close\n" + + "\n"; + String response = getResponse(request); + + assertThat(response, Matchers.nullValue()); + } + + @Test + public void testGeneratedProtocolNames() + { + String keystore = MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath(); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + + ProxyConnectionFactory proxy = new ProxyConnectionFactory(HttpVersion.HTTP_1_1.asString()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()); + + assertEquals("[SSL|[proxy]]", new DetectorConnectionFactory(ssl, proxy).getProtocol()); + assertEquals("[[proxy]|SSL]", new DetectorConnectionFactory(proxy, ssl).getProtocol()); + } + + @Test + public void testDetectorWithNoDetectingFails() + { + assertThrows(IllegalArgumentException.class, DetectorConnectionFactory::new); + } + + @Test + public void testExerciseDetectorNotEnoughBytes() throws Exception + { + ConnectionFactory.Detecting detectingNeverRecognizes = new ConnectionFactory.Detecting() + { + @Override + public Detection detect(ByteBuffer buffer) + { + return Detection.NOT_RECOGNIZED; + } + + @Override + public String getProtocol() + { + return "nevergood"; + } + + @Override + public List getProtocols() + { + throw new AssertionError(); + } + + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + throw new AssertionError(); + } + }; + + ConnectionFactory.Detecting detectingAlwaysNeedMoreBytes = new ConnectionFactory.Detecting() + { + @Override + public Detection detect(ByteBuffer buffer) + { + return Detection.NEED_MORE_BYTES; + } + + @Override + public String getProtocol() + { + return "neverenough"; + } + + @Override + public List getProtocols() + { + throw new AssertionError(); + } + + @Override + public Connection newConnection(Connector connector, EndPoint endPoint) + { + throw new AssertionError(); + } + }; + + DetectorConnectionFactory detector = new DetectorConnectionFactory(detectingNeverRecognizes, detectingAlwaysNeedMoreBytes); + HttpConnectionFactory http = new HttpConnectionFactory(); + + start(detector, http); + + String request = "AAAA".repeat(32768); + + try + { + String response = getResponse(request); + assertThat(response, Matchers.nullValue()); + } + catch (SocketException expected) + { + // The test may fail writing the "request" + // bytes as the server sends back a TCP RST. + } + } +} diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java b/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java index fb899eb0c9a..5cc61c2209f 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server; @@ -34,17 +34,17 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Dump request handler. * Dumps GET and POST requests. * Useful for testing and debugging. */ -public class DumpHandler extends AbstractHandler.ErrorDispatchHandler +public class DumpHandler extends AbstractHandler { - private static final Logger LOG = Log.getLogger(DumpHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(DumpHandler.class); String label = "Dump HttpHandler"; @@ -58,7 +58,7 @@ public class DumpHandler extends AbstractHandler.ErrorDispatchHandler } @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (!isStarted()) return; @@ -113,7 +113,7 @@ public class DumpHandler extends AbstractHandler.ErrorDispatchHandler writer.write("
      \nlocal=" + request.getLocalAddr() + ":" + request.getLocalPort() + "\n
      \n"); writer.write("
      \nremote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\n
      \n"); writer.write("

      Header:

      ");
      -        writer.write(request.getMethod() + " " + request.getRequestURI() + " " + request.getProtocol() + "\n");
      +        writer.write(String.format("%4s %s %s\n", request.getMethod(), request.getRequestURI(), request.getProtocol()));
               Enumeration headers = request.getHeaderNames();
               while (headers.hasMoreElements())
               {
      @@ -154,17 +154,17 @@ public class DumpHandler extends AbstractHandler.ErrorDispatchHandler
                   }
               }
       
      -        String cookie_name = request.getParameter("CookieName");
      -        if (cookie_name != null && cookie_name.trim().length() > 0)
      +        String cookieName = request.getParameter("CookieName");
      +        if (cookieName != null && cookieName.trim().length() > 0)
               {
      -            String cookie_action = request.getParameter("Button");
      +            String cookieAction = request.getParameter("Button");
                   try
                   {
                       String val = request.getParameter("CookieVal");
                       val = val.replaceAll("[ \n\r=<>]", "?");
                       Cookie cookie =
      -                    new Cookie(cookie_name.trim(), val);
      -                if ("Clear Cookie".equals(cookie_action))
      +                    new Cookie(cookieName.trim(), val);
      +                if ("Clear Cookie".equals(cookieAction))
                           cookie.setMaxAge(0);
                       response.addCookie(cookie);
                   }
      @@ -223,10 +223,7 @@ public class DumpHandler extends AbstractHandler.ErrorDispatchHandler
                   }
                   catch (IOException e)
                   {
      -                if (LOG.isDebugEnabled())
      -                    LOG.warn(e);
      -                else
      -                    LOG.warn(e.toString());
      +                LOG.warn("Failed to copy request content", e);
                       writer.write(e.toString());
                   }
               }
      @@ -259,7 +256,7 @@ public class DumpHandler extends AbstractHandler.ErrorDispatchHandler
               }
               catch (Exception e)
               {
      -            LOG.ignore(e);
      +            LOG.trace("IGNORED", e);
               }
           }
       }
      diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java
      index c367b993b4c..b6335bf287d 100644
      --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java
      +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java
      @@ -1,24 +1,27 @@
       //
      -//  ========================================================================
      -//  Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
      -//  ------------------------------------------------------------------------
      -//  All rights reserved. This program and the accompanying materials
      -//  are made available under the terms of the Eclipse Public License v1.0
      -//  and Apache License v2.0 which accompanies this distribution.
      +// ========================================================================
      +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
       //
      -//      The Eclipse Public License is available at
      -//      http://www.eclipse.org/legal/epl-v10.html
      +// This program and the accompanying materials are made available under
      +// the terms of the Eclipse Public License 2.0 which is available at
      +// https://www.eclipse.org/legal/epl-2.0
       //
      -//      The Apache License v2.0 is available at
      -//      http://www.opensource.org/licenses/apache2.0.php
      +// This Source Code may also be made available under the following
      +// Secondary Licenses when the conditions for such availability set
      +// forth in the Eclipse Public License, v. 2.0 are satisfied:
      +// the Apache License v2.0 which is available at
      +// https://www.apache.org/licenses/LICENSE-2.0
       //
      -//  You may elect to redistribute this code under either of these licenses.
      -//  ========================================================================
      +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
      +// ========================================================================
       //
       
       package org.eclipse.jetty.server;
       
       import java.io.IOException;
      +import java.util.HashSet;
      +import java.util.Map;
      +import java.util.Set;
       import javax.servlet.DispatcherType;
       import javax.servlet.RequestDispatcher;
       import javax.servlet.ServletException;
      @@ -26,70 +29,41 @@ import javax.servlet.http.HttpServletRequest;
       import javax.servlet.http.HttpServletResponse;
       
       import org.eclipse.jetty.http.BadMessageException;
      -import org.eclipse.jetty.http.HttpField;
       import org.eclipse.jetty.http.HttpHeader;
       import org.eclipse.jetty.http.tools.HttpTester;
      +import org.eclipse.jetty.logging.StacklessLogging;
       import org.eclipse.jetty.server.handler.AbstractHandler;
      -import org.eclipse.jetty.server.handler.ErrorHandler;
      +import org.eclipse.jetty.util.ajax.JSON;
       import org.junit.jupiter.api.AfterAll;
       import org.junit.jupiter.api.BeforeAll;
       import org.junit.jupiter.api.Test;
      +import org.junit.jupiter.params.ParameterizedTest;
      +import org.junit.jupiter.params.provider.ValueSource;
       
       import static org.hamcrest.MatcherAssert.assertThat;
      +import static org.hamcrest.Matchers.anyOf;
       import static org.hamcrest.Matchers.containsString;
      +import static org.hamcrest.Matchers.greaterThan;
      +import static org.hamcrest.Matchers.instanceOf;
       import static org.hamcrest.Matchers.is;
       import static org.hamcrest.Matchers.not;
       import static org.hamcrest.Matchers.notNullValue;
      -import static org.hamcrest.Matchers.startsWith;
      +import static org.hamcrest.Matchers.nullValue;
      +import static org.junit.jupiter.api.Assertions.assertTrue;
       
       public class ErrorHandlerTest
       {
      +    static StacklessLogging stacklessLogging;
           static Server server;
           static LocalConnector connector;
       
           @BeforeAll
           public static void before() throws Exception
           {
      +        stacklessLogging = new StacklessLogging(HttpChannel.class);
               server = new Server();
               connector = new LocalConnector(server);
               server.addConnector(connector);
      -        server.addBean(new ErrorHandler()
      -        {
      -            @Override
      -            protected void generateAcceptableResponse(
      -                Request baseRequest,
      -                HttpServletRequest request,
      -                HttpServletResponse response,
      -                int code,
      -                String message,
      -                String mimeType) throws IOException
      -            {
      -                switch (mimeType)
      -                {
      -                    case "text/json":
      -                    case "application/json":
      -                    {
      -                        baseRequest.setHandled(true);
      -                        response.setContentType(mimeType);
      -                        response.getWriter()
      -                            .append("{")
      -                            .append("code: \"").append(Integer.toString(code)).append("\",")
      -                            .append("message: \"").append(message).append('"')
      -                            .append("}");
      -                        break;
      -                    }
      -                    case "text/plain":
      -                    {
      -                        baseRequest.setHandled(true);
      -                        response.setContentType("text/plain");
      -                        response.getOutputStream().print(response.getContentType());
      -                        break;
      -                    }
      -                    default:
      -                        super.generateAcceptableResponse(baseRequest, request, response, code, message, mimeType);
      -                }
      -            }
      -        });
       
               server.setHandler(new AbstractHandler()
               {
      @@ -99,7 +73,7 @@ public class ErrorHandlerTest
                       if (baseRequest.getDispatcherType() == DispatcherType.ERROR)
                       {
                           baseRequest.setHandled(true);
      -                    response.sendError(((Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)).intValue());
      +                    response.sendError((Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE));
                           return;
                       }
       
      @@ -113,34 +87,42 @@ public class ErrorHandlerTest
       
                       if (target.startsWith("/badmessage/"))
                       {
      -                    throw new ServletException(new BadMessageException(Integer.parseInt(target.substring(12))));
      -                }
      -            }
      -        });
      -        server.setHandler(new AbstractHandler()
      -        {
      -            @Override
      -            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
      -            {
      -
      -                if (baseRequest.getDispatcherType() == DispatcherType.ERROR)
      -                {
      -                    baseRequest.setHandled(true);
      -                    response.sendError(((Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)).intValue());
      -                    return;
      +                    int code = Integer.parseInt(target.substring(target.lastIndexOf('/') + 1));
      +                    throw new ServletException(new BadMessageException(code));
                       }
       
      -                if (target.startsWith("/charencoding/"))
      +                // produce an exception with an JSON formatted cause message
      +                if (target.startsWith("/jsonmessage/"))
                       {
      -                    baseRequest.setHandled(true);
      -                    response.setCharacterEncoding("utf-8");
      -                    response.sendError(404);
      -                    return;
      +                    String message = "\"}, \"glossary\": {\n \"title\": \"example\"\n }\n {\"";
      +                    throw new ServletException(new RuntimeException(message));
                       }
       
      -                if (target.startsWith("/badmessage/"))
      +                // produce an exception with an XML cause message
      +                if (target.startsWith("/xmlmessage/"))
                       {
      -                    throw new ServletException(new BadMessageException(Integer.parseInt(target.substring(12))));
      +                    String message =
      +                        "\n" +
      +                            " \n" +
      +                            "  example glossary\n" +
      +                            " ";
      +                    throw new ServletException(new RuntimeException(message));
      +                }
      +
      +                // produce an exception with an HTML cause message
      +                if (target.startsWith("/htmlmessage/"))
      +                {
      +                    String message = "
      %3Cscript%3E"; + throw new ServletException(new RuntimeException(message)); + } + + // produce an exception with a UTF-8 cause message + if (target.startsWith("/utf8message/")) + { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharacters + String message = "Euro is € and \u20AC and %E2%82%AC"; + // @checkstyle-enable-check : AvoidEscapedUnicodeCharacters + throw new ServletException(new RuntimeException(message)); } } }); @@ -151,193 +133,238 @@ public class ErrorHandlerTest public static void after() throws Exception { server.stop(); + stacklessLogging.close(); } @Test public void test404NoAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404EmptyAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Accept: \r\n" + "Host: Localhost\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, containsString("Content-Length: 0")); - assertThat(response, not(containsString("Content-Type"))); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), is(0)); + assertThat("Response Content-Type", response.getField(HttpHeader.CONTENT_TYPE), is(nullValue())); } @Test public void test404UnAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Accept: text/*;q=0\r\n" + "Host: Localhost\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, containsString("Content-Length: 0")); - assertThat(response, not(containsString("Content-Type"))); + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), is(0)); + assertThat("Response Content-Type", response.getField(HttpHeader.CONTENT_TYPE), is(nullValue())); } @Test public void test404AllAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: */*\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404HtmlAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void testMoreSpecificAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html, some/other;specific=true\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404HtmlAcceptAnyCharset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: *\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404HtmlAcceptUtf8Charset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404HtmlAcceptNotUtf8Charset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8;q=0\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404HtmlAcceptNotUtf8UnknownCharset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8;q=0,unknown\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, containsString("Content-Length: 0")); - assertThat(response, not(containsString("Content-Type"))); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), is(0)); + assertThat("Response Content-Type", response.getField(HttpHeader.CONTENT_TYPE), is(nullValue())); } @Test public void test404HtmlAcceptUnknownUtf8Charset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8;q=0.1,unknown\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404PreferHtml() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html;q=1.0,text/json;q=0.5,*/*\r\n" + "Accept-Charset: *\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404PreferJson() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html;q=0.5,text/json;q=1.0,*/*\r\n" + "Accept-Charset: *\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/json")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/json")); + + assertContent(response); } @Test @@ -348,12 +375,14 @@ public class ErrorHandlerTest "Host: Localhost\r\n" + "Accept: text/plain\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); assertThat("Response status code", response.getStatus(), is(404)); - HttpField contentType = response.getField(HttpHeader.CONTENT_TYPE); - assertThat("Response Content-Type", contentType, is(notNullValue())); - assertThat("Response Content-Type value", contentType.getValue(), not(containsString("null"))); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/plain")); + + assertContent(response); } @Test @@ -363,8 +392,178 @@ public class ErrorHandlerTest "GET /badmessage/444 HTTP/1.1\r\n" + "Host: Localhost\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); assertThat("Response status code", response.getStatus(), is(444)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); + } + + @ParameterizedTest + @ValueSource(strings = { + "/jsonmessage/", + "/xmlmessage/", + "/htmlmessage/", + "/utf8message/", + }) + public void testComplexCauseMessageNoAcceptHeader(String path) throws Exception + { + String rawResponse = connector.getResponse( + "GET " + path + " HTTP/1.1\r\n" + + "Host: Localhost\r\n" + + "\r\n"); + + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(500)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + String content = assertContent(response); + + if (path.startsWith("/utf8")) + { + // we are Not expecting UTF-8 output, look for mangled ISO-8859-1 version + assertThat("content", content, containsString("Euro is &euro; and ? and %E2%82%AC")); + } + } + + @ParameterizedTest + @ValueSource(strings = { + "/jsonmessage/", + "/xmlmessage/", + "/htmlmessage/", + "/utf8message/", + }) + public void testComplexCauseMessageAcceptUtf8Header(String path) throws Exception + { + String rawResponse = connector.getResponse( + "GET " + path + " HTTP/1.1\r\n" + + "Host: Localhost\r\n" + + "Accept: text/html\r\n" + + "Accept-Charset: utf-8\r\n" + + "\r\n"); + + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(500)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + String content = assertContent(response); + + if (path.startsWith("/utf8")) + { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharacters + // we are Not expecting UTF-8 output, look for mangled ISO-8859-1 version + assertThat("content", content, containsString("Euro is &euro; and \u20AC and %E2%82%AC")); + // @checkstyle-enabled-check : AvoidEscapedUnicodeCharacters + } + } + + private String assertContent(HttpTester.Response response) + { + String contentType = response.get(HttpHeader.CONTENT_TYPE); + String content = response.getContent(); + + if (contentType.contains("text/html")) + { + assertThat(content, not(containsString("", + "/context/%27list%27/%22me%22/%3B%3Cscript%3Ewindow.alert(%27xss%27)%3B%3C/script%3E"), + Arguments.of("test\u00f6?\u00f6:\u00df", "test%C3%B6%3F%C3%B6:%C3%9F"), + Arguments.of("test?\u00f6?\u00f6:\u00df", "test%3F%C3%B6%3F%C3%B6:%C3%9F") + ); + } + + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("encodePathSource") + public void testEncodePath(String rawPath, String expectedEncoded) { // test basic encode/decode StringBuilder buf = new StringBuilder(); - buf.setLength(0); - URIUtil.encodePath(buf, "/foo%23+;,:=/b a r/?info "); - assertEquals("/foo%2523+%3B,:=/b%20a%20r/%3Finfo%20", buf.toString()); - - assertEquals("/foo%2523+%3B,:=/b%20a%20r/%3Finfo%20", URIUtil.encodePath("/foo%23+;,:=/b a r/?info ")); + URIUtil.encodePath(buf, rawPath); + assertEquals(expectedEncoded, buf.toString()); + } + @Test + public void testEncodeString() + { + StringBuilder buf = new StringBuilder(); buf.setLength(0); URIUtil.encodeString(buf, "foo%23;,:=b a r", ";,= "); assertEquals("foo%2523%3b%2c:%3db%20a%20r", buf.toString()); - - buf.setLength(0); - URIUtil.encodePath(buf, "/context/'list'/\"me\"/;"); - assertEquals("/context/%27list%27/%22me%22/%3B%3Cscript%3Ewindow.alert(%27xss%27)%3B%3C/script%3E", buf.toString()); - - buf.setLength(0); - URIUtil.encodePath(buf, "test\u00f6?\u00f6:\u00df"); - assertEquals("test%C3%B6%3F%C3%B6:%C3%9F", buf.toString()); - - buf.setLength(0); - URIUtil.encodePath(buf, "test?\u00f6?\u00f6:\u00df"); - assertEquals("test%3F%C3%B6%3F%C3%B6:%C3%9F", buf.toString()); } - @Test // TODO: Parameterize - public void testDecodePath() + public static Stream decodePathSource() { - assertEquals(URIUtil.decodePath("xx/foo/barxx", 2, 8), "/foo/bar"); - assertEquals("/foo/bar", URIUtil.decodePath("/foo/bar")); - assertEquals("/f o/b r", URIUtil.decodePath("/f%20o/b%20r")); - assertEquals("/foo/bar", URIUtil.decodePath("/foo;ignore/bar;ignore")); - assertEquals("/fää/bar", URIUtil.decodePath("/f\u00e4\u00e4;ignore/bar;ignore")); - assertEquals("/f\u0629\u0629%23/bar", URIUtil.decodePath("/f%d8%a9%d8%a9%2523;ignore/bar;ignore")); + List arguments = new ArrayList<>(); + arguments.add(Arguments.of("/foo/bar", "/foo/bar")); - assertEquals("foo%23;,:=b a r", URIUtil.decodePath("foo%2523%3b%2c:%3db%20a%20r;rubbish")); - assertEquals("/foo/bar%23;,:=b a r=", URIUtil.decodePath("xxx/foo/bar%2523%3b%2c:%3db%20a%20r%3Dxxx;rubbish", 3, 35)); - assertEquals("f\u00e4\u00e4%23;,:=b a r=", URIUtil.decodePath("fää%2523%3b%2c:%3db%20a%20r%3D")); - assertEquals("f\u0629\u0629%23;,:=b a r", URIUtil.decodePath("f%d8%a9%d8%a9%2523%3b%2c:%3db%20a%20r")); + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck + arguments.add(Arguments.of("/f%20o/b%20r", "/f o/b r")); + arguments.add(Arguments.of("fää%2523%3b%2c:%3db%20a%20r%3D", "f\u00e4\u00e4%23;,:=b a r=")); + arguments.add(Arguments.of("f%d8%a9%d8%a9%2523%3b%2c:%3db%20a%20r", "f\u0629\u0629%23;,:=b a r")); + + // path parameters should be ignored + arguments.add(Arguments.of("/foo;ignore/bar;ignore", "/foo/bar")); + arguments.add(Arguments.of("/f\u00e4\u00e4;ignore/bar;ignore", "/fää/bar")); + arguments.add(Arguments.of("/f%d8%a9%d8%a9%2523;ignore/bar;ignore", "/f\u0629\u0629%23/bar")); + arguments.add(Arguments.of("foo%2523%3b%2c:%3db%20a%20r;rubbish", "foo%23;,:=b a r")); // Test for null character (real world ugly test case) byte[] oddBytes = {'/', 0x00, '/'}; String odd = new String(oddBytes, StandardCharsets.ISO_8859_1); - assertEquals(odd, URIUtil.decodePath("/%00/")); + arguments.add(Arguments.of("/%00/", odd)); + + // Deprecated Microsoft Percent-U encoding + arguments.add(Arguments.of("abc%u3040", "abc\u3040")); + return arguments.stream(); } - @Test // TODO: Parameterize - public void testAddEncodedPaths() + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("decodePathSource") + public void testDecodePath(String encodedPath, String expectedPath) { - assertEquals(URIUtil.addEncodedPaths(null, null), null, "null+null"); - assertEquals(URIUtil.addEncodedPaths(null, ""), "", "null+"); - assertEquals(URIUtil.addEncodedPaths(null, "bbb"), "bbb", "null+bbb"); - assertEquals(URIUtil.addEncodedPaths(null, "/"), "/", "null+/"); - assertEquals(URIUtil.addEncodedPaths(null, "/bbb"), "/bbb", "null+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("", null), "", "+null"); - assertEquals(URIUtil.addEncodedPaths("", ""), "", "+"); - assertEquals(URIUtil.addEncodedPaths("", "bbb"), "bbb", "+bbb"); - assertEquals(URIUtil.addEncodedPaths("", "/"), "/", "+/"); - assertEquals(URIUtil.addEncodedPaths("", "/bbb"), "/bbb", "+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa", null), "aaa", "aaa+null"); - assertEquals(URIUtil.addEncodedPaths("aaa", ""), "aaa", "aaa+"); - assertEquals(URIUtil.addEncodedPaths("aaa", "bbb"), "aaa/bbb", "aaa+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa", "/"), "aaa/", "aaa+/"); - assertEquals(URIUtil.addEncodedPaths("aaa", "/bbb"), "aaa/bbb", "aaa+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("/", null), "/", "/+null"); - assertEquals(URIUtil.addEncodedPaths("/", ""), "/", "/+"); - assertEquals(URIUtil.addEncodedPaths("/", "bbb"), "/bbb", "/+bbb"); - assertEquals(URIUtil.addEncodedPaths("/", "/"), "/", "/+/"); - assertEquals(URIUtil.addEncodedPaths("/", "/bbb"), "/bbb", "/+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa/", null), "aaa/", "aaa/+null"); - assertEquals(URIUtil.addEncodedPaths("aaa/", ""), "aaa/", "aaa/+"); - assertEquals(URIUtil.addEncodedPaths("aaa/", "bbb"), "aaa/bbb", "aaa/+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa/", "/"), "aaa/", "aaa/+/"); - assertEquals(URIUtil.addEncodedPaths("aaa/", "/bbb"), "aaa/bbb", "aaa/+/bbb"); - - assertEquals(URIUtil.addEncodedPaths(";JS", null), ";JS", ";JS+null"); - assertEquals(URIUtil.addEncodedPaths(";JS", ""), ";JS", ";JS+"); - assertEquals(URIUtil.addEncodedPaths(";JS", "bbb"), "bbb;JS", ";JS+bbb"); - assertEquals(URIUtil.addEncodedPaths(";JS", "/"), "/;JS", ";JS+/"); - assertEquals(URIUtil.addEncodedPaths(";JS", "/bbb"), "/bbb;JS", ";JS+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa;JS", null), "aaa;JS", "aaa;JS+null"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS", ""), "aaa;JS", "aaa;JS+"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS", "bbb"), "aaa/bbb;JS", "aaa;JS+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS", "/"), "aaa/;JS", "aaa;JS+/"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS", "/bbb"), "aaa/bbb;JS", "aaa;JS+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa/;JS", null), "aaa/;JS", "aaa;JS+null"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS", ""), "aaa/;JS", "aaa;JS+"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS", "bbb"), "aaa/bbb;JS", "aaa;JS+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS", "/"), "aaa/;JS", "aaa;JS+/"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS", "/bbb"), "aaa/bbb;JS", "aaa;JS+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("?A=1", null), "?A=1", "?A=1+null"); - assertEquals(URIUtil.addEncodedPaths("?A=1", ""), "?A=1", "?A=1+"); - assertEquals(URIUtil.addEncodedPaths("?A=1", "bbb"), "bbb?A=1", "?A=1+bbb"); - assertEquals(URIUtil.addEncodedPaths("?A=1", "/"), "/?A=1", "?A=1+/"); - assertEquals(URIUtil.addEncodedPaths("?A=1", "/bbb"), "/bbb?A=1", "?A=1+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa?A=1", null), "aaa?A=1", "aaa?A=1+null"); - assertEquals(URIUtil.addEncodedPaths("aaa?A=1", ""), "aaa?A=1", "aaa?A=1+"); - assertEquals(URIUtil.addEncodedPaths("aaa?A=1", "bbb"), "aaa/bbb?A=1", "aaa?A=1+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa?A=1", "/"), "aaa/?A=1", "aaa?A=1+/"); - assertEquals(URIUtil.addEncodedPaths("aaa?A=1", "/bbb"), "aaa/bbb?A=1", "aaa?A=1+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa/?A=1", null), "aaa/?A=1", "aaa?A=1+null"); - assertEquals(URIUtil.addEncodedPaths("aaa/?A=1", ""), "aaa/?A=1", "aaa?A=1+"); - assertEquals(URIUtil.addEncodedPaths("aaa/?A=1", "bbb"), "aaa/bbb?A=1", "aaa?A=1+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa/?A=1", "/"), "aaa/?A=1", "aaa?A=1+/"); - assertEquals(URIUtil.addEncodedPaths("aaa/?A=1", "/bbb"), "aaa/bbb?A=1", "aaa?A=1+/bbb"); - - assertEquals(URIUtil.addEncodedPaths(";JS?A=1", null), ";JS?A=1", ";JS?A=1+null"); - assertEquals(URIUtil.addEncodedPaths(";JS?A=1", ""), ";JS?A=1", ";JS?A=1+"); - assertEquals(URIUtil.addEncodedPaths(";JS?A=1", "bbb"), "bbb;JS?A=1", ";JS?A=1+bbb"); - assertEquals(URIUtil.addEncodedPaths(";JS?A=1", "/"), "/;JS?A=1", ";JS?A=1+/"); - assertEquals(URIUtil.addEncodedPaths(";JS?A=1", "/bbb"), "/bbb;JS?A=1", ";JS?A=1+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa;JS?A=1", null), "aaa;JS?A=1", "aaa;JS?A=1+null"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS?A=1", ""), "aaa;JS?A=1", "aaa;JS?A=1+"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS?A=1", "bbb"), "aaa/bbb;JS?A=1", "aaa;JS?A=1+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS?A=1", "/"), "aaa/;JS?A=1", "aaa;JS?A=1+/"); - assertEquals(URIUtil.addEncodedPaths("aaa;JS?A=1", "/bbb"), "aaa/bbb;JS?A=1", "aaa;JS?A=1+/bbb"); - - assertEquals(URIUtil.addEncodedPaths("aaa/;JS?A=1", null), "aaa/;JS?A=1", "aaa;JS?A=1+null"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS?A=1", ""), "aaa/;JS?A=1", "aaa;JS?A=1+"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS?A=1", "bbb"), "aaa/bbb;JS?A=1", "aaa;JS?A=1+bbb"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS?A=1", "/"), "aaa/;JS?A=1", "aaa;JS?A=1+/"); - assertEquals(URIUtil.addEncodedPaths("aaa/;JS?A=1", "/bbb"), "aaa/bbb;JS?A=1", "aaa;JS?A=1+/bbb"); + String path = URIUtil.decodePath(encodedPath); + assertEquals(expectedPath, path); } - @Test // TODO: Parameterize - public void testAddDecodedPaths() + public static Stream decodeBadPathSource() { - assertEquals(URIUtil.addPaths(null, null), null, "null+null"); - assertEquals(URIUtil.addPaths(null, ""), "", "null+"); - assertEquals(URIUtil.addPaths(null, "bbb"), "bbb", "null+bbb"); - assertEquals(URIUtil.addPaths(null, "/"), "/", "null+/"); - assertEquals(URIUtil.addPaths(null, "/bbb"), "/bbb", "null+/bbb"); + List arguments = new ArrayList<>(); - assertEquals(URIUtil.addPaths("", null), "", "+null"); - assertEquals(URIUtil.addPaths("", ""), "", "+"); - assertEquals(URIUtil.addPaths("", "bbb"), "bbb", "+bbb"); - assertEquals(URIUtil.addPaths("", "/"), "/", "+/"); - assertEquals(URIUtil.addPaths("", "/bbb"), "/bbb", "+/bbb"); + // Test for null character (real world ugly test case) + // TODO is this a bad decoding or a bad URI ? + // arguments.add(Arguments.of("/%00/")); - assertEquals(URIUtil.addPaths("aaa", null), "aaa", "aaa+null"); - assertEquals(URIUtil.addPaths("aaa", ""), "aaa", "aaa+"); - assertEquals(URIUtil.addPaths("aaa", "bbb"), "aaa/bbb", "aaa+bbb"); - assertEquals(URIUtil.addPaths("aaa", "/"), "aaa/", "aaa+/"); - assertEquals(URIUtil.addPaths("aaa", "/bbb"), "aaa/bbb", "aaa+/bbb"); + // Deprecated Microsoft Percent-U encoding + // TODO still supported for now ? + // arguments.add(Arguments.of("abc%u3040")); - assertEquals(URIUtil.addPaths("/", null), "/", "/+null"); - assertEquals(URIUtil.addPaths("/", ""), "/", "/+"); - assertEquals(URIUtil.addPaths("/", "bbb"), "/bbb", "/+bbb"); - assertEquals(URIUtil.addPaths("/", "/"), "/", "/+/"); - assertEquals(URIUtil.addPaths("/", "/bbb"), "/bbb", "/+/bbb"); + // Bad %## encoding + arguments.add(Arguments.of("abc%xyz")); - assertEquals(URIUtil.addPaths("aaa/", null), "aaa/", "aaa/+null"); - assertEquals(URIUtil.addPaths("aaa/", ""), "aaa/", "aaa/+"); - assertEquals(URIUtil.addPaths("aaa/", "bbb"), "aaa/bbb", "aaa/+bbb"); - assertEquals(URIUtil.addPaths("aaa/", "/"), "aaa/", "aaa/+/"); - assertEquals(URIUtil.addPaths("aaa/", "/bbb"), "aaa/bbb", "aaa/+/bbb"); + // Incomplete %## encoding + arguments.add(Arguments.of("abc%")); + arguments.add(Arguments.of("abc%A")); - assertEquals(URIUtil.addPaths(";JS", null), ";JS", ";JS+null"); - assertEquals(URIUtil.addPaths(";JS", ""), ";JS", ";JS+"); - assertEquals(URIUtil.addPaths(";JS", "bbb"), ";JS/bbb", ";JS+bbb"); - assertEquals(URIUtil.addPaths(";JS", "/"), ";JS/", ";JS+/"); - assertEquals(URIUtil.addPaths(";JS", "/bbb"), ";JS/bbb", ";JS+/bbb"); + // Invalid microsoft %u#### encoding + arguments.add(Arguments.of("abc%uvwxyz")); + arguments.add(Arguments.of("abc%uEFGHIJ")); - assertEquals(URIUtil.addPaths("aaa;JS", null), "aaa;JS", "aaa;JS+null"); - assertEquals(URIUtil.addPaths("aaa;JS", ""), "aaa;JS", "aaa;JS+"); - assertEquals(URIUtil.addPaths("aaa;JS", "bbb"), "aaa;JS/bbb", "aaa;JS+bbb"); - assertEquals(URIUtil.addPaths("aaa;JS", "/"), "aaa;JS/", "aaa;JS+/"); - assertEquals(URIUtil.addPaths("aaa;JS", "/bbb"), "aaa;JS/bbb", "aaa;JS+/bbb"); + // Incomplete microsoft %u#### encoding + arguments.add(Arguments.of("abc%uABC")); + arguments.add(Arguments.of("abc%uAB")); + arguments.add(Arguments.of("abc%uA")); + arguments.add(Arguments.of("abc%u")); - assertEquals(URIUtil.addPaths("aaa/;JS", null), "aaa/;JS", "aaa;JS+null"); - assertEquals(URIUtil.addPaths("aaa/;JS", ""), "aaa/;JS", "aaa;JS+"); - assertEquals(URIUtil.addPaths("aaa/;JS", "bbb"), "aaa/;JS/bbb", "aaa;JS+bbb"); - assertEquals(URIUtil.addPaths("aaa/;JS", "/"), "aaa/;JS/", "aaa;JS+/"); - assertEquals(URIUtil.addPaths("aaa/;JS", "/bbb"), "aaa/;JS/bbb", "aaa;JS+/bbb"); + // Invalid UTF-8 and ISO8859-1 + // TODO currently ISO8859 is too forgiving to detect these + /* + arguments.add(Arguments.of("abc%C3%28")); // invalid 2 octext sequence + arguments.add(Arguments.of("abc%A0%A1")); // invalid 2 octext sequence + arguments.add(Arguments.of("abc%e2%28%a1")); // invalid 3 octext sequence + arguments.add(Arguments.of("abc%e2%82%28")); // invalid 3 octext sequence + arguments.add(Arguments.of("abc%f0%28%8c%bc")); // invalid 4 octext sequence + arguments.add(Arguments.of("abc%f0%90%28%bc")); // invalid 4 octext sequence + arguments.add(Arguments.of("abc%f0%28%8c%28")); // invalid 4 octext sequence + arguments.add(Arguments.of("abc%f8%a1%a1%a1%a1")); // valid sequence, but not unicode + arguments.add(Arguments.of("abc%fc%a1%a1%a1%a1%a1")); // valid sequence, but not unicode + arguments.add(Arguments.of("abc%f8%a1%a1%a1")); // incomplete sequence + */ - assertEquals(URIUtil.addPaths("?A=1", null), "?A=1", "?A=1+null"); - assertEquals(URIUtil.addPaths("?A=1", ""), "?A=1", "?A=1+"); - assertEquals(URIUtil.addPaths("?A=1", "bbb"), "?A=1/bbb", "?A=1+bbb"); - assertEquals(URIUtil.addPaths("?A=1", "/"), "?A=1/", "?A=1+/"); - assertEquals(URIUtil.addPaths("?A=1", "/bbb"), "?A=1/bbb", "?A=1+/bbb"); - - assertEquals(URIUtil.addPaths("aaa?A=1", null), "aaa?A=1", "aaa?A=1+null"); - assertEquals(URIUtil.addPaths("aaa?A=1", ""), "aaa?A=1", "aaa?A=1+"); - assertEquals(URIUtil.addPaths("aaa?A=1", "bbb"), "aaa?A=1/bbb", "aaa?A=1+bbb"); - assertEquals(URIUtil.addPaths("aaa?A=1", "/"), "aaa?A=1/", "aaa?A=1+/"); - assertEquals(URIUtil.addPaths("aaa?A=1", "/bbb"), "aaa?A=1/bbb", "aaa?A=1+/bbb"); - - assertEquals(URIUtil.addPaths("aaa/?A=1", null), "aaa/?A=1", "aaa?A=1+null"); - assertEquals(URIUtil.addPaths("aaa/?A=1", ""), "aaa/?A=1", "aaa?A=1+"); - assertEquals(URIUtil.addPaths("aaa/?A=1", "bbb"), "aaa/?A=1/bbb", "aaa?A=1+bbb"); - assertEquals(URIUtil.addPaths("aaa/?A=1", "/"), "aaa/?A=1/", "aaa?A=1+/"); - assertEquals(URIUtil.addPaths("aaa/?A=1", "/bbb"), "aaa/?A=1/bbb", "aaa?A=1+/bbb"); + return arguments.stream(); } - @Test // TODO: Parameterize - public void testCompactPath() + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("decodeBadPathSource") + public void testBadDecodePath(String encodedPath) { - assertEquals("/foo/bar", URIUtil.compactPath("/foo/bar")); - assertEquals("/foo/bar?a=b//c", URIUtil.compactPath("/foo/bar?a=b//c")); - - assertEquals("/foo/bar", URIUtil.compactPath("//foo//bar")); - assertEquals("/foo/bar?a=b//c", URIUtil.compactPath("//foo//bar?a=b//c")); - - assertEquals("/foo/bar", URIUtil.compactPath("/foo///bar")); - assertEquals("/foo/bar?a=b//c", URIUtil.compactPath("/foo///bar?a=b//c")); + assertThrows(IllegalArgumentException.class, () -> URIUtil.decodePath(encodedPath)); } - @Test // TODO: Parameterize - public void testParentPath() + @Test + public void testDecodePathSubstring() { - assertEquals("/aaa/", URIUtil.parentPath("/aaa/bbb/"), "parent /aaa/bbb/"); - assertEquals("/aaa/", URIUtil.parentPath("/aaa/bbb"), "parent /aaa/bbb"); - assertEquals("/", URIUtil.parentPath("/aaa/"), "parent /aaa/"); - assertEquals("/", URIUtil.parentPath("/aaa"), "parent /aaa"); - assertEquals(null, URIUtil.parentPath("/"), "parent /"); - assertEquals(null, URIUtil.parentPath(null), "parent null"); + String path = URIUtil.decodePath("xx/foo/barxx", 2, 8); + assertEquals("/foo/bar", path); + + path = URIUtil.decodePath("xxx/foo/bar%2523%3b%2c:%3db%20a%20r%3Dxxx;rubbish", 3, 35); + assertEquals("/foo/bar%23;,:=b a r=", path); } - @Test // TODO: Parameterize - public void testEqualsIgnoreEncoding() + public static Stream addEncodedPathsSource() { - assertTrue(URIUtil.equalsIgnoreEncodings("http://example.com/foo/bar", "http://example.com/foo/bar")); - assertTrue(URIUtil.equalsIgnoreEncodings("/barry's", "/barry%27s")); - assertTrue(URIUtil.equalsIgnoreEncodings("/barry%27s", "/barry's")); - assertTrue(URIUtil.equalsIgnoreEncodings("/barry%27s", "/barry%27s")); - assertTrue(URIUtil.equalsIgnoreEncodings("/b rry's", "/b%20rry%27s")); - assertTrue(URIUtil.equalsIgnoreEncodings("/b rry%27s", "/b%20rry's")); - assertTrue(URIUtil.equalsIgnoreEncodings("/b rry%27s", "/b%20rry%27s")); + return Stream.of( + Arguments.of(null, null, null), + Arguments.of(null, "", ""), + Arguments.of(null, "bbb", "bbb"), + Arguments.of(null, "/", "/"), + Arguments.of(null, "/bbb", "/bbb"), - assertTrue(URIUtil.equalsIgnoreEncodings("/foo%2fbar", "/foo%2fbar")); - assertTrue(URIUtil.equalsIgnoreEncodings("/foo%2fbar", "/foo%2Fbar")); + Arguments.of("", null, ""), + Arguments.of("", "", ""), + Arguments.of("", "bbb", "bbb"), + Arguments.of("", "/", "/"), + Arguments.of("", "/bbb", "/bbb"), - assertFalse(URIUtil.equalsIgnoreEncodings("ABC", "abc")); - assertFalse(URIUtil.equalsIgnoreEncodings("/barry's", "/barry%26s")); + Arguments.of("aaa", null, "aaa"), + Arguments.of("aaa", "", "aaa"), + Arguments.of("aaa", "bbb", "aaa/bbb"), + Arguments.of("aaa", "/", "aaa/"), + Arguments.of("aaa", "/bbb", "aaa/bbb"), - assertFalse(URIUtil.equalsIgnoreEncodings("/foo/bar", "/foo%2fbar")); - assertFalse(URIUtil.equalsIgnoreEncodings("/foo2fbar", "/foo/bar")); + Arguments.of("/", null, "/"), + Arguments.of("/", "", "/"), + Arguments.of("/", "bbb", "/bbb"), + Arguments.of("/", "/", "/"), + Arguments.of("/", "/bbb", "/bbb"), + + Arguments.of("aaa/", null, "aaa/"), + Arguments.of("aaa/", "", "aaa/"), + Arguments.of("aaa/", "bbb", "aaa/bbb"), + Arguments.of("aaa/", "/", "aaa/"), + Arguments.of("aaa/", "/bbb", "aaa/bbb"), + + Arguments.of(";JS", null, ";JS"), + Arguments.of(";JS", "", ";JS"), + Arguments.of(";JS", "bbb", "bbb;JS"), + Arguments.of(";JS", "/", "/;JS"), + Arguments.of(";JS", "/bbb", "/bbb;JS"), + + Arguments.of("aaa;JS", null, "aaa;JS"), + Arguments.of("aaa;JS", "", "aaa;JS"), + Arguments.of("aaa;JS", "bbb", "aaa/bbb;JS"), + Arguments.of("aaa;JS", "/", "aaa/;JS"), + Arguments.of("aaa;JS", "/bbb", "aaa/bbb;JS"), + + Arguments.of("aaa/;JS", null, "aaa/;JS"), + Arguments.of("aaa/;JS", "", "aaa/;JS"), + Arguments.of("aaa/;JS", "bbb", "aaa/bbb;JS"), + Arguments.of("aaa/;JS", "/", "aaa/;JS"), + Arguments.of("aaa/;JS", "/bbb", "aaa/bbb;JS"), + + Arguments.of("?A=1", null, "?A=1"), + Arguments.of("?A=1", "", "?A=1"), + Arguments.of("?A=1", "bbb", "bbb?A=1"), + Arguments.of("?A=1", "/", "/?A=1"), + Arguments.of("?A=1", "/bbb", "/bbb?A=1"), + + Arguments.of("aaa?A=1", null, "aaa?A=1"), + Arguments.of("aaa?A=1", "", "aaa?A=1"), + Arguments.of("aaa?A=1", "bbb", "aaa/bbb?A=1"), + Arguments.of("aaa?A=1", "/", "aaa/?A=1"), + Arguments.of("aaa?A=1", "/bbb", "aaa/bbb?A=1"), + + Arguments.of("aaa/?A=1", null, "aaa/?A=1"), + Arguments.of("aaa/?A=1", "", "aaa/?A=1"), + Arguments.of("aaa/?A=1", "bbb", "aaa/bbb?A=1"), + Arguments.of("aaa/?A=1", "/", "aaa/?A=1"), + Arguments.of("aaa/?A=1", "/bbb", "aaa/bbb?A=1"), + + Arguments.of(";JS?A=1", null, ";JS?A=1"), + Arguments.of(";JS?A=1", "", ";JS?A=1"), + Arguments.of(";JS?A=1", "bbb", "bbb;JS?A=1"), + Arguments.of(";JS?A=1", "/", "/;JS?A=1"), + Arguments.of(";JS?A=1", "/bbb", "/bbb;JS?A=1"), + + Arguments.of("aaa;JS?A=1", null, "aaa;JS?A=1"), + Arguments.of("aaa;JS?A=1", "", "aaa;JS?A=1"), + Arguments.of("aaa;JS?A=1", "bbb", "aaa/bbb;JS?A=1"), + Arguments.of("aaa;JS?A=1", "/", "aaa/;JS?A=1"), + Arguments.of("aaa;JS?A=1", "/bbb", "aaa/bbb;JS?A=1"), + + Arguments.of("aaa/;JS?A=1", null, "aaa/;JS?A=1"), + Arguments.of("aaa/;JS?A=1", "", "aaa/;JS?A=1"), + Arguments.of("aaa/;JS?A=1", "bbb", "aaa/bbb;JS?A=1"), + Arguments.of("aaa/;JS?A=1", "/", "aaa/;JS?A=1"), + Arguments.of("aaa/;JS?A=1", "/bbb", "aaa/bbb;JS?A=1") + ); } - @Test // TODO: Parameterize - public void testEqualsIgnoreEncoding_JarFile() + @ParameterizedTest(name = "[{index}] {0}+{1}") + @MethodSource("addEncodedPathsSource") + public void testAddEncodedPaths(String path1, String path2, String expected) { - URI uriA = URI.create("jar:file:/path/to/main.jar!/META-INF/versions/"); - URI uriB = URI.create("jar:file:/path/to/main.jar!/META-INF/%76ersions/"); - assertTrue(URIUtil.equalsIgnoreEncodings(uriA, uriB)); - - uriA = URI.create("JAR:FILE:/path/to/main.jar!/META-INF/versions/"); - uriB = URI.create("jar:file:/path/to/main.jar!/META-INF/versions/"); - assertTrue(URIUtil.equalsIgnoreEncodings(uriA, uriB)); + String actual = URIUtil.addEncodedPaths(path1, path2); + assertEquals(expected, actual, String.format("%s+%s", path1, path2)); } - @Test // TODO: Parameterize - public void testJarSource() throws Exception + public static Stream addDecodedPathsSource() { - assertThat(URIUtil.getJarSource("file:///tmp/"), is("file:///tmp/")); - assertThat(URIUtil.getJarSource("jar:file:///tmp/foo.jar"), is("file:///tmp/foo.jar")); - assertThat(URIUtil.getJarSource("jar:file:///tmp/foo.jar!/some/path"), is("file:///tmp/foo.jar")); - assertThat(URIUtil.getJarSource(new URI("file:///tmp/")), is(new URI("file:///tmp/"))); - assertThat(URIUtil.getJarSource(new URI("jar:file:///tmp/foo.jar")), is(new URI("file:///tmp/foo.jar"))); - assertThat(URIUtil.getJarSource(new URI("jar:file:///tmp/foo.jar!/some/path")), is(new URI("file:///tmp/foo.jar"))); + return Stream.of( + Arguments.of(null, null, null), + Arguments.of(null, "", ""), + Arguments.of(null, "bbb", "bbb"), + Arguments.of(null, "/", "/"), + Arguments.of(null, "/bbb", "/bbb"), + + Arguments.of("", null, ""), + Arguments.of("", "", ""), + Arguments.of("", "bbb", "bbb"), + Arguments.of("", "/", "/"), + Arguments.of("", "/bbb", "/bbb"), + + Arguments.of("aaa", null, "aaa"), + Arguments.of("aaa", "", "aaa"), + Arguments.of("aaa", "bbb", "aaa/bbb"), + Arguments.of("aaa", "/", "aaa/"), + Arguments.of("aaa", "/bbb", "aaa/bbb"), + + Arguments.of("/", null, "/"), + Arguments.of("/", "", "/"), + Arguments.of("/", "bbb", "/bbb"), + Arguments.of("/", "/", "/"), + Arguments.of("/", "/bbb", "/bbb"), + + Arguments.of("aaa/", null, "aaa/"), + Arguments.of("aaa/", "", "aaa/"), + Arguments.of("aaa/", "bbb", "aaa/bbb"), + Arguments.of("aaa/", "/", "aaa/"), + Arguments.of("aaa/", "/bbb", "aaa/bbb"), + + Arguments.of(";JS", null, ";JS"), + Arguments.of(";JS", "", ";JS"), + Arguments.of(";JS", "bbb", ";JS/bbb"), + Arguments.of(";JS", "/", ";JS/"), + Arguments.of(";JS", "/bbb", ";JS/bbb"), + + Arguments.of("aaa;JS", null, "aaa;JS"), + Arguments.of("aaa;JS", "", "aaa;JS"), + Arguments.of("aaa;JS", "bbb", "aaa;JS/bbb"), + Arguments.of("aaa;JS", "/", "aaa;JS/"), + Arguments.of("aaa;JS", "/bbb", "aaa;JS/bbb"), + + Arguments.of("aaa/;JS", null, "aaa/;JS"), + Arguments.of("aaa/;JS", "", "aaa/;JS"), + Arguments.of("aaa/;JS", "bbb", "aaa/;JS/bbb"), + Arguments.of("aaa/;JS", "/", "aaa/;JS/"), + Arguments.of("aaa/;JS", "/bbb", "aaa/;JS/bbb"), + + Arguments.of("?A=1", null, "?A=1"), + Arguments.of("?A=1", "", "?A=1"), + Arguments.of("?A=1", "bbb", "?A=1/bbb"), + Arguments.of("?A=1", "/", "?A=1/"), + Arguments.of("?A=1", "/bbb", "?A=1/bbb"), + + Arguments.of("aaa?A=1", null, "aaa?A=1"), + Arguments.of("aaa?A=1", "", "aaa?A=1"), + Arguments.of("aaa?A=1", "bbb", "aaa?A=1/bbb"), + Arguments.of("aaa?A=1", "/", "aaa?A=1/"), + Arguments.of("aaa?A=1", "/bbb", "aaa?A=1/bbb"), + + Arguments.of("aaa/?A=1", null, "aaa/?A=1"), + Arguments.of("aaa/?A=1", "", "aaa/?A=1"), + Arguments.of("aaa/?A=1", "bbb", "aaa/?A=1/bbb"), + Arguments.of("aaa/?A=1", "/", "aaa/?A=1/"), + Arguments.of("aaa/?A=1", "/bbb", "aaa/?A=1/bbb") + ); } - public static Stream encodeSpaces() + @ParameterizedTest(name = "[{index}] {0}+{1}") + @MethodSource("addDecodedPathsSource") + public void testAddDecodedPaths(String path1, String path2, String expected) { - List data = new ArrayList<>(); + String actual = URIUtil.addPaths(path1, path2); + assertEquals(expected, actual, String.format("%s+%s", path1, path2)); + } - // [raw, expected] + public static Stream compactPathSource() + { + return Stream.of( + Arguments.of("/foo/bar", "/foo/bar"), + Arguments.of("/foo/bar?a=b//c", "/foo/bar?a=b//c"), - // null - data.add(new String[]{null, null}); + Arguments.of("//foo//bar", "/foo/bar"), + Arguments.of("//foo//bar?a=b//c", "/foo/bar?a=b//c"), - // no spaces - data.add(new String[]{"abc", "abc"}); + Arguments.of("/foo///bar", "/foo/bar"), + Arguments.of("/foo///bar?a=b//c", "/foo/bar?a=b//c") + ); + } - // match - data.add(new String[]{"a c", "a%20c"}); - data.add(new String[]{" ", "%20%20%20"}); - data.add(new String[]{"a%20space", "a%20space"}); + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("compactPathSource") + public void testCompactPath(String path, String expected) + { + String actual = URIUtil.compactPath(path); + assertEquals(expected, actual); + } - return data.stream(); + public static Stream parentPathSource() + { + return Stream.of( + Arguments.of("/aaa/bbb/", "/aaa/"), + Arguments.of("/aaa/bbb", "/aaa/"), + Arguments.of("/aaa/", "/"), + Arguments.of("/aaa", "/"), + Arguments.of("/", null), + Arguments.of(null, null) + ); + } + + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("parentPathSource") + public void testParentPath(String path, String expectedPath) + { + String actual = URIUtil.parentPath(path); + assertEquals(expectedPath, actual, String.format("parent %s", path)); + } + + public static Stream equalsIgnoreEncodingStringTrueSource() + { + return Stream.of( + Arguments.of("http://example.com/foo/bar", "http://example.com/foo/bar"), + Arguments.of("/barry's", "/barry%27s"), + Arguments.of("/barry%27s", "/barry's"), + Arguments.of("/barry%27s", "/barry%27s"), + Arguments.of("/b rry's", "/b%20rry%27s"), + Arguments.of("/b rry%27s", "/b%20rry's"), + Arguments.of("/b rry%27s", "/b%20rry%27s"), + + Arguments.of("/foo%2fbar", "/foo%2fbar"), + Arguments.of("/foo%2fbar", "/foo%2Fbar"), + + // encoded vs not-encode ("%" symbol is encoded as "%25") + Arguments.of("/abc%25xyz", "/abc%xyz"), + Arguments.of("/abc%25xy", "/abc%xy"), + Arguments.of("/abc%25x", "/abc%x"), + Arguments.of("/zzz%25", "/zzz%") + ); } @ParameterizedTest - @MethodSource(value = "encodeSpaces") + @MethodSource("equalsIgnoreEncodingStringTrueSource") + public void testEqualsIgnoreEncodingStringTrue(String uriA, String uriB) + { + assertTrue(URIUtil.equalsIgnoreEncodings(uriA, uriB)); + } + + public static Stream equalsIgnoreEncodingStringFalseSource() + { + return Stream.of( + // case difference + Arguments.of("ABC", "abc"), + // Encoding difference ("'" is "%27") + Arguments.of("/barry's", "/barry%26s"), + // Never match on "%2f" differences - only intested in filename / directory name differences + // This could be a directory called "foo" with a file called "bar" on the left, and just a file "foo%2fbar" on the right + Arguments.of("/foo/bar", "/foo%2fbar"), + // not actually encoded + Arguments.of("/foo2fbar", "/foo/bar"), + // encoded vs not-encode ("%" symbol is encoded as "%25") + Arguments.of("/yyy%25zzz", "/aaa%xxx"), + Arguments.of("/zzz%25", "/aaa%") + ); + } + + @ParameterizedTest + @MethodSource("equalsIgnoreEncodingStringFalseSource") + public void testEqualsIgnoreEncodingStringFalse(String uriA, String uriB) + { + assertFalse(URIUtil.equalsIgnoreEncodings(uriA, uriB)); + } + + public static Stream equalsIgnoreEncodingURITrueSource() + { + return Stream.of( + Arguments.of( + URI.create("jar:file:/path/to/main.jar!/META-INF/versions/"), + URI.create("jar:file:/path/to/main.jar!/META-INF/%76ersions/") + ), + Arguments.of( + URI.create("JAR:FILE:/path/to/main.jar!/META-INF/versions/"), + URI.create("jar:file:/path/to/main.jar!/META-INF/versions/") + ) + ); + } + + @ParameterizedTest + @MethodSource("equalsIgnoreEncodingURITrueSource") + public void testEqualsIgnoreEncodingURITrue(URI uriA, URI uriB) + { + assertTrue(URIUtil.equalsIgnoreEncodings(uriA, uriB)); + } + + public static Stream getJarSourceStringSource() + { + return Stream.of( + Arguments.of("file:///tmp/", "file:///tmp/"), + Arguments.of("jar:file:///tmp/foo.jar", "file:///tmp/foo.jar"), + Arguments.of("jar:file:///tmp/foo.jar!/some/path", "file:///tmp/foo.jar") + ); + } + + @ParameterizedTest + @MethodSource("getJarSourceStringSource") + public void testJarSourceString(String uri, String expectedJarUri) throws Exception + { + assertThat(URIUtil.getJarSource(uri), is(expectedJarUri)); + } + + public static Stream getJarSourceURISource() + { + return Stream.of( + Arguments.of(URI.create("file:///tmp/"), URI.create("file:///tmp/")), + Arguments.of(URI.create("jar:file:///tmp/foo.jar"), URI.create("file:///tmp/foo.jar")), + Arguments.of(URI.create("jar:file:///tmp/foo.jar!/some/path"), URI.create("file:///tmp/foo.jar")) + ); + } + + @ParameterizedTest + @MethodSource("getJarSourceURISource") + public void testJarSourceURI(URI uri, URI expectedJarUri) throws Exception + { + assertThat(URIUtil.getJarSource(uri), is(expectedJarUri)); + } + + public static Stream encodeSpacesSource() + { + return Stream.of( + // null + Arguments.of(null, null), + + // no spaces + Arguments.of("abc", "abc"), + + // match + Arguments.of("a c", "a%20c"), + Arguments.of(" ", "%20%20%20"), + Arguments.of("a%20space", "a%20space") + ); + } + + @ParameterizedTest + @MethodSource("encodeSpacesSource") public void testEncodeSpaces(String raw, String expected) { assertThat(URIUtil.encodeSpaces(raw), is(expected)); } - public static Stream encodeSpecific() + public static Stream encodeSpecific() { - List data = new ArrayList<>(); + return Stream.of( + // [raw, chars, expected] - // [raw, chars, expected] + // null input + Arguments.of(null, null, null), - // null input - data.add(new String[]{null, null, null}); + // null chars + Arguments.of("abc", null, "abc"), - // null chars - data.add(new String[]{"abc", null, "abc"}); + // empty chars + Arguments.of("abc", "", "abc"), - // empty chars - data.add(new String[]{"abc", "", "abc"}); + // no matches + Arguments.of("abc", ".;", "abc"), + Arguments.of("xyz", ".;", "xyz"), + Arguments.of(":::", ".;", ":::"), - // no matches - data.add(new String[]{"abc", ".;", "abc"}); - data.add(new String[]{"xyz", ".;", "xyz"}); - data.add(new String[]{":::", ".;", ":::"}); + // matches + Arguments.of("a c", " ", "a%20c"), + Arguments.of("name=value", "=", "name%3Dvalue"), + Arguments.of("This has fewer then 10% hits.", ".%", "This has fewer then 10%25 hits%2E"), - // matches - data.add(new String[]{"a c", " ", "a%20c"}); - data.add(new String[]{"name=value", "=", "name%3Dvalue"}); - data.add(new String[]{"This has fewer then 10% hits.", ".%", "This has fewer then 10%25 hits%2E"}); - - // partially encoded already - data.add(new String[]{"a%20name=value%20pair", "=", "a%20name%3Dvalue%20pair"}); - data.add(new String[]{"a%20name=value%20pair", "=%", "a%2520name%3Dvalue%2520pair"}); - - return data.stream(); + // partially encoded already + Arguments.of("a%20name=value%20pair", "=", "a%20name%3Dvalue%20pair"), + Arguments.of("a%20name=value%20pair", "=%", "a%2520name%3Dvalue%2520pair") + ); } @ParameterizedTest @@ -382,36 +579,34 @@ public class URIUtilTest assertThat(URIUtil.encodeSpecific(raw, chars), is(expected)); } - public static Stream decodeSpecific() + public static Stream decodeSpecific() { - List data = new ArrayList<>(); + return Stream.of( + // [raw, chars, expected] - // [raw, chars, expected] + // null input + Arguments.of(null, null, null), - // null input - data.add(new String[]{null, null, null}); + // null chars + Arguments.of("abc", null, "abc"), - // null chars - data.add(new String[]{"abc", null, "abc"}); + // empty chars + Arguments.of("abc", "", "abc"), - // empty chars - data.add(new String[]{"abc", "", "abc"}); + // no matches + Arguments.of("abc", ".;", "abc"), + Arguments.of("xyz", ".;", "xyz"), + Arguments.of(":::", ".;", ":::"), - // no matches - data.add(new String[]{"abc", ".;", "abc"}); - data.add(new String[]{"xyz", ".;", "xyz"}); - data.add(new String[]{":::", ".;", ":::"}); + // matches + Arguments.of("a%20c", " ", "a c"), + Arguments.of("name%3Dvalue", "=", "name=value"), + Arguments.of("This has fewer then 10%25 hits%2E", ".%", "This has fewer then 10% hits."), - // matches - data.add(new String[]{"a%20c", " ", "a c"}); - data.add(new String[]{"name%3Dvalue", "=", "name=value"}); - data.add(new String[]{"This has fewer then 10%25 hits%2E", ".%", "This has fewer then 10% hits."}); - - // partially decode - data.add(new String[]{"a%20name%3Dvalue%20pair", "=", "a%20name=value%20pair"}); - data.add(new String[]{"a%2520name%3Dvalue%2520pair", "=%", "a%20name=value%20pair"}); - - return data.stream(); + // partially decode + Arguments.of("a%20name%3Dvalue%20pair", "=", "a%20name=value%20pair"), + Arguments.of("a%2520name%3Dvalue%2520pair", "=%", "a%20name=value%20pair") + ); } @ParameterizedTest @@ -420,4 +615,98 @@ public class URIUtilTest { assertThat(URIUtil.decodeSpecific(raw, chars), is(expected)); } + + public static Stream resourceUriLastSegmentSource() + { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck + return Stream.of( + Arguments.of("test.war", "test.war"), + Arguments.of("a/b/c/test.war", "test.war"), + Arguments.of("bar%2Fbaz/test.war", "test.war"), + Arguments.of("fizz buzz/test.war", "test.war"), + Arguments.of("another one/bites the dust/", "bites the dust"), + Arguments.of("another+one/bites+the+dust/", "bites+the+dust"), + Arguments.of("another%20one/bites%20the%20dust/", "bites%20the%20dust"), + Arguments.of("spanish/n\u00FAmero.war", "n\u00FAmero.war"), + Arguments.of("spanish/n%C3%BAmero.war", "n%C3%BAmero.war"), + Arguments.of("a/b!/", "b"), + Arguments.of("a/b!/c/", "b"), + Arguments.of("a/b!/c/d/", "b"), + Arguments.of("a/b%21/", "b%21") + ); + } + + /** + * Using FileSystem provided URIs, attempt to get last URI path segment + */ + @ParameterizedTest + @MethodSource("resourceUriLastSegmentSource") + public void testFileUriGetUriLastPathSegment(String basePath, String expectedName) throws IOException + { + Path root = workDir.getPath(); + Path base = root.resolve(basePath); + if (basePath.endsWith("/")) + { + FS.ensureDirExists(base); + } + else + { + FS.ensureDirExists(base.getParent()); + FS.touch(base); + } + URI uri = base.toUri(); + if (OS.MAC.isCurrentOs()) + { + // Normalize Unicode to NFD form that OSX Path/FileSystem produces + expectedName = Normalizer.normalize(expectedName, Normalizer.Form.NFD); + } + assertThat(URIUtil.getUriLastPathSegment(uri), is(expectedName)); + } + + public static Stream uriLastSegmentSource() throws URISyntaxException, IOException + { + final String TEST_RESOURCE_JAR = "test-base-resource.jar"; + Path testJar = MavenTestingUtils.getTestResourcePathFile(TEST_RESOURCE_JAR); + URI uri = new URI("jar", testJar.toUri().toASCIIString(), null); + + Map env = new HashMap<>(); + env.put("multi-release", "runtime"); + + List arguments = new ArrayList<>(); + arguments.add(Arguments.of(uri, TEST_RESOURCE_JAR)); + try (FileSystem zipFs = FileSystems.newFileSystem(uri, env)) + { + FileVisitOption[] fileVisitOptions = new FileVisitOption[]{}; + + for (Path root : zipFs.getRootDirectories()) + { + Stream entryStream = Files.find(root, 10, (path, attrs) -> true, fileVisitOptions); + entryStream.forEach((path) -> + { + if (path.toString().endsWith("!/")) + { + // skip - JAR entry type not supported by Jetty + // TODO: re-enable once we start to use zipfs + LOG.warn("Skipping Unsupported entry: " + path.toUri()); + } + else + { + arguments.add(Arguments.of(path.toUri(), TEST_RESOURCE_JAR)); + } + }); + } + } + + return arguments.stream(); + } + + /** + * Tests of URIs last segment, including "jar:file:" based URIs. + */ + @ParameterizedTest + @MethodSource("uriLastSegmentSource") + public void testGetUriLastPathSegment(URI uri, String expectedName) + { + assertThat(URIUtil.getUriLastPathSegment(uri), is(expectedName)); + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java index a517404d97a..d528cf6d171 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; @@ -39,6 +39,7 @@ import static org.junit.jupiter.api.DynamicTest.dynamicTest; /** * URL Encoding / Decoding Tests */ +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck public class URLEncodedTest { @TestFactory @@ -48,111 +49,111 @@ public class URLEncodedTest tests.add(dynamicTest("Initially not empty", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - assertEquals(0, url_encoded.size()); + UrlEncoded urlEncoded = new UrlEncoded(); + assertEquals(0, urlEncoded.size()); })); tests.add(dynamicTest("Not empty after decode(\"\")", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode(""); - assertEquals(0, url_encoded.size()); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode(""); + assertEquals(0, urlEncoded.size()); })); tests.add(dynamicTest("Simple encode", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name1=Value1"); - assertEquals(1, url_encoded.size(), "simple param size"); - assertEquals("Name1=Value1", url_encoded.encode(), "simple encode"); - assertEquals("Value1", url_encoded.getString("Name1"), "simple get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name1=Value1"); + assertEquals(1, urlEncoded.size(), "simple param size"); + assertEquals("Name1=Value1", urlEncoded.encode(), "simple encode"); + assertEquals("Value1", urlEncoded.getString("Name1"), "simple get"); })); tests.add(dynamicTest("Dangling param", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name2="); - assertEquals(1, url_encoded.size(), "dangling param size"); - assertEquals("Name2", url_encoded.encode(), "dangling encode"); - assertEquals("", url_encoded.getString("Name2"), "dangling get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name2="); + assertEquals(1, urlEncoded.size(), "dangling param size"); + assertEquals("Name2", urlEncoded.encode(), "dangling encode"); + assertEquals("", urlEncoded.getString("Name2"), "dangling get"); })); tests.add(dynamicTest("noValue param", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name3"); - assertEquals(1, url_encoded.size(), "noValue param size"); - assertEquals("Name3", url_encoded.encode(), "noValue encode"); - assertEquals("", url_encoded.getString("Name3"), "noValue get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name3"); + assertEquals(1, urlEncoded.size(), "noValue param size"); + assertEquals("Name3", urlEncoded.encode(), "noValue encode"); + assertEquals("", urlEncoded.getString("Name3"), "noValue get"); })); tests.add(dynamicTest("badly encoded param", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name4=V\u0629lue+4%21"); - assertEquals(1, url_encoded.size(), "encoded param size"); - assertEquals("Name4=V%D8%A9lue+4%21", url_encoded.encode(), "encoded encode"); - assertEquals("V\u0629lue 4!", url_encoded.getString("Name4"), "encoded get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name4=V\u0629lue+4%21"); + assertEquals(1, urlEncoded.size(), "encoded param size"); + assertEquals("Name4=V%D8%A9lue+4%21", urlEncoded.encode(), "encoded encode"); + assertEquals("V\u0629lue 4!", urlEncoded.getString("Name4"), "encoded get"); })); tests.add(dynamicTest("encoded param 1", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name4=Value%2B4%21"); - assertEquals(1, url_encoded.size(), "encoded param size"); - assertEquals("Name4=Value%2B4%21", url_encoded.encode(), "encoded encode"); - assertEquals("Value+4!", url_encoded.getString("Name4"), "encoded get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name4=Value%2B4%21"); + assertEquals(1, urlEncoded.size(), "encoded param size"); + assertEquals("Name4=Value%2B4%21", urlEncoded.encode(), "encoded encode"); + assertEquals("Value+4!", urlEncoded.getString("Name4"), "encoded get"); })); tests.add(dynamicTest("encoded param 2", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name4=Value+4%21%20%214"); - assertEquals(1, url_encoded.size(), "encoded param size"); - assertEquals("Name4=Value+4%21+%214", url_encoded.encode(), "encoded encode"); - assertEquals("Value 4! !4", url_encoded.getString("Name4"), "encoded get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name4=Value+4%21%20%214"); + assertEquals(1, urlEncoded.size(), "encoded param size"); + assertEquals("Name4=Value+4%21+%214", urlEncoded.encode(), "encoded encode"); + assertEquals("Value 4! !4", urlEncoded.getString("Name4"), "encoded get"); })); tests.add(dynamicTest("multi param", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name5=aaa&Name6=bbb"); - assertEquals(2, url_encoded.size(), "multi param size"); - assertTrue(url_encoded.encode().equals("Name5=aaa&Name6=bbb") || - url_encoded.encode().equals("Name6=bbb&Name5=aaa"), - "multi encode " + url_encoded.encode()); - assertEquals("aaa", url_encoded.getString("Name5"), "multi get"); - assertEquals("bbb", url_encoded.getString("Name6"), "multi get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name5=aaa&Name6=bbb"); + assertEquals(2, urlEncoded.size(), "multi param size"); + assertTrue(urlEncoded.encode().equals("Name5=aaa&Name6=bbb") || + urlEncoded.encode().equals("Name6=bbb&Name5=aaa"), + "multi encode " + urlEncoded.encode()); + assertEquals("aaa", urlEncoded.getString("Name5"), "multi get"); + assertEquals("bbb", urlEncoded.getString("Name6"), "multi get"); })); tests.add(dynamicTest("multiple value encoded", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name7=aaa&Name7=b%2Cb&Name7=ccc"); - assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", url_encoded.encode(), "multi encode"); - assertEquals("aaa,b,b,ccc", url_encoded.getString("Name7"), "list get all"); - assertEquals("aaa", url_encoded.getValues("Name7").get(0), "list get"); - assertEquals("b,b", url_encoded.getValues("Name7").get(1), "list get"); - assertEquals("ccc", url_encoded.getValues("Name7").get(2), "list get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name7=aaa&Name7=b%2Cb&Name7=ccc"); + assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", urlEncoded.encode(), "multi encode"); + assertEquals("aaa,b,b,ccc", urlEncoded.getString("Name7"), "list get all"); + assertEquals("aaa", urlEncoded.getValues("Name7").get(0), "list get"); + assertEquals("b,b", urlEncoded.getValues("Name7").get(1), "list get"); + assertEquals("ccc", urlEncoded.getValues("Name7").get(2), "list get"); })); tests.add(dynamicTest("encoded param", () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.clear(); - url_encoded.decode("Name8=xx%2C++yy++%2Czz"); - assertEquals(1, url_encoded.size(), "encoded param size"); - assertEquals("Name8=xx%2C++yy++%2Czz", url_encoded.encode(), "encoded encode"); - assertEquals("xx, yy ,zz", url_encoded.getString("Name8"), "encoded get"); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.clear(); + urlEncoded.decode("Name8=xx%2C++yy++%2Czz"); + assertEquals(1, urlEncoded.size(), "encoded param size"); + assertEquals("Name8=xx%2C++yy++%2Czz", urlEncoded.encode(), "encoded encode"); + assertEquals("xx, yy ,zz", urlEncoded.getString("Name8"), "encoded get"); })); return tests.iterator(); @@ -167,7 +168,7 @@ public class URLEncodedTest {StringUtil.__ISO_8859_1, StringUtil.__ISO_8859_1, "%30"}, {StringUtil.__UTF8, StringUtil.__UTF8, "%30"}, {StringUtil.__UTF16, StringUtil.__UTF16, "%00%30"}, - }; + }; // Note: "%30" -> decode -> "0" @@ -229,29 +230,29 @@ public class URLEncodedTest public void testUtf8() throws Exception { - UrlEncoded url_encoded = new UrlEncoded(); - assertEquals(0, url_encoded.size(), "Empty"); + UrlEncoded urlEncoded = new UrlEncoded(); + assertEquals(0, urlEncoded.size(), "Empty"); - url_encoded.clear(); - url_encoded.decode("text=%E0%B8%9F%E0%B8%AB%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%81%E0%B8%9F%E0%B8%A7%E0%B8%AB%E0%B8%AA%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%AB%E0%B8%9F%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%AA%E0%B8%B2%E0%B8%9F%E0%B8%81%E0%B8%AB%E0%B8%A3%E0%B8%94%E0%B9%89%E0%B8%9F%E0%B8%AB%E0%B8%99%E0%B8%81%E0%B8%A3%E0%B8%94%E0%B8%B5&Action=Submit"); + urlEncoded.clear(); + urlEncoded.decode("text=%E0%B8%9F%E0%B8%AB%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%81%E0%B8%9F%E0%B8%A7%E0%B8%AB%E0%B8%AA%E0%B8%94%E0%B8%B2%E0%B9%88%E0%B8%AB%E0%B8%9F%E0%B8%81%E0%B8%A7%E0%B8%94%E0%B8%AA%E0%B8%B2%E0%B8%9F%E0%B8%81%E0%B8%AB%E0%B8%A3%E0%B8%94%E0%B9%89%E0%B8%9F%E0%B8%AB%E0%B8%99%E0%B8%81%E0%B8%A3%E0%B8%94%E0%B8%B5&Action=Submit"); String hex = "E0B89FE0B8ABE0B881E0B8A7E0B894E0B8B2E0B988E0B881E0B89FE0B8A7E0B8ABE0B8AAE0B894E0B8B2E0B988E0B8ABE0B89FE0B881E0B8A7E0B894E0B8AAE0B8B2E0B89FE0B881E0B8ABE0B8A3E0B894E0B989E0B89FE0B8ABE0B899E0B881E0B8A3E0B894E0B8B5"; String expected = new String(TypeUtil.fromHexString(hex), "utf-8"); - assertEquals(expected, url_encoded.getString("text")); + assertEquals(expected, urlEncoded.getString("text")); } @Test - public void testUtf8_MultiByteCodePoint() + public void testUtf8MultiByteCodePoint() { String input = "text=test%C3%A4"; - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.decode(input); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.decode(input); // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00e4&mode=hex // Should be "testä" // "test" followed by a LATIN SMALL LETTER A WITH DIAERESIS String expected = "test\u00e4"; - assertThat(url_encoded.getString("text"), is(expected)); + assertThat(urlEncoded.getString("text"), is(expected)); } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/UptimeTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/UptimeTest.java index 4d64c4e1cf6..8e31fe80c9a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/UptimeTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/UptimeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedInvalidEncodingTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedInvalidEncodingTest.java index fb6bd52b7b1..4df751118c9 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedInvalidEncodingTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedInvalidEncodingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; @@ -51,8 +51,8 @@ public class UrlEncodedInvalidEncodingTest { assertThrows(expectedThrowable, () -> { - UrlEncoded url_encoded = new UrlEncoded(); - url_encoded.decode(inputString, charset); + UrlEncoded urlEncoded = new UrlEncoded(); + urlEncoded.decode(inputString, charset); }); } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedUtf8Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedUtf8Test.java index 57f82cfd330..f253d65af7c 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedUtf8Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedUtf8Test.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; @@ -22,9 +22,9 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -32,8 +32,7 @@ import static org.junit.jupiter.api.Assertions.fail; public class UrlEncodedUtf8Test { - - static final Logger LOG = Log.getLogger(UrlEncodedUtf8Test.class); + private static final Logger LOG = LoggerFactory.getLogger(UrlEncodedUtf8Test.class); @Test public void testIncompleteSequestAtTheEnd() throws Exception @@ -96,7 +95,7 @@ public class UrlEncodedUtf8Test { if (!thrown) throw e; - LOG.ignore(e); + LOG.trace("IGNORED", e); } } @@ -116,7 +115,7 @@ public class UrlEncodedUtf8Test { if (!thrown) throw e; - LOG.ignore(e); + LOG.trace("IGNORED", e); } } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8AppendableTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8AppendableTest.java index 916bd908160..0a944f66c58 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8AppendableTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8AppendableTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; @@ -39,6 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.DynamicTest.dynamicTest; +// @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck public class Utf8AppendableTest { public static final List> APPENDABLE_IMPLS; @@ -157,7 +158,7 @@ public class Utf8AppendableTest @ParameterizedTest @MethodSource("implementations") - public void testFastFail_1(Class impl) throws Exception + public void testFastFail1(Class impl) throws Exception { byte[] part1 = TypeUtil.fromHexString("cebae1bdb9cf83cebcceb5"); byte[] part2 = TypeUtil.fromHexString("f4908080"); // INVALID @@ -177,7 +178,7 @@ public class Utf8AppendableTest @ParameterizedTest @MethodSource("implementations") - public void testFastFail_2(Class impl) throws Exception + public void testFastFail2(Class impl) throws Exception { byte[] part1 = TypeUtil.fromHexString("cebae1bdb9cf83cebcceb5f4"); byte[] part2 = TypeUtil.fromHexString("90"); // INVALID @@ -197,7 +198,7 @@ public class Utf8AppendableTest @ParameterizedTest @MethodSource("implementations") - public void testPartial_UnsplitCodepoint(Class impl) throws Exception + public void testPartialUnsplitCodepoint(Class impl) throws Exception { Utf8Appendable utf8 = impl.getDeclaredConstructor().newInstance(); @@ -216,7 +217,7 @@ public class Utf8AppendableTest @ParameterizedTest @MethodSource("implementations") - public void testPartial_SplitCodepoint(Class impl) throws Exception + public void testPartialSplitCodepoint(Class impl) throws Exception { Utf8Appendable utf8 = impl.getDeclaredConstructor().newInstance(); @@ -235,7 +236,7 @@ public class Utf8AppendableTest @ParameterizedTest @MethodSource("implementations") - public void testPartial_SplitCodepoint_WithNoBuf(Class impl) throws Exception + public void testPartialSplitCodepointWithNoBuf(Class impl) throws Exception { Utf8Appendable utf8 = impl.getDeclaredConstructor().newInstance(); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java index eb8c5729513..2e193cb91a2 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/ContainerLifeCycleTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/ContainerLifeCycleTest.java index b9e5f593f9e..7221f57f423 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/ContainerLifeCycleTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/ContainerLifeCycleTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.component; @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.StringReader; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jetty.util.TypeUtil; @@ -129,10 +130,7 @@ public class ContainerLifeCycleTest container.stop(); container.destroy(); - assertThrows(IllegalStateException.class, () -> - { - container.start(); - }); + assertThrows(IllegalStateException.class, container::start); } @Test @@ -210,13 +208,13 @@ public class ContainerLifeCycleTest { ContainerLifeCycle a0 = new ContainerLifeCycle(); String dump = trim(a0.dump()); - dump = check(dump, "ContainerLifeCycl"); + check(dump, "ContainerLifeCycl"); ContainerLifeCycle aa0 = new ContainerLifeCycle(); a0.addBean(aa0); dump = trim(a0.dump()); dump = check(dump, "ContainerLifeCycl"); - dump = check(dump, "+? ContainerLife"); + check(dump, "+? ContainerLife"); ContainerLifeCycle aa1 = new ContainerLifeCycle(); a0.addBean(aa1); @@ -224,7 +222,7 @@ public class ContainerLifeCycleTest dump = check(dump, "ContainerLifeCycl"); dump = check(dump, "+? ContainerLife"); dump = check(dump, "+? ContainerLife"); - dump = check(dump, ""); + check(dump, ""); ContainerLifeCycle aa2 = new ContainerLifeCycle(); a0.addBean(aa2, false); @@ -233,7 +231,7 @@ public class ContainerLifeCycleTest dump = check(dump, "+? ContainerLife"); dump = check(dump, "+? ContainerLife"); dump = check(dump, "+~ ContainerLife"); - dump = check(dump, ""); + check(dump, ""); aa1.start(); a0.start(); @@ -242,7 +240,7 @@ public class ContainerLifeCycleTest dump = check(dump, "+= ContainerLife"); dump = check(dump, "+~ ContainerLife"); dump = check(dump, "+~ ContainerLife"); - dump = check(dump, ""); + check(dump, ""); a0.manage(aa1); a0.removeBean(aa2); @@ -250,7 +248,7 @@ public class ContainerLifeCycleTest dump = check(dump, "ContainerLifeCycl"); dump = check(dump, "+= ContainerLife"); dump = check(dump, "+= ContainerLife"); - dump = check(dump, ""); + check(dump, ""); ContainerLifeCycle aaa0 = new ContainerLifeCycle(); aa0.addBean(aaa0); @@ -259,7 +257,7 @@ public class ContainerLifeCycleTest dump = check(dump, "+= ContainerLife"); dump = check(dump, "| +~ Container"); dump = check(dump, "+= ContainerLife"); - dump = check(dump, ""); + check(dump, ""); ContainerLifeCycle aa10 = new ContainerLifeCycle(); aa1.addBean(aa10, true); @@ -269,7 +267,7 @@ public class ContainerLifeCycleTest dump = check(dump, "| +~ Container"); dump = check(dump, "+= ContainerLife"); dump = check(dump, " += Container"); - dump = check(dump, ""); + check(dump, ""); final ContainerLifeCycle a1 = new ContainerLifeCycle(); final ContainerLifeCycle a2 = new ContainerLifeCycle(); @@ -301,7 +299,7 @@ public class ContainerLifeCycleTest dump = check(dump, " +> java.util.Arrays$ArrayList"); dump = check(dump, " +: ContainerLifeCycle"); dump = check(dump, " +: ContainerLifeCycle"); - dump = check(dump, ""); + check(dump, ""); a2.addBean(aa0, true); dump = trim(a0.dump()); @@ -319,7 +317,7 @@ public class ContainerLifeCycleTest dump = check(dump, " +> java.util.Arrays$ArrayList"); dump = check(dump, " +: ContainerLifeCycle"); dump = check(dump, " +: ContainerLifeCycle"); - dump = check(dump, ""); + check(dump, ""); a2.unmanage(aa0); dump = trim(a0.dump()); @@ -336,7 +334,7 @@ public class ContainerLifeCycleTest dump = check(dump, " +> java.util.Arrays$ArrayList"); dump = check(dump, " +: ContainerLifeCycle"); dump = check(dump, " +: ContainerLifeCycle"); - dump = check(dump, ""); + check(dump, ""); a0.unmanage(aa); dump = trim(a0.dump()); @@ -346,7 +344,7 @@ public class ContainerLifeCycleTest dump = check(dump, "+= ContainerLife"); dump = check(dump, "| += Container"); dump = check(dump, "+~ ContainerLife"); - dump = check(dump, ""); + check(dump, ""); } @Test @@ -377,9 +375,8 @@ public class ContainerLifeCycleTest child.add(c); } - public @Override - String toString() + public String toString() { return "listener"; } @@ -387,18 +384,16 @@ public class ContainerLifeCycleTest ContainerLifeCycle c0 = new ContainerLifeCycle() { - public @Override - String toString() + public String toString() { return "c0"; } }; ContainerLifeCycle c00 = new ContainerLifeCycle() { - public @Override - String toString() + public String toString() { return "c00"; } @@ -439,9 +434,8 @@ public class ContainerLifeCycleTest child.add(c); } - public @Override - String toString() + public String toString() { return "inherited"; } @@ -449,6 +443,11 @@ public class ContainerLifeCycleTest c0.addBean(inherited); + assertEquals("listener", handled.poll()); + assertEquals("added", operation.poll()); + assertEquals(c0, parent.poll()); + assertEquals(inherited, child.poll()); + assertEquals("inherited", handled.poll()); assertEquals("added", operation.poll()); assertEquals(c0, parent.poll()); @@ -459,11 +458,6 @@ public class ContainerLifeCycleTest assertEquals(c0, parent.poll()); assertEquals(listener, child.poll()); - assertEquals("listener", handled.poll()); - assertEquals("added", operation.poll()); - assertEquals(c0, parent.poll()); - assertEquals(inherited, child.poll()); - assertEquals("inherited", handled.poll()); assertEquals("added", operation.poll()); assertEquals(c0, parent.poll()); @@ -504,7 +498,7 @@ public class ContainerLifeCycleTest assertEquals(c00, child.poll()); } - private final class InheritedListenerLifeCycle extends AbstractLifeCycle implements Container.InheritedListener + private static final class InheritedListenerLifeCycle extends AbstractLifeCycle implements Container.InheritedListener { @Override public void beanRemoved(Container p, Object c) @@ -528,27 +522,24 @@ public class ContainerLifeCycleTest { ContainerLifeCycle c0 = new ContainerLifeCycle() { - public @Override - String toString() + public String toString() { return "c0"; } }; ContainerLifeCycle c00 = new ContainerLifeCycle() { - public @Override - String toString() + public String toString() { return "c00"; } }; ContainerLifeCycle c01 = new ContainerLifeCycle() { - public @Override - String toString() + public String toString() { return "c01"; } @@ -627,7 +618,7 @@ public class ContainerLifeCycleTest } @Test - public void testGetBeans() throws Exception + public void testGetBeans() { TestContainerLifeCycle root = new TestContainerLifeCycle(); TestContainerLifeCycle left = new TestContainerLifeCycle(); @@ -652,4 +643,94 @@ public class ContainerLifeCycleTest assertThat(root.getContainedBeans(Integer.class), containsInAnyOrder(0, 1, 2, 3, 4)); assertThat(root.getContainedBeans(String.class), containsInAnyOrder("leaf")); } + + @Test + public void testBeanStoppingAddedToStartingBean() throws Exception + { + ContainerLifeCycle longLived = new ContainerLifeCycle() + { + @Override + protected void doStop() throws Exception + { + super.doStop(); + + ContainerLifeCycle shortLived = new ContainerLifeCycle(); + shortLived.addBean(this); + shortLived.start(); + + assertTrue(shortLived.isStarted()); + assertTrue(isStopping()); + assertFalse(shortLived.isManaged(this)); + } + }; + longLived.start(); + longLived.stop(); + } + + @Test + public void testFailedManagedBeanCanBeRestarted() throws Exception + { + AtomicBoolean fail = new AtomicBoolean(); + ContainerLifeCycle container = new ContainerLifeCycle(); + ContainerLifeCycle bean1 = new ContainerLifeCycle(); + ContainerLifeCycle bean2 = new ContainerLifeCycle() + { + @Override + protected void doStart() throws Exception + { + super.doStart(); + // Fail only the first time. + if (fail.compareAndSet(false, true)) + throw new RuntimeException(); + } + }; + ContainerLifeCycle bean3 = new ContainerLifeCycle(); + container.addBean(bean1); + container.addBean(bean2); + container.addBean(bean3); + + // Start the first time, it should fail. + assertThrows(RuntimeException.class, container::start); + assertTrue(container.isFailed()); + assertTrue(bean1.isStopped()); + assertTrue(bean2.isFailed()); + assertTrue(bean3.isStopped()); + + // Re-start, it should succeed. + container.start(); + assertTrue(container.isStarted()); + assertTrue(bean1.isStarted()); + assertTrue(bean2.isStarted()); + assertTrue(bean3.isStarted()); + } + + @Test + public void testFailedAutoBeanIsNotRestarted() throws Exception + { + AtomicBoolean fail = new AtomicBoolean(); + ContainerLifeCycle bean = new ContainerLifeCycle() + { + @Override + protected void doStart() throws Exception + { + super.doStart(); + // Fail only the first time. + if (fail.compareAndSet(false, true)) + throw new RuntimeException(); + } + }; + // The bean is started externally and fails. + assertThrows(RuntimeException.class, bean::start); + + // The same bean now becomes part of a container. + ContainerLifeCycle container = new ContainerLifeCycle(); + container.addBean(bean); + assertTrue(container.isAuto(bean)); + + // Start the container, the bean must not be managed. + container.start(); + assertTrue(container.isStarted()); + assertTrue(bean.isFailed()); + assertTrue(container.isUnmanaged(bean)); + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/DumpableTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/DumpableTest.java index d586772ebf6..38f0436448a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/DumpableTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/DumpableTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.component; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerNestedTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerNestedTest.java index 18f475ab8e7..6df87593a54 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerNestedTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerNestedTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.component; @@ -37,7 +37,7 @@ import static org.hamcrest.Matchers.is; public class LifeCycleListenerNestedTest { // Set this true to use test-specific workaround. - private final boolean WORKAROUND = false; + private final boolean workaround = false; public static class Foo extends ContainerLifeCycle { @@ -161,7 +161,7 @@ public class LifeCycleListenerNestedTest { if (child instanceof LifeCycle) { - ((LifeCycle)child).addLifeCycleListener(this); + ((LifeCycle)child).addEventListener(this); } } @@ -170,13 +170,13 @@ public class LifeCycleListenerNestedTest { if (child instanceof LifeCycle) { - ((LifeCycle)child).removeLifeCycleListener(this); + ((LifeCycle)child).removeEventListener(this); } } } @Test - public void testAddBean_AddListener_Start() throws Exception + public void testAddBeanAddListenerStart() throws Exception { Foo foo = new Foo(); Bar bara = new Bar("a"); @@ -185,8 +185,8 @@ public class LifeCycleListenerNestedTest foo.addBean(barb); CapturingListener listener = new CapturingListener(); - foo.addLifeCycleListener(listener); - if (WORKAROUND) + foo.addEventListener(listener); + if (workaround) foo.addEventListener(listener); try @@ -211,13 +211,13 @@ public class LifeCycleListenerNestedTest } @Test - public void testAddListener_AddBean_Start() throws Exception + public void testAddListenerAddBeanStart() throws Exception { Foo foo = new Foo(); CapturingListener listener = new CapturingListener(); - foo.addLifeCycleListener(listener); - if (WORKAROUND) + foo.addEventListener(listener); + if (workaround) foo.addEventListener(listener); Bar bara = new Bar("a"); @@ -247,15 +247,15 @@ public class LifeCycleListenerNestedTest } @Test - public void testAddListener_Start_AddBean() throws Exception + public void testAddListenerStartAddBean() throws Exception { Foo foo = new Foo(); Bar bara = new Bar("a"); Bar barb = new Bar("b"); CapturingListener listener = new CapturingListener(); - foo.addLifeCycleListener(listener); - if (WORKAROUND) + foo.addEventListener(listener); + if (workaround) foo.addEventListener(listener); try diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java index 651f3bfe5c0..8e0f7656391 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java @@ -1,26 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.component; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.logging.StacklessLogging; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -36,7 +36,7 @@ public class LifeCycleListenerTest { TestLifeCycle lifecycle = new TestLifeCycle(); TestListener listener = new TestListener(); - lifecycle.addLifeCycleListener(listener); + lifecycle.addEventListener(listener); lifecycle.setCause(cause); @@ -72,7 +72,7 @@ public class LifeCycleListenerTest { TestLifeCycle lifecycle = new TestLifeCycle(); TestListener listener = new TestListener(); - lifecycle.addLifeCycleListener(listener); + lifecycle.addEventListener(listener); // need to set the state to something other than stopped or stopping or // else @@ -116,11 +116,11 @@ public class LifeCycleListenerTest { TestLifeCycle lifecycle = new TestLifeCycle(); TestListener listener = new TestListener(); - lifecycle.addLifeCycleListener(listener); + lifecycle.addEventListener(listener); lifecycle.start(); assertTrue(listener.starting, "The starting event didn't occur"); - lifecycle.removeLifeCycleListener(listener); + lifecycle.removeEventListener(listener); lifecycle.stop(); assertFalse(listener.stopping, "The stopping event occurred"); } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Blue.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/Blue.java deleted file mode 100644 index a4dbadfb166..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Blue.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -public class Blue -{ - private static final Logger LOG = Log.getLogger(Blue.class); - - public void generateLogs() - { - LOG.debug("My color is {}", Blue.class.getSimpleName()); - LOG.info("I represent the emotion Admiration"); - LOG.warn("I can also mean Disgust"); - LOG.ignore(new RuntimeException("Yawn")); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java deleted file mode 100644 index dad64b28d72..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.logging.Handler; -import java.util.logging.LogRecord; - -import org.eclipse.jetty.util.IO; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; - -public class CapturingJULHandler extends Handler -{ - private static final String LN = System.getProperty("line.separator"); - private StringBuilder output = new StringBuilder(); - - @Override - public void publish(LogRecord record) - { - StringBuilder buf = new StringBuilder(); - buf.append(record.getLevel().getName()).append("|"); - buf.append(record.getLoggerName()).append("|"); - buf.append(record.getMessage()); - - output.append(buf); - if (record.getMessage().length() > 0) - { - output.append(LN); - } - - if (record.getThrown() != null) - { - StringWriter sw = new StringWriter(128); - PrintWriter capture = new PrintWriter(sw); - record.getThrown().printStackTrace(capture); - capture.flush(); - output.append(sw.toString()); - IO.close(capture); - } - } - - public void clear() - { - output.setLength(0); - } - - @Override - public void flush() - { - /* do nothing */ - } - - @Override - public void close() throws SecurityException - { - /* do nothing */ - } - - public void dump() - { - System.out.println(output); - } - - public void assertContainsLine(String line) - { - assertThat(output.toString(), containsString(line)); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Green.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/Green.java deleted file mode 100644 index 329fb11ee9a..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Green.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -public class Green -{ - private static final Logger LOG = Log.getLogger(Green.class); - - public void generateLogs() - { - LOG.debug("My color is {}", Green.class.getSimpleName()); - LOG.info("I represent the emotion Trust"); - LOG.warn("I can also mean Fear"); - LOG.ignore(new RuntimeException("Ick")); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java deleted file mode 100644 index 85a1db3c361..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java +++ /dev/null @@ -1,243 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogManager; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class JavaUtilLogTest -{ - private static Handler[] originalHandlers; - private static CapturingJULHandler jul; - - @BeforeAll - public static void setJUL() - { - LogManager lmgr = LogManager.getLogManager(); - java.util.logging.Logger root = lmgr.getLogger(""); - // Remember original handlers - originalHandlers = root.getHandlers(); - // Remove original handlers - for (Handler existing : originalHandlers) - { - root.removeHandler(existing); - } - // Set test/capturing handler - jul = new CapturingJULHandler(); - root.addHandler(jul); - } - - @AfterAll - public static void restoreJUL() - { - LogManager lmgr = LogManager.getLogManager(); - java.util.logging.Logger root = lmgr.getLogger(""); - // Remove test handlers - for (Handler existing : root.getHandlers()) - { - root.removeHandler(existing); - } - // Restore original handlers - for (Handler original : originalHandlers) - { - root.addHandler(original); - } - } - - @Test - public void testNamedLogger() - { - jul.clear(); - JavaUtilLog log = new JavaUtilLog("test"); - log.info("Info test"); - - jul.assertContainsLine("INFO|test|Info test"); - - JavaUtilLog loglong = new JavaUtilLog("test.a.long.name"); - loglong.info("Long test"); - - jul.assertContainsLine("INFO|test.a.long.name|Long test"); - } - - @Test - public void testDebugOutput() - { - jul.clear(); - - // Common Throwable (for test) - Throwable th = new Throwable("Message"); - - // Capture raw string form - StringWriter tout = new StringWriter(); - th.printStackTrace(new PrintWriter(tout)); - String ths = tout.toString(); - - // Tests - JavaUtilLog log = new JavaUtilLog("test.de.bug"); - setJulLevel("test.de.bug", Level.FINE); - - log.debug("Simple debug"); - log.debug("Debug with {} parameter", 1); - log.debug("Debug with {} {} parameters", 2, "spiffy"); - log.debug("Debug with throwable", th); - log.debug(th); - - // jul.dump(); - - jul.assertContainsLine("FINE|test.de.bug|Simple debug"); - jul.assertContainsLine("FINE|test.de.bug|Debug with 1 parameter"); - jul.assertContainsLine("FINE|test.de.bug|Debug with 2 spiffy parameters"); - jul.assertContainsLine("FINE|test.de.bug|Debug with throwable"); - jul.assertContainsLine(ths); - } - - @Test - public void testInfoOutput() - { - jul.clear(); - - // Common Throwable (for test) - Throwable th = new Throwable("Message"); - - // Capture raw string form - StringWriter tout = new StringWriter(); - th.printStackTrace(new PrintWriter(tout)); - String ths = tout.toString(); - - // Tests - JavaUtilLog log = new JavaUtilLog("test.in.fo"); - setJulLevel("test.in.fo", Level.INFO); - - log.info("Simple info"); - log.info("Info with {} parameter", 1); - log.info("Info with {} {} parameters", 2, "spiffy"); - log.info("Info with throwable", th); - log.info(th); - - // jul.dump(); - - jul.assertContainsLine("INFO|test.in.fo|Simple info"); - jul.assertContainsLine("INFO|test.in.fo|Info with 1 parameter"); - jul.assertContainsLine("INFO|test.in.fo|Info with 2 spiffy parameters"); - jul.assertContainsLine("INFO|test.in.fo|Info with throwable"); - jul.assertContainsLine(ths); - } - - @Test - public void testWarnOutput() - { - jul.clear(); - - // Common Throwable (for test) - Throwable th = new Throwable("Message"); - - // Capture raw string form - StringWriter tout = new StringWriter(); - th.printStackTrace(new PrintWriter(tout)); - String ths = tout.toString(); - - // Tests - JavaUtilLog log = new JavaUtilLog("test.wa.rn"); - setJulLevel("test.wa.rn", Level.WARNING); - - log.warn("Simple warn"); - log.warn("Warn with {} parameter", 1); - log.warn("Warn with {} {} parameters", 2, "spiffy"); - log.warn("Warn with throwable", th); - log.warn(th); - - // jul.dump(); - - jul.assertContainsLine("WARNING|test.wa.rn|Simple warn"); - jul.assertContainsLine("WARNING|test.wa.rn|Warn with 1 parameter"); - jul.assertContainsLine("WARNING|test.wa.rn|Warn with 2 spiffy parameters"); - jul.assertContainsLine("WARNING|test.wa.rn|Warn with throwable"); - jul.assertContainsLine(ths); - } - - @Test - public void testFormattingWithNulls() - { - jul.clear(); - - JavaUtilLog log = new JavaUtilLog("test.nu.ll"); - setJulLevel("test.nu.ll", Level.INFO); - - log.info("Testing info(msg,null,null) - {} {}", "arg0", "arg1"); - log.info("Testing info(msg,null,null) - {}/{}", null, null); - log.info("Testing info(msg,null,null) > {}", null, null); - log.info("Testing info(msg,null,null)", null, null); - log.info(null, "Testing", "info(null,arg0,arg1)"); - log.info(null, null, null); - - //jul.dump(); - - jul.assertContainsLine("INFO|test.nu.ll|Testing info(msg,null,null) - null/null"); - jul.assertContainsLine("INFO|test.nu.ll|Testing info(msg,null,null) > null null"); - jul.assertContainsLine("INFO|test.nu.ll|Testing info(msg,null,null) null null"); - jul.assertContainsLine("INFO|test.nu.ll|null Testing info(null,arg0,arg1)"); - jul.assertContainsLine("INFO|test.nu.ll|null null null"); - } - - @Test - public void testIsDebugEnabled() - { - JavaUtilLog log = new JavaUtilLog("test.legacy"); - - setJulLevel("test.legacy", Level.ALL); - assertThat("log.level(all).isDebugEnabled", log.isDebugEnabled(), is(true)); - - setJulLevel("test.legacy", Level.FINEST); - assertThat("log.level(finest).isDebugEnabled", log.isDebugEnabled(), is(true)); - - setJulLevel("test.legacy", Level.FINER); - assertThat("log.level(finer).isDebugEnabled", log.isDebugEnabled(), is(true)); - - setJulLevel("test.legacy", Level.FINE); - assertThat("log.level(fine).isDebugEnabled", log.isDebugEnabled(), is(true)); - - setJulLevel("test.legacy", Level.INFO); - assertThat("log.level(info).isDebugEnabled", log.isDebugEnabled(), is(false)); - - setJulLevel("test.legacy", Level.WARNING); - assertThat("log.level(warn).isDebugEnabled", log.isDebugEnabled(), is(false)); - - log.setDebugEnabled(true); - assertThat("log.isDebugEnabled", log.isDebugEnabled(), is(true)); - - log.setDebugEnabled(false); - assertThat("log.isDebugEnabled", log.isDebugEnabled(), is(false)); - } - - private void setJulLevel(String name, Level lvl) - { - java.util.logging.Logger log = java.util.logging.Logger.getLogger(name); - log.setLevel(lvl); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java deleted file mode 100644 index cbe6fe7f5c1..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java +++ /dev/null @@ -1,140 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Stream; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class LogTest -{ - private static Logger originalLogger; - private static Map originalLoggers; - - @BeforeAll - public static void rememberOriginalLogger() - { - originalLogger = Log.getLog(); - originalLoggers = new HashMap<>(Log.getLoggers()); - Log.getMutableLoggers().clear(); - } - - @AfterAll - public static void restoreOriginalLogger() - { - Log.setLog(originalLogger); - Log.getMutableLoggers().clear(); - Log.getMutableLoggers().putAll(originalLoggers); - } - - @Test - public void testDefaultLogging() - { - Logger log = Log.getLogger(LogTest.class); - log.info("Test default logging"); - } - - @Test - public void testNamedLogNamed_StdErrLog() - { - Log.setLog(new StdErrLog()); - - assertNamedLogging(Red.class); - assertNamedLogging(Blue.class); - assertNamedLogging(Green.class); - } - - @Test - public void testNamedLogNamed_JUL() - { - Log.setLog(new JavaUtilLog()); - - assertNamedLogging(Red.class); - assertNamedLogging(Blue.class); - assertNamedLogging(Green.class); - } - - @Test - public void testNamedLogNamed_Slf4J() throws Exception - { - Log.setLog(new Slf4jLog()); - - assertNamedLogging(Red.class); - assertNamedLogging(Blue.class); - assertNamedLogging(Green.class); - } - - private void assertNamedLogging(Class clazz) - { - Logger lc = Log.getLogger(clazz); - assertEquals(lc.getName(), clazz.getName(), "Named logging (impl=" + Log.getLog().getClass().getName() + ")"); - } - - public static Stream packageCases() - { - return Stream.of( - // null entry - Arguments.of(null, ""), - // empty entry - Arguments.of("", ""), - // all whitespace entry - Arguments.of(" \t ", ""), - // bad / invalid characters - Arguments.of("org.eclipse.Foo.\u0000", "oe.Foo"), - Arguments.of("org.eclipse.\u20ac.Euro", "oe\u20ac.Euro"), - // bad package segments - Arguments.of(".foo", "foo"), - Arguments.of(".bar.Foo", "b.Foo"), - Arguments.of("org...bar..Foo", "ob.Foo"), - Arguments.of("org . . . bar . . Foo ", "ob.Foo"), - Arguments.of("org . . . bar . . Foo ", "ob.Foo"), - // long-ish classname - Arguments.of("org.eclipse.jetty.websocket.common.extensions.compress.DeflateFrameExtension", "oejwcec.DeflateFrameExtension"), - // internal class - Arguments.of("org.eclipse.jetty.foo.Bar$Internal", "oejf.Bar$Internal") - ); - } - - @ParameterizedTest - @MethodSource("packageCases") - public void testCondensePackageViaLogger(String input, String expected) - { - StdErrLog log = new StdErrLog(); - StdErrLog logger = (StdErrLog)log.newLogger(input); - assertThat("log[" + input + "] condenses to name", logger._abbrevname, is(expected)); - } - - @ParameterizedTest - @MethodSource("packageCases") - public void testCondensePackageDirect(String input, String expected) - { - assertThat("log[" + input + "] condenses to name", AbstractLogger.condensePackageString(input), is(expected)); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/NamedLogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/NamedLogTest.java deleted file mode 100644 index 736cd816f91..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/NamedLogTest.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import org.junit.jupiter.api.Test; - -public class NamedLogTest -{ - @Test - public void testNamedLogging() - { - Red red = new Red(); - Green green = new Green(); - Blue blue = new Blue(); - - StdErrCapture output = new StdErrCapture(); - - setLoggerOptions(Red.class, output); - setLoggerOptions(Green.class, output); - setLoggerOptions(Blue.class, output); - - red.generateLogs(); - green.generateLogs(); - blue.generateLogs(); - - output.assertContains(Red.class.getName()); - output.assertContains(Green.class.getName()); - output.assertContains(Blue.class.getName()); - } - - private void setLoggerOptions(Class clazz, StdErrCapture output) - { - Logger logger = Log.getLogger(clazz); - logger.setDebugEnabled(true); - - if (logger instanceof StdErrLog) - { - StdErrLog sel = (StdErrLog)logger; - sel.setPrintLongNames(true); - output.capture(sel); - } - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Red.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/Red.java deleted file mode 100644 index 16f41dc6ad7..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Red.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -public class Red -{ - private static final Logger LOG = Log.getLogger(Red.class); - - public void generateLogs() - { - LOG.debug("My color is {}", Red.class.getSimpleName()); - LOG.info("I represent the emotion Love"); - LOG.warn("I can also mean Anger"); - LOG.ignore(new RuntimeException("Nom")); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Slf4jHelper.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/Slf4jHelper.java deleted file mode 100644 index 529da51c3bb..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/Slf4jHelper.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.io.File; -import java.io.FileFilter; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; - -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; - -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -public final class Slf4jHelper -{ - public static ClassLoader createTestClassLoader(ClassLoader parentClassLoader) throws MalformedURLException - { - File testJarDir = MavenTestingUtils.getTargetFile("test-jars"); - assumeTrue(testJarDir.exists()); // trigger @Ignore if dir not there - - File[] jarfiles = testJarDir.listFiles(new FileFilter() - { - public boolean accept(File path) - { - if (!path.isFile()) - { - return false; - } - return path.getName().endsWith(".jar"); - } - }); - - assumeTrue(jarfiles.length > 0); // trigger @Ignore if no jar files. - - URL[] urls = new URL[jarfiles.length]; - for (int i = 0; i < jarfiles.length; i++) - { - urls[i] = jarfiles[i].toURI().toURL(); - // System.out.println("Adding test-jar => " + urls[i]); - } - - return new URLClassLoader(urls, parentClassLoader); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java deleted file mode 100644 index cd94ef53493..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java +++ /dev/null @@ -1,70 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; - -public class StdErrCapture -{ - private ByteArrayOutputStream test; - private PrintStream err; - - public StdErrCapture(StdErrLog log) - { - this(); - log.setStdErrStream(err); - } - - public StdErrCapture() - { - test = new ByteArrayOutputStream(); - err = new PrintStream(test); - } - - public void capture(StdErrLog log) - { - log.setStdErrStream(err); - } - - public void assertContains(String expectedString) - { - err.flush(); - String output = new String(test.toByteArray()); - assertThat(output, containsString(expectedString)); - } - - public void assertNotContains(String unexpectedString) - { - err.flush(); - String output = new String(test.toByteArray()); - assertThat(output, not(containsString(unexpectedString))); - } - - @Override - public String toString() - { - err.flush(); - return new String(test.toByteArray()); - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java deleted file mode 100644 index 490d99e43c0..00000000000 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java +++ /dev/null @@ -1,771 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import java.util.Properties; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertSame; - -/** - * Tests for StdErrLog - */ -public class StdErrLogTest -{ - static - { - StdErrLog.setTagPad(0); - } - - @BeforeEach - public void before() - { - Thread.currentThread().setName("tname"); - } - - @Test - public void testStdErrLogFormat() throws UnsupportedEncodingException - { - StdErrLog log = new StdErrLog(LogTest.class.getName(), new Properties()); - StdErrCapture output = new StdErrCapture(log); - - log.info("testing:{},{}", "test", "format1"); - log.info("testing:{}", "test", "format2"); - log.info("testing", "test", "format3"); - log.info("testing:{},{}", "test", null); - log.info("testing {} {}", null, null); - log.info("testing:{}", null, null); - log.info("testing", null, null); - - System.err.println(output); - output.assertContains("INFO:oejul.LogTest:tname: testing:test,format1"); - output.assertContains("INFO:oejul.LogTest:tname: testing:test,format1"); - output.assertContains("INFO:oejul.LogTest:tname: testing:test format2"); - output.assertContains("INFO:oejul.LogTest:tname: testing test format3"); - output.assertContains("INFO:oejul.LogTest:tname: testing:test,null"); - output.assertContains("INFO:oejul.LogTest:tname: testing null null"); - output.assertContains("INFO:oejul.LogTest:tname: testing:null"); - output.assertContains("INFO:oejul.LogTest:tname: testing"); - } - - @Test - public void testStdErrLogDebug() - { - StdErrLog log = new StdErrLog("xxx", new Properties()); - StdErrCapture output = new StdErrCapture(log); - - log.setLevel(StdErrLog.LEVEL_DEBUG); - log.debug("testing {} {}", "test", "debug"); - log.info("testing {} {}", "test", "info"); - log.warn("testing {} {}", "test", "warn"); - log.setLevel(StdErrLog.LEVEL_INFO); - log.debug("YOU SHOULD NOT SEE THIS!", null, null); - - // Test for backward compat with old (now deprecated) method - Logger before = log.getLogger("before"); - log.setDebugEnabled(true); - Logger after = log.getLogger("after"); - before.debug("testing {} {}", "test", "debug-before"); - log.debug("testing {} {}", "test", "debug-deprecated"); - after.debug("testing {} {}", "test", "debug-after"); - - log.setDebugEnabled(false); - before.debug("testing {} {}", "test", "debug-before-false"); - log.debug("testing {} {}", "test", "debug-deprecated-false"); - after.debug("testing {} {}", "test", "debug-after-false"); - - output.assertContains("DBUG:xxx:tname: testing test debug"); - output.assertContains("INFO:xxx:tname: testing test info"); - output.assertContains("WARN:xxx:tname: testing test warn"); - output.assertNotContains("YOU SHOULD NOT SEE THIS!"); - output.assertContains("DBUG:x.before:tname: testing test debug-before"); - output.assertContains("DBUG:xxx:tname: testing test debug-deprecated"); - output.assertContains("DBUG:x.after:tname: testing test debug-after"); - output.assertNotContains("DBUG:x.before:tname: testing test debug-before-false"); - output.assertNotContains("DBUG:xxx:tname: testing test debug-deprecated-false"); - output.assertNotContains("DBUG:x.after:tname: testing test debug-after-false"); - } - - @Test - public void testStdErrLogName() - { - StdErrLog log = new StdErrLog("test", new Properties()); - log.setPrintLongNames(true); - StdErrCapture output = new StdErrCapture(log); - - assertThat("Log.name", log.getName(), is("test")); - Logger next = log.getLogger("next"); - assertThat("Log.name(child)", next.getName(), is("test.next")); - next.info("testing {} {}", "next", "info"); - - output.assertContains(":test.next:tname: testing next info"); - } - - @Test - public void testStdErrThrowable() - { - // Common Throwable (for test) - Throwable th = new Throwable("Message"); - - // Capture raw string form - StringWriter tout = new StringWriter(); - th.printStackTrace(new PrintWriter(tout)); - String ths = tout.toString(); - - // Start test - StdErrLog log = new StdErrLog("test", new Properties()); - StdErrCapture output = new StdErrCapture(log); - - log.warn("ex", th); - output.assertContains(ths); - - th = new Throwable("Message with \033 escape"); - - log.warn("ex", th); - output.assertNotContains("Message with \033 escape"); - log.info(th.toString()); - output.assertNotContains("Message with \033 escape"); - - log.warn("ex", th); - output.assertContains("Message with ? escape"); - log.info(th.toString()); - output.assertContains("Message with ? escape"); - } - - /** - * Test to make sure that using a Null parameter on parameterized messages does not result in a NPE - * - * @throws Exception failed test - */ - @Test - public void testParameterizedMessage_NullValues() throws Exception - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - log.setLevel(StdErrLog.LEVEL_DEBUG); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - log.info("Testing info(msg,null,null) - {} {}", "arg0", "arg1"); - log.info("Testing info(msg,null,null) - {} {}", null, null); - log.info("Testing info(msg,null,null) - {}", null, null); - log.info("Testing info(msg,null,null)", null, null); - log.info(null, "Testing", "info(null,arg0,arg1)"); - log.info(null, null, null); - - log.debug("Testing debug(msg,null,null) - {} {}", "arg0", "arg1"); - log.debug("Testing debug(msg,null,null) - {} {}", null, null); - log.debug("Testing debug(msg,null,null) - {}", null, null); - log.debug("Testing debug(msg,null,null)", null, null); - log.debug(null, "Testing", "debug(null,arg0,arg1)"); - log.debug(null, null, null); - - log.debug("Testing debug(msg,null)"); - log.debug(null, new Throwable("Testing debug(null,thrw)").fillInStackTrace()); - - log.warn("Testing warn(msg,null,null) - {} {}", "arg0", "arg1"); - log.warn("Testing warn(msg,null,null) - {} {}", null, null); - log.warn("Testing warn(msg,null,null) - {}", null, null); - log.warn("Testing warn(msg,null,null)", null, null); - log.warn(null, "Testing", "warn(msg,arg0,arg1)"); - log.warn(null, null, null); - - log.warn("Testing warn(msg,null)"); - log.warn(null, new Throwable("Testing warn(msg,thrw)").fillInStackTrace()); - } - } - - @Test - public void testGetLoggingLevel_Default() - { - Properties props = new Properties(); - - // Default Levels - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, null), "Default Logging Level"); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, ""), "Default Logging Level"); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty"), "Default Logging Level"); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, StdErrLogTest.class.getName()), "Default Logging Level"); - } - - @Test - public void testGetLoggingLevel_Bad() - { - Properties props = new Properties(); - props.setProperty("log.LEVEL", "WARN"); - props.setProperty("org.eclipse.jetty.bad.LEVEL", "EXPECTED_BAD_LEVEL"); - - // Default Level (because of bad level value) - assertEquals(StdErrLog.LEVEL_WARN, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.bad"), "Bad Logging Level"); - } - - @Test - public void testGetLoggingLevel_Lowercase() - { - Properties props = new Properties(); - props.setProperty("log.LEVEL", "warn"); - props.setProperty("org.eclipse.jetty.util.LEVEL", "info"); - - // Default Level - assertEquals(StdErrLog.LEVEL_WARN, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty"), "Lowercase Level"); - // Specific Level - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util"), "Lowercase Level"); - } - - @Test - public void testGetLoggingLevel_Root() - { - Properties props = new Properties(); - props.setProperty("log.LEVEL", "DEBUG"); - - // Default Levels - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, null), "Default Logging Level"); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, ""), "Default Logging Level"); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty"), "Default Logging Level"); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, StdErrLogTest.class.getName()), "Default Logging Level"); - } - - @Test - public void testGetLoggingLevel_FQCN() - { - String name = StdErrLogTest.class.getName(); - Properties props = new Properties(); - props.setProperty(name + ".LEVEL", "ALL"); - - // Default Levels - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, null)); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "")); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty")); - - // Specified Level - assertEquals(StdErrLog.LEVEL_ALL, StdErrLog.getLoggingLevel(props, name)); - } - - @Test - public void testGetLoggingLevel_UtilLevel() - { - Properties props = new Properties(); - props.setProperty("org.eclipse.jetty.util.LEVEL", "DEBUG"); - - // Default Levels - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, null)); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "")); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty")); - assertEquals(StdErrLog.LEVEL_INFO, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.server.BogusObject")); - - // Configured Level - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, StdErrLogTest.class.getName())); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util.Bogus")); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util")); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util.resource.PathResource")); - } - - @Test - public void testGetLoggingLevel_MixedLevels() - { - Properties props = new Properties(); - props.setProperty("log.LEVEL", "DEBUG"); - props.setProperty("org.eclipse.jetty.util.LEVEL", "WARN"); - props.setProperty("org.eclipse.jetty.util.ConcurrentHashMap.LEVEL", "ALL"); - - // Default Levels - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, null)); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "")); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty")); - assertEquals(StdErrLog.LEVEL_DEBUG, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.server.ServerObject")); - - // Configured Level - assertEquals(StdErrLog.LEVEL_WARN, StdErrLog.getLoggingLevel(props, StdErrLogTest.class.getName())); - assertEquals(StdErrLog.LEVEL_WARN, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util.MagicUtil")); - assertEquals(StdErrLog.LEVEL_WARN, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util")); - assertEquals(StdErrLog.LEVEL_WARN, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util.resource.PathResource")); - assertEquals(StdErrLog.LEVEL_ALL, StdErrLog.getLoggingLevel(props, "org.eclipse.jetty.util.ConcurrentHashMap")); - } - - /** - * Tests StdErrLog.warn() methods with level filtering. - *

      - * Should always see WARN level messages, regardless of set level. - * - * @throws UnsupportedEncodingException failed test - */ - @Test - public void testWarnFiltering() throws UnsupportedEncodingException - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - StdErrCapture output = new StdErrCapture(log); - - // Start with default level - log.warn("See Me"); - - // Set to debug level - log.setLevel(StdErrLog.LEVEL_DEBUG); - log.warn("Hear Me"); - - // Set to warn level - log.setLevel(StdErrLog.LEVEL_WARN); - log.warn("Cheer Me"); - - log.warn("", new Throwable("out of focus")); - log.warn(new Throwable("scene lost")); - - // Validate Output - // System.err.print(output); - output.assertContains("See Me"); - output.assertContains("Hear Me"); - output.assertContains("Cheer Me"); - - // Validate Stack Traces - output.assertContains(".StdErrLogTest:tname: "); - output.assertContains("java.lang.Throwable: out of focus"); - output.assertContains("java.lang.Throwable: scene lost"); - } - } - - /** - * Tests StdErrLog.info() methods with level filtering. - *

      - * Should only see INFO level messages when level is set to {@link StdErrLog#LEVEL_INFO} and below. - * - * @throws Exception failed test - */ - @Test - public void testInfoFiltering() throws Exception - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - StdErrCapture output = new StdErrCapture(log); - - // Normal/Default behavior - log.info("I will not buy"); - - // Level Debug - log.setLevel(StdErrLog.LEVEL_DEBUG); - log.info("this record"); - - // Level All - log.setLevel(StdErrLog.LEVEL_ALL); - log.info("it is scratched."); - - log.info("", new Throwable("out of focus")); - log.info(new Throwable("scene lost")); - - // Level Warn - log.setLevel(StdErrLog.LEVEL_WARN); - log.info("sorry?"); - log.info("", new Throwable("on editing room floor")); - - // Validate Output - output.assertContains("I will not buy"); - output.assertContains("this record"); - output.assertContains("it is scratched."); - output.assertNotContains("sorry?"); - - // Validate Stack Traces - output.assertNotContains(""); - output.assertNotContains("on editing room floor"); - - output.assertContains(".StdErrLogTest:tname: "); - output.assertContains("java.lang.Throwable: out of focus"); - output.assertContains("java.lang.Throwable: scene lost"); - } - } - - /** - * Tests {@link StdErrLog#LEVEL_OFF} filtering. - * - * @throws Exception failed test - */ - @Test - public void testOffFiltering() throws Exception - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - log.setLevel(StdErrLog.LEVEL_OFF); - - StdErrCapture output = new StdErrCapture(log); - - // Various logging events - log.debug("Squelch"); - log.debug("Squelch", new RuntimeException("Squelch")); - log.info("Squelch"); - log.info("Squelch", new IllegalStateException("Squelch")); - log.warn("Squelch"); - log.warn("Squelch", new Exception("Squelch")); - log.ignore(new Throwable("Squelch")); - - // Validate Output - output.assertNotContains("Squelch"); - } - } - - /** - * Tests StdErrLog.debug() methods with level filtering. - *

      - * Should only see DEBUG level messages when level is set to {@link StdErrLog#LEVEL_DEBUG} and below. - * - * @throws Exception failed test - */ - @Test - public void testDebugFiltering() throws Exception - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - StdErrCapture output = new StdErrCapture(log); - - // Normal/Default behavior - log.debug("Tobacconist"); - log.debug("", new Throwable("on editing room floor")); - - // Level Debug - log.setLevel(StdErrLog.LEVEL_DEBUG); - log.debug("my hovercraft is"); - - log.debug("", new Throwable("out of focus")); - log.debug(new Throwable("scene lost")); - - // Level All - log.setLevel(StdErrLog.LEVEL_ALL); - log.debug("full of eels."); - - // Level Warn - log.setLevel(StdErrLog.LEVEL_WARN); - log.debug("what?"); - - // Validate Output - // System.err.print(output); - output.assertNotContains("Tobacconist"); - output.assertContains("my hovercraft is"); - output.assertContains("full of eels."); - output.assertNotContains("what?"); - - // Validate Stack Traces - output.assertNotContains(""); - output.assertNotContains("on editing room floor"); - - output.assertContains(".StdErrLogTest:tname: "); - output.assertContains("java.lang.Throwable: out of focus"); - output.assertContains("java.lang.Throwable: scene lost"); - } - } - - /** - * Tests StdErrLog with {@link Logger#ignore(Throwable)} use. - *

      - * Should only see IGNORED level messages when level is set to {@link StdErrLog#LEVEL_ALL}. - * - * @throws Exception failed test - */ - @Test - public void testIgnores() throws Exception - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - StdErrCapture output = new StdErrCapture(log); - - // Normal/Default behavior - log.ignore(new Throwable("IGNORE ME")); - - // Show Ignored - log.setLevel(StdErrLog.LEVEL_ALL); - log.ignore(new Throwable("Don't ignore me")); - - // Set to Debug level - log.setLevel(StdErrLog.LEVEL_DEBUG); - log.ignore(new Throwable("Debug me")); - - // Validate Output - // System.err.print(output); - output.assertNotContains("IGNORE ME"); - output.assertContains("Don't ignore me"); - output.assertNotContains("Debug me"); - } - } - - @Test - public void testIsDebugEnabled() throws Exception - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - log.setLevel(StdErrLog.LEVEL_ALL); - assertThat("log.level(all).isDebugEnabled", log.isDebugEnabled(), is(true)); - - log.setLevel(StdErrLog.LEVEL_DEBUG); - assertThat("log.level(debug).isDebugEnabled", log.isDebugEnabled(), is(true)); - - log.setLevel(StdErrLog.LEVEL_INFO); - assertThat("log.level(info).isDebugEnabled", log.isDebugEnabled(), is(false)); - - log.setLevel(StdErrLog.LEVEL_WARN); - assertThat("log.level(warn).isDebugEnabled", log.isDebugEnabled(), is(false)); - - log.setLevel(StdErrLog.LEVEL_OFF); - assertThat("log.level(off).isDebugEnabled", log.isDebugEnabled(), is(false)); - } - } - - @Test - public void testSetGetLevel() - { - StdErrLog log = new StdErrLog(StdErrLogTest.class.getName(), new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - log.setLevel(StdErrLog.LEVEL_ALL); - assertThat("log.level(all).getLevel()", log.getLevel(), is(StdErrLog.LEVEL_ALL)); - - log.setLevel(StdErrLog.LEVEL_DEBUG); - assertThat("log.level(debug).getLevel()", log.getLevel(), is(StdErrLog.LEVEL_DEBUG)); - - log.setLevel(StdErrLog.LEVEL_INFO); - assertThat("log.level(info).getLevel()", log.getLevel(), is(StdErrLog.LEVEL_INFO)); - - log.setLevel(StdErrLog.LEVEL_WARN); - assertThat("log.level(warn).getLevel()", log.getLevel(), is(StdErrLog.LEVEL_WARN)); - - log.setLevel(StdErrLog.LEVEL_OFF); - assertThat("log.level(off).getLevel()", log.getLevel(), is(StdErrLog.LEVEL_OFF)); - } - } - - @Test - public void testGetChildLogger_Simple() - { - String baseName = "jetty"; - StdErrLog log = new StdErrLog(baseName, new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - assertThat("Logger.name", log.getName(), is("jetty")); - - Logger log2 = log.getLogger("child"); - assertThat("Logger.child.name", log2.getName(), is("jetty.child")); - } - } - - @Test - public void testGetChildLogger_Deep() - { - String baseName = "jetty"; - StdErrLog log = new StdErrLog(baseName, new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - assertThat("Logger.name", log.getName(), is("jetty")); - - Logger log2 = log.getLogger("child.of.the.sixties"); - assertThat("Logger.child.name", log2.getName(), is("jetty.child.of.the.sixties")); - } - } - - @Test - public void testGetChildLogger_Null() - { - String baseName = "jetty"; - StdErrLog log = new StdErrLog(baseName, new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - assertThat("Logger.name", log.getName(), is("jetty")); - - // Pass null as child reference, should return parent logger - Logger log2 = log.getLogger((String)null); - assertThat("Logger.child.name", log2.getName(), is("jetty")); - assertSame(log2, log, "Should have returned same logger"); - } - } - - @Test - public void testGetChildLogger_EmptyName() - { - String baseName = "jetty"; - StdErrLog log = new StdErrLog(baseName, new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - assertThat("Logger.name", log.getName(), is("jetty")); - - // Pass empty name as child reference, should return parent logger - Logger log2 = log.getLogger(""); - assertThat("Logger.child.name", log2.getName(), is("jetty")); - assertSame(log2, log, "Should have returned same logger"); - } - } - - @Test - public void testGetChildLogger_EmptyNameSpaces() - { - String baseName = "jetty"; - StdErrLog log = new StdErrLog(baseName, new Properties()); - try (StacklessLogging stackless = new StacklessLogging(log)) - { - assertThat("Logger.name", log.getName(), is("jetty")); - - // Pass empty name as child reference, should return parent logger - Logger log2 = log.getLogger(" "); - assertThat("Logger.child.name", log2.getName(), is("jetty")); - assertSame(log2, log, "Should have returned same logger"); - } - } - - @Test - public void testGetChildLogger_NullParent() - { - AbstractLogger log = new StdErrLog(null, new Properties()); - - assertThat("Logger.name", log.getName(), is("")); - - Logger log2 = log.getLogger("jetty"); - assertThat("Logger.child.name", log2.getName(), is("jetty")); - assertNotSame(log2, log, "Should have returned same logger"); - } - - @Test - public void testToString() - { - StdErrLog log = new StdErrLog("jetty", new Properties()); - - log.setLevel(StdErrLog.LEVEL_ALL); - assertThat("Logger.toString", log.toString(), is("StdErrLog:jetty:LEVEL=ALL")); - - log.setLevel(StdErrLog.LEVEL_DEBUG); - assertThat("Logger.toString", log.toString(), is("StdErrLog:jetty:LEVEL=DEBUG")); - - log.setLevel(StdErrLog.LEVEL_INFO); - assertThat("Logger.toString", log.toString(), is("StdErrLog:jetty:LEVEL=INFO")); - - log.setLevel(StdErrLog.LEVEL_WARN); - assertThat("Logger.toString", log.toString(), is("StdErrLog:jetty:LEVEL=WARN")); - - log.setLevel(99); // intentionally bogus level - assertThat("Logger.toString", log.toString(), is("StdErrLog:jetty:LEVEL=?")); - } - - @Test - public void testPrintSource() throws UnsupportedEncodingException - { - Properties props = new Properties(); - props.put("test.SOURCE", "true"); - StdErrLog log = new StdErrLog("test", props); - log.setLevel(StdErrLog.LEVEL_DEBUG); - - ByteArrayOutputStream test = new ByteArrayOutputStream(); - PrintStream err = new PrintStream(test); - log.setStdErrStream(err); - - log.debug("Show me the source!"); - - String output = new String(test.toByteArray(), StandardCharsets.UTF_8); - // System.err.print(output); - - assertThat(output, containsString(".StdErrLogTest#testPrintSource(StdErrLogTest.java:")); - - props.put("test.SOURCE", "false"); - log = new StdErrLog("other", props); - } - - @Test - public void testConfiguredAndSetDebugEnabled() - { - Properties props = new Properties(); - props.setProperty("org.eclipse.jetty.util.LEVEL", "WARN"); - props.setProperty("org.eclipse.jetty.io.LEVEL", "WARN"); - - StdErrLog root = new StdErrLog("", props); - assertLevel(root, StdErrLog.LEVEL_INFO); // default - - StdErrLog log = (StdErrLog)root.getLogger(StdErrLogTest.class.getName()); - assertThat("Log.isDebugEnabled()", log.isDebugEnabled(), is(false)); - assertLevel(log, StdErrLog.LEVEL_WARN); // as configured - - // Boot stomp it all to debug - root.setDebugEnabled(true); - assertThat("Log.isDebugEnabled()", log.isDebugEnabled(), is(true)); - assertLevel(log, StdErrLog.LEVEL_DEBUG); // as stomped - - // Restore configured - root.setDebugEnabled(false); - assertThat("Log.isDebugEnabled()", log.isDebugEnabled(), is(false)); - assertLevel(log, StdErrLog.LEVEL_WARN); // as configured - } - - @Test - public void testSuppressed() - { - StdErrLog log = new StdErrLog("xxx", new Properties()); - StdErrCapture output = new StdErrCapture(log); - - Exception inner = new Exception("inner"); - inner.addSuppressed(new IllegalStateException() - {{ - addSuppressed(new Exception("branch0")); - }}); - IOException outer = new IOException("outer", inner); - - outer.addSuppressed(new IllegalStateException() - {{ - addSuppressed(new Exception("branch1")); - }}); - outer.addSuppressed(new IllegalArgumentException() - {{ - addSuppressed(new Exception("branch2")); - }}); - - log.warn("problem", outer); - - output.assertContains("\t|\t|java.lang.Exception: branch2"); - output.assertContains("\t|\t|java.lang.Exception: branch1"); - output.assertContains("\t|\t|java.lang.Exception: branch0"); - } - - private void assertLevel(StdErrLog log, int expectedLevel) - { - assertThat("Log[" + log.getName() + "].level", levelToString(log.getLevel()), is(levelToString(expectedLevel))); - } - - private String levelToString(int level) - { - switch (level) - { - case StdErrLog.LEVEL_ALL: - return "ALL"; - case StdErrLog.LEVEL_DEBUG: - return "DEBUG"; - case StdErrLog.LEVEL_INFO: - return "INFO"; - case StdErrLog.LEVEL_WARN: - return "WARN"; - default: - return Integer.toString(level); - } - } -} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ClassPathResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ClassPathResourceTest.java index 83404b2d0f7..5c21361b16c 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ClassPathResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ClassPathResourceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java index 8e4fd128bae..03f876dd25f 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java @@ -1,25 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; @@ -228,7 +230,7 @@ public class FileSystemResourceTest @ParameterizedTest @EnabledOnOs(WINDOWS) @MethodSource("fsResourceProvider") - public void testBogusFilename_Windows(Class resourceClass) + public void testBogusFilenameWindows(Class resourceClass) { // "CON" is a reserved name under windows assertThrows(IllegalArgumentException.class, @@ -238,7 +240,7 @@ public class FileSystemResourceTest @ParameterizedTest @EnabledOnOs({LINUX, MAC}) @MethodSource("fsResourceProvider") - public void testBogusFilename_Unix(Class resourceClass) + public void testBogusFilenameUnix(Class resourceClass) { // A windows path is invalid under unix assertThrows(IllegalArgumentException.class, @@ -247,7 +249,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testNewResource_WithSpace(Class resourceClass) throws Exception + public void testNewResourceWithSpace(Class resourceClass) throws Exception { Path dir = workDir.getPath().normalize().toRealPath(); @@ -319,6 +321,42 @@ public class FileSystemResourceTest } } + @ParameterizedTest + @MethodSource("fsResourceProvider") + public void testAccessUniCodeFile(Class resourceClass) throws Exception + { + Path dir = workDir.getEmptyPathDir(); + + String readableRootDir = findRootDir(dir.getFileSystem()); + assumeTrue(readableRootDir != null, "Readable Root Dir found"); + + Path subdir = dir.resolve("sub"); + Files.createDirectories(subdir); + + touchFile(subdir.resolve("swedish-å.txt"), "hi a-with-circle"); + touchFile(subdir.resolve("swedish-ä.txt"), "hi a-with-two-dots"); + touchFile(subdir.resolve("swedish-ö.txt"), "hi o-with-two-dots"); + + try (Resource base = newResource(resourceClass, subdir.toFile())) + { + Resource refA1 = base.addPath("swedish-å.txt"); + Resource refA2 = base.addPath("swedish-ä.txt"); + Resource refO1 = base.addPath("swedish-ö.txt"); + + assertThat("Ref A1 exists", refA1.exists(), is(true)); + assertThat("Ref A2 exists", refA2.exists(), is(true)); + assertThat("Ref O1 exists", refO1.exists(), is(true)); + + assertThat("Ref A1 alias", refA1.isAlias(), is(false)); + assertThat("Ref A2 alias", refA2.isAlias(), is(false)); + assertThat("Ref O1 alias", refO1.isAlias(), is(false)); + + assertThat("Ref A1 contents", toString(refA1), is("hi a-with-circle")); + assertThat("Ref A2 contents", toString(refA2), is("hi a-with-two-dots")); + assertThat("Ref O1 contents", toString(refO1), is("hi o-with-two-dots")); + } + } + private String findRootDir(FileSystem fs) { // look for a directory off of a root path @@ -336,6 +374,7 @@ public class FileSystemResourceTest } catch (Exception ignored) { + // FIXME why ignoring exceptions?? } } @@ -354,7 +393,7 @@ public class FileSystemResourceTest try (Resource base = newResource(resourceClass, dir.toFile())) { Resource res = base.addPath("foo"); - assertThat("is contained in", res.isContainedIn(base), is(false)); + assertThat("is contained in", res.isContainedIn(base), is(true)); } } @@ -399,7 +438,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testLastModified_NotExists(Class resourceClass) throws Exception + public void testLastModifiedNotExists(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); @@ -418,12 +457,7 @@ public class FileSystemResourceTest Files.createDirectories(dir); Path file = dir.resolve("foo"); - - try (StringReader reader = new StringReader("foo"); - BufferedWriter writer = Files.newBufferedWriter(file)) - { - IO.copy(reader, writer); - } + touchFile(file, "foo"); long expected = Files.size(file); @@ -436,7 +470,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testLength_NotExists(Class resourceClass) throws Exception + public void testLengthNotExists(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -471,7 +505,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testDelete_NotExists(Class resourceClass) throws Exception + public void testDeleteNotExists(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -512,12 +546,7 @@ public class FileSystemResourceTest Path file = dir.resolve("foo"); String content = "Foo is here"; - - try (StringReader reader = new StringReader(content); - BufferedWriter writer = Files.newBufferedWriter(file)) - { - IO.copy(reader, writer); - } + touchFile(file, content); try (Resource base = newResource(resourceClass, dir.toFile())) { @@ -1110,7 +1139,7 @@ public class FileSystemResourceTest */ @ParameterizedTest @MethodSource("fsResourceProvider") - public void testExist_Normal(Class resourceClass) throws Exception + public void testExistNormal(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -1189,7 +1218,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testExist_BadURINull(Class resourceClass) throws Exception + public void testExistBadURINull(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -1216,7 +1245,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testExist_BadURINullX(Class resourceClass) throws Exception + public void testExistBadURINullX(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -1243,7 +1272,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testAddPath_WindowsSlash(Class resourceClass) throws Exception + public void testAddPathWindowsSlash(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -1284,7 +1313,7 @@ public class FileSystemResourceTest @ParameterizedTest @MethodSource("fsResourceProvider") - public void testAddPath_WindowsExtensionLess(Class resourceClass) throws Exception + public void testAddPathWindowsExtensionLess(Class resourceClass) throws Exception { Path dir = workDir.getEmptyPathDir(); Files.createDirectories(dir); @@ -1484,4 +1513,23 @@ public class FileSystemResourceTest assertThat("getAlias()", resource.getAlias(), nullValue()); } } + + private String toString(Resource resource) throws IOException + { + try (InputStream inputStream = resource.getInputStream(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) + { + IO.copy(inputStream, outputStream); + return outputStream.toString("utf-8"); + } + } + + private void touchFile(Path outputFile, String content) throws IOException + { + try (StringReader reader = new StringReader(content); + BufferedWriter writer = Files.newBufferedWriter(outputFile)) + { + IO.copy(reader, writer); + } + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JarResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JarResourceTest.java index d22642d5dac..7704c44af58 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JarResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JarResourceTest.java @@ -1,96 +1,101 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; -import java.io.File; -import java.io.FilenameFilter; +import java.io.IOException; +import java.net.URI; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import java.util.zip.ZipFile; +import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(WorkDirExtension.class) public class JarResourceTest { - private String testResURI = MavenTestingUtils.getTestResourcesPath().toUri().toASCIIString(); + public WorkDir workDir; @Test public void testJarFile() throws Exception { - String s = "jar:" + testResURI + "TestData/test.zip!/subdir/"; + Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/test.zip"); + String s = "jar:" + testZip.toUri().toASCIIString() + "!/subdir/"; Resource r = Resource.newResource(s); Set entries = new HashSet<>(Arrays.asList(r.list())); assertThat(entries, containsInAnyOrder("alphabet", "numbers", "subsubdir/")); - File extract = File.createTempFile("extract", null); - if (extract.exists()) - extract.delete(); - extract.mkdir(); - extract.deleteOnExit(); + Path extract = workDir.getPathFile("extract"); + FS.ensureEmpty(extract); - r.copyTo(extract); + r.copyTo(extract.toFile()); - Resource e = Resource.newResource(extract.getAbsolutePath()); + Resource e = Resource.newResource(extract.toString()); entries = new HashSet<>(Arrays.asList(e.list())); assertThat(entries, containsInAnyOrder("alphabet", "numbers", "subsubdir/")); - IO.delete(extract); - - s = "jar:" + testResURI + "TestData/test.zip!/subdir/subsubdir/"; + s = "jar:" + testZip.toUri().toASCIIString() + "!/subdir/subsubdir/"; r = Resource.newResource(s); entries = new HashSet<>(Arrays.asList(r.list())); assertThat(entries, containsInAnyOrder("alphabet", "numbers")); - extract = File.createTempFile("extract", null); - if (extract.exists()) - extract.delete(); - extract.mkdir(); - extract.deleteOnExit(); + Path extract2 = workDir.getPathFile("extract2"); + FS.ensureEmpty(extract2); - r.copyTo(extract); + r.copyTo(extract2.toFile()); - e = Resource.newResource(extract.getAbsolutePath()); + e = Resource.newResource(extract2.toString()); entries = new HashSet<>(Arrays.asList(e.list())); assertThat(entries, containsInAnyOrder("alphabet", "numbers")); - IO.delete(extract); } @Test public void testJarFileGetAllResoures() throws Exception { - String s = "jar:" + testResURI + "TestData/test.zip!/subdir/"; + Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/test.zip"); + String s = "jar:" + testZip.toUri().toASCIIString() + "!/subdir/"; Resource r = Resource.newResource(s); Collection deep = r.getAllResources(); @@ -101,16 +106,17 @@ public class JarResourceTest public void testJarFileIsContainedIn() throws Exception { - String s = "jar:" + testResURI + "TestData/test.zip!/subdir/"; + Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/test.zip"); + String s = "jar:" + testZip.toUri().toASCIIString() + "!/subdir/"; Resource r = Resource.newResource(s); - Resource container = Resource.newResource(testResURI + "TestData/test.zip"); + Resource container = Resource.newResource(testZip); - assertTrue(r instanceof JarFileResource); + assertThat(r, instanceOf(JarFileResource.class)); JarFileResource jarFileResource = (JarFileResource)r; assertTrue(jarFileResource.isContainedIn(container)); - container = Resource.newResource(testResURI + "TestData"); + container = Resource.newResource(testZip.getParent()); assertFalse(jarFileResource.isContainedIn(container)); } @@ -118,9 +124,11 @@ public class JarResourceTest public void testJarFileLastModified() throws Exception { - String s = "jar:" + testResURI + "TestData/test.zip!/subdir/numbers"; + Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/test.zip"); - try (ZipFile zf = new ZipFile(MavenTestingUtils.getTestResourceFile("TestData/test.zip"))) + String s = "jar:" + testZip.toUri().toASCIIString() + "!/subdir/numbers"; + + try (ZipFile zf = new ZipFile(testZip.toFile())) { long last = zf.getEntry("subdir/numbers").getTime(); @@ -132,73 +140,143 @@ public class JarResourceTest @Test public void testJarFileCopyToDirectoryTraversal() throws Exception { - String s = "jar:" + testResURI + "TestData/extract.zip!/"; + Path extractZip = MavenTestingUtils.getTestResourcePathFile("TestData/extract.zip"); + + String s = "jar:" + extractZip.toUri().toASCIIString() + "!/"; Resource r = Resource.newResource(s); - assertTrue(r instanceof JarResource); + assertThat(r, instanceOf(JarResource.class)); JarResource jarResource = (JarResource)r; - File destParent = File.createTempFile("copyjar", null); - if (destParent.exists()) - destParent.delete(); - destParent.mkdir(); - destParent.deleteOnExit(); + Path destParent = workDir.getPathFile("copyjar"); + FS.ensureEmpty(destParent); - File dest = new File(destParent.getCanonicalPath() + "/extract"); - if (dest.exists()) - dest.delete(); - dest.mkdir(); - dest.deleteOnExit(); + Path dest = destParent.toRealPath().resolve("extract"); + FS.ensureEmpty(dest); - jarResource.copyTo(dest); + jarResource.copyTo(dest.toFile()); // dest contains only the valid entry; dest.getParent() contains only the dest directory - assertEquals(1, dest.listFiles().length); - assertEquals(1, dest.getParentFile().listFiles().length); + assertEquals(1, listFiles(dest).size()); + assertEquals(1, listFiles(dest.getParent()).size()); - FilenameFilter dotdotFilenameFilter = new FilenameFilter() - { - @Override - public boolean accept(File directory, String name) - { - return name.equals("dotdot.txt"); - } - }; - assertEquals(0, dest.listFiles(dotdotFilenameFilter).length); - assertEquals(0, dest.getParentFile().listFiles(dotdotFilenameFilter).length); + DirectoryStream.Filter dotdotFilenameFilter = (path) -> + path.getFileName().toString().equalsIgnoreCase("dotdot.dot"); - FilenameFilter extractfileFilenameFilter = new FilenameFilter() - { - @Override - public boolean accept(File directory, String name) - { - return name.equals("extract-filenotdir"); - } - }; - assertEquals(0, dest.listFiles(extractfileFilenameFilter).length); - assertEquals(0, dest.getParentFile().listFiles(extractfileFilenameFilter).length); + assertEquals(0, listFiles(dest, dotdotFilenameFilter).size()); + assertEquals(0, listFiles(dest.getParent(), dotdotFilenameFilter).size()); - FilenameFilter currentDirectoryFilenameFilter = new FilenameFilter() - { - @Override - public boolean accept(File directory, String name) - { - return name.equals("current.txt"); - } - }; - assertEquals(1, dest.listFiles(currentDirectoryFilenameFilter).length); - assertEquals(0, dest.getParentFile().listFiles(currentDirectoryFilenameFilter).length); + DirectoryStream.Filter extractfileFilenameFilter = (path) -> + path.getFileName().toString().equalsIgnoreCase("extract-filenotdir"); - IO.delete(dest); - assertFalse(dest.exists()); + assertEquals(0, listFiles(dest, extractfileFilenameFilter).size()); + assertEquals(0, listFiles(dest.getParent(), extractfileFilenameFilter).size()); + + DirectoryStream.Filter currentDirectoryFilenameFilter = (path) -> + path.getFileName().toString().equalsIgnoreCase("current.txt"); + + assertEquals(1, listFiles(dest, currentDirectoryFilenameFilter).size()); + assertEquals(0, listFiles(dest.getParent(), currentDirectoryFilenameFilter).size()); } @Test public void testEncodedFileName() throws Exception { - String s = "jar:" + testResURI + "TestData/test.zip!/file%20name.txt"; + Path testZip = MavenTestingUtils.getTestResourcePathFile("TestData/test.zip"); + + String s = "jar:" + testZip.toUri().toASCIIString() + "!/file%20name.txt"; Resource r = Resource.newResource(s); assertTrue(r.exists()); } + + @Test + public void testJarFileResourceList() throws Exception + { + Path testJar = MavenTestingUtils.getTestResourcePathFile("jar-file-resource.jar"); + String uri = "jar:" + testJar.toUri().toASCIIString() + "!/"; + + Resource resource = new JarFileResource(URI.create(uri).toURL(),false); + Resource rez = resource.addPath("rez/"); + + assertThat("path /rez/ is a dir", rez.isDirectory(), is(true)); + + List actual = Arrays.asList(rez.list()); + String[] expected = new String[]{ + "one", + "aaa", + "bbb", + "oddities/", + "another dir/", + "ccc", + "deep/", + }; + assertThat("Dir contents", actual, containsInAnyOrder(expected)); + } + + /** + * Test getting a file listing of a Directory in a JAR + * Where the JAR entries contain names that are URI encoded / escaped + */ + @Test + public void testJarFileResourceListPreEncodedEntries() throws Exception + { + Path testJar = MavenTestingUtils.getTestResourcePathFile("jar-file-resource.jar"); + String uri = "jar:" + testJar.toUri().toASCIIString() + "!/"; + + Resource resource = new JarFileResource(URI.create(uri).toURL(),false); + Resource rez = resource.addPath("rez/oddities/"); + + assertThat("path /rez/oddities/ is a dir", rez.isDirectory(), is(true)); + + List actual = Arrays.asList(rez.list()); + String[] expected = new String[]{ + ";", + "#hashcode", + "index.html#fragment", + "other%2fkind%2Fof%2fslash", // pre-encoded / escaped + "a file with a space", + ";\" onmousedown=\"alert(document.location)\"", + "some\\slash\\you\\got\\there" // not encoded, stored as backslash native + }; + assertThat("Dir contents", actual, containsInAnyOrder(expected)); + } + + @Test + public void testJarFileResourceListDirWithSpace() throws Exception + { + Path testJar = MavenTestingUtils.getTestResourcePathFile("jar-file-resource.jar"); + String uri = "jar:" + testJar.toUri().toASCIIString() + "!/"; + + Resource resource = new JarFileResource(URI.create(uri).toURL(),false); + Resource anotherDir = resource.addPath("rez/another dir/"); + + assertThat("path /rez/another dir/ is a dir", anotherDir.isDirectory(), is(true)); + + List actual = Arrays.asList(anotherDir.list()); + String[] expected = new String[]{ + "a file.txt", + "another file.txt", + "..\\a different file.txt", + }; + assertThat("Dir contents", actual, containsInAnyOrder(expected)); + } + + private List listFiles(Path dir) throws IOException + { + return Files.list(dir).collect(Collectors.toList()); + } + + private List listFiles(Path dir, DirectoryStream.Filter filter) throws IOException + { + List results = new ArrayList<>(); + try (DirectoryStream filteredDirStream = Files.newDirectoryStream(dir, filter)) + { + for (Path path : filteredDirStream) + { + results.add(path); + } + return results; + } + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JrtResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JrtResourceTest.java index 772861b2925..5d2e9edc6c9 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JrtResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/JrtResourceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; @@ -41,8 +41,8 @@ public class JrtResourceTest public void testResourceFromUriForString() throws Exception { - URI string_loc = TypeUtil.getLocationOfClass(String.class); - Resource resource = Resource.newResource(string_loc); + URI stringLoc = TypeUtil.getLocationOfClass(String.class); + Resource resource = Resource.newResource(stringLoc); assertThat(resource.exists(), is(true)); assertThat(resource.isDirectory(), is(false)); @@ -58,8 +58,8 @@ public class JrtResourceTest public void testResourceFromStringForString() throws Exception { - URI string_loc = TypeUtil.getLocationOfClass(String.class); - Resource resource = Resource.newResource(string_loc.toASCIIString()); + URI stringLoc = TypeUtil.getLocationOfClass(String.class); + Resource resource = Resource.newResource(stringLoc.toASCIIString()); assertThat(resource.exists(), is(true)); assertThat(resource.isDirectory(), is(false)); @@ -75,8 +75,8 @@ public class JrtResourceTest public void testResourceFromURLForString() throws Exception { - URI string_loc = TypeUtil.getLocationOfClass(String.class); - Resource resource = Resource.newResource(string_loc.toURL()); + URI stringLoc = TypeUtil.getLocationOfClass(String.class); + Resource resource = Resource.newResource(stringLoc.toURL()); assertThat(resource.exists(), is(true)); assertThat(resource.isDirectory(), is(false)); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java index 50a8693c95b..458cba3a88e 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; @@ -41,12 +41,11 @@ import static org.hamcrest.Matchers.nullValue; public class PathResourceTest { @Test - public void testNonDefaultFileSystem_GetInputStream() throws URISyntaxException, IOException + public void testNonDefaultFileSystemGetInputStream() throws URISyntaxException, IOException { Path exampleJar = MavenTestingUtils.getTestResourcePathFile("example.jar"); URI uri = new URI("jar", exampleJar.toUri().toASCIIString(), null); - System.err.println("URI = " + uri); Map env = new HashMap<>(); env.put("multi-release", "runtime"); @@ -66,12 +65,11 @@ public class PathResourceTest } @Test - public void testNonDefaultFileSystem_GetReadableByteChannel() throws URISyntaxException, IOException + public void testNonDefaultFileSystemGetReadableByteChannel() throws URISyntaxException, IOException { Path exampleJar = MavenTestingUtils.getTestResourcePathFile("example.jar"); URI uri = new URI("jar", exampleJar.toUri().toASCIIString(), null); - System.err.println("URI = " + uri); Map env = new HashMap<>(); env.put("multi-release", "runtime"); @@ -91,12 +89,11 @@ public class PathResourceTest } @Test - public void testNonDefaultFileSystem_GetFile() throws URISyntaxException, IOException + public void testNonDefaultFileSystemGetFile() throws URISyntaxException, IOException { Path exampleJar = MavenTestingUtils.getTestResourcePathFile("example.jar"); URI uri = new URI("jar", exampleJar.toUri().toASCIIString(), null); - System.err.println("URI = " + uri); Map env = new HashMap<>(); env.put("multi-release", "runtime"); @@ -113,7 +110,7 @@ public class PathResourceTest } @Test - public void testDefaultFileSystem_GetFile() throws Exception + public void testDefaultFileSystemGetFile() throws Exception { Path exampleJar = MavenTestingUtils.getTestResourcePathFile("example.jar"); PathResource resource = new PathResource(exampleJar); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceAliasTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceAliasTest.java index bb668a183d6..ffd19fc4578 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceAliasTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceAliasTest.java @@ -1,110 +1,152 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; -import java.io.File; +import java.io.IOException; import java.net.MalformedURLException; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; import org.eclipse.jetty.toolchain.test.FS; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +@ExtendWith(WorkDirExtension.class) public class ResourceAliasTest { - static File __dir; + private static final Logger LOG = LoggerFactory.getLogger(ResourceAliasTest.class); - @BeforeAll - public static void beforeClass() - { - __dir = MavenTestingUtils.getTargetTestingDir("RAT"); - } + public WorkDir workDir; - @BeforeEach - public void before() + @Test + public void testPercentPaths() throws IOException { - FS.ensureDirExists(__dir); - FS.ensureEmpty(__dir); + Path baseDir = workDir.getEmptyPathDir(); + + Path foo = baseDir.resolve("%foo"); + Files.createDirectories(foo); + + Path bar = foo.resolve("bar%"); + Files.createDirectories(bar); + + Path text = bar.resolve("test.txt"); + FS.touch(text); + + // At this point we have a path .../%foo/bar%/test.txt present on the filesystem. + // This would also apply for paths found in JAR files (like META-INF/resources/%foo/bar%/test.txt) + + assertTrue(Files.exists(text)); + + Resource baseResource = new PathResource(baseDir); + assertTrue(baseResource.exists(), "baseResource exists"); + + Resource fooResource = baseResource.addPath("%foo"); + assertTrue(fooResource.exists(), "fooResource exists"); + assertTrue(fooResource.isDirectory(), "fooResource isDir"); + assertFalse(fooResource.isAlias(), "fooResource isAlias"); + + Resource barResource = fooResource.addPath("bar%"); + assertTrue(barResource.exists(), "barResource exists"); + assertTrue(barResource.isDirectory(), "barResource isDir"); + assertFalse(barResource.isAlias(), "barResource isAlias"); + + Resource textResource = barResource.addPath("test.txt"); + assertTrue(textResource.exists(), "textResource exists"); + assertFalse(textResource.isDirectory(), "textResource isDir"); } @Test public void testNullCharEndingFilename() throws Exception { - File file = new File(__dir, "test.txt"); - assertFalse(file.exists()); - assertTrue(file.createNewFile()); - assertTrue(file.exists()); + Path baseDir = workDir.getEmptyPathDir(); - File file0 = new File(__dir, "test.txt\0"); - if (!file0.exists()) - return; // this file system does not suffer this problem - - assertTrue(file0.exists()); // This is an alias! - - Resource dir = Resource.newResource(__dir); - - // Test not alias paths - Resource resource = Resource.newResource(file); - assertTrue(resource.exists()); - assertNull(resource.getAlias()); - resource = Resource.newResource(file.getAbsoluteFile()); - assertTrue(resource.exists()); - assertNull(resource.getAlias()); - resource = Resource.newResource(file.toURI()); - assertTrue(resource.exists()); - assertNull(resource.getAlias()); - resource = Resource.newResource(file.toURI().toString()); - assertTrue(resource.exists()); - assertNull(resource.getAlias()); - resource = dir.addPath("test.txt"); - assertTrue(resource.exists()); - assertNull(resource.getAlias()); - - // Test alias paths - resource = Resource.newResource(file0); - assertTrue(resource.exists()); - assertNotNull(resource.getAlias()); - resource = Resource.newResource(file0.getAbsoluteFile()); - assertTrue(resource.exists()); - assertNotNull(resource.getAlias()); - resource = Resource.newResource(file0.toURI()); - assertTrue(resource.exists()); - assertNotNull(resource.getAlias()); - resource = Resource.newResource(file0.toURI().toString()); - assertTrue(resource.exists()); - assertNotNull(resource.getAlias()); + Path file = baseDir.resolve("test.txt"); + FS.touch(file); try { - resource = dir.addPath("test.txt\0"); + Path file0 = baseDir.resolve("test.txt\0"); + if (!Files.exists(file0)) + return; // this file system does get tricked by ending filenames + + assertThat(file0 + " exists", Files.exists(file0), is(true)); // This is an alias! + + Resource dir = Resource.newResource(baseDir); + + // Test not alias paths + Resource resource = Resource.newResource(file); + assertTrue(resource.exists()); + assertNull(resource.getAlias()); + resource = Resource.newResource(file.toAbsolutePath()); + assertTrue(resource.exists()); + assertNull(resource.getAlias()); + resource = Resource.newResource(file.toUri()); + assertTrue(resource.exists()); + assertNull(resource.getAlias()); + resource = Resource.newResource(file.toUri().toString()); + assertTrue(resource.exists()); + assertNull(resource.getAlias()); + resource = dir.addPath("test.txt"); + assertTrue(resource.exists()); + assertNull(resource.getAlias()); + + // Test alias paths + resource = Resource.newResource(file0); assertTrue(resource.exists()); assertNotNull(resource.getAlias()); + resource = Resource.newResource(file0.toAbsolutePath()); + assertTrue(resource.exists()); + assertNotNull(resource.getAlias()); + resource = Resource.newResource(file0.toUri()); + assertTrue(resource.exists()); + assertNotNull(resource.getAlias()); + resource = Resource.newResource(file0.toUri().toString()); + assertTrue(resource.exists()); + assertNotNull(resource.getAlias()); + + try + { + resource = dir.addPath("test.txt\0"); + assertTrue(resource.exists()); + assertNotNull(resource.getAlias()); + } + catch (MalformedURLException e) + { + assertTrue(true); + } } - catch (MalformedURLException e) + catch (InvalidPathException e) { - assertTrue(true); + // this file system does allow null char ending filenames + LOG.trace("IGNORED", e); } } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java index f93f1c41527..404661f94fc 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; @@ -44,7 +44,7 @@ public class ResourceCollectionTest public WorkDir workdir; @Test - public void testUnsetCollection_ThrowsISE() + public void testUnsetCollectionThrowsISE() { ResourceCollection coll = new ResourceCollection(); @@ -52,7 +52,7 @@ public class ResourceCollectionTest } @Test - public void testEmptyResourceArray_ThrowsISE() + public void testEmptyResourceArrayThrowsISE() { ResourceCollection coll = new ResourceCollection(new Resource[0]); @@ -60,7 +60,7 @@ public class ResourceCollectionTest } @Test - public void testResourceArrayWithNull_ThrowsISE() + public void testResourceArrayWithNullThrowsISE() { ResourceCollection coll = new ResourceCollection(new Resource[]{null}); @@ -68,7 +68,7 @@ public class ResourceCollectionTest } @Test - public void testEmptyStringArray_ThrowsISE() + public void testEmptyStringArrayThrowsISE() { ResourceCollection coll = new ResourceCollection(new String[0]); @@ -76,14 +76,14 @@ public class ResourceCollectionTest } @Test - public void testStringArrayWithNull_ThrowsIAE() + public void testStringArrayWithNullThrowsIAE() { assertThrows(IllegalArgumentException.class, () -> new ResourceCollection(new String[]{null})); } @Test - public void testNullCsv_ThrowsIAE() + public void testNullCsvThrowsIAE() { assertThrows(IllegalArgumentException.class, () -> { @@ -93,7 +93,7 @@ public class ResourceCollectionTest } @Test - public void testEmptyCsv_ThrowsIAE() + public void testEmptyCsvThrowsIAE() { assertThrows(IllegalArgumentException.class, () -> { @@ -103,7 +103,7 @@ public class ResourceCollectionTest } @Test - public void testBlankCsv_ThrowsIAE() + public void testBlankCsvThrowsIAE() { assertThrows(IllegalArgumentException.class, () -> { @@ -113,7 +113,7 @@ public class ResourceCollectionTest } @Test - public void testSetResourceNull_ThrowsISE() + public void testSetResourceNullThrowsISE() { // Create a ResourceCollection with one valid entry Path path = MavenTestingUtils.getTargetPath(); @@ -127,7 +127,7 @@ public class ResourceCollectionTest } @Test - public void testSetResourceEmpty_ThrowsISE() + public void testSetResourceEmptyThrowsISE() { // Create a ResourceCollection with one valid entry Path path = MavenTestingUtils.getTargetPath(); @@ -141,7 +141,7 @@ public class ResourceCollectionTest } @Test - public void testSetResourceAllNulls_ThrowsISE() + public void testSetResourceAllNullsThrowsISE() { // Create a ResourceCollection with one valid entry Path path = MavenTestingUtils.getTargetPath(); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java index de235e2e78c..dd2188c080d 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.resource; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java index 357767af6c8..88cc1933d98 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.security; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java index 0b5dbb28039..ee6cf19c05f 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.security; @@ -44,6 +44,7 @@ public class PasswordTest @Test public void testObfuscateUnicode() { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck String password = "secret password !#\u20ac "; String obfuscate = Password.obfuscate(password); assertEquals(password, Password.deobfuscate(obfuscate)); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java index 38e2df39c1c..15d8228f427 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.ssl; @@ -28,8 +28,8 @@ import java.util.stream.Stream; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -72,7 +72,6 @@ public class SslContextFactoryTest public void testSLOTH() throws Exception { cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); cf.start(); @@ -90,10 +89,9 @@ public class SslContextFactoryTest } @Test - public void testDump_IncludeTlsRsa() throws Exception + public void testDumpIncludeTlsRsa() throws Exception { cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); cf.setIncludeCipherSuites("TLS_RSA_.*"); cf.setExcludeCipherSuites("BOGUS"); // just to not exclude anything @@ -125,117 +123,92 @@ public class SslContextFactoryTest public void testNoTsFileKs() throws Exception { cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testNoTsSetKs() throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); - try (InputStream keystoreInputStream = this.getClass().getResourceAsStream("keystore")) + KeyStore ks = KeyStore.getInstance("PKCS12"); + try (InputStream keystoreInputStream = this.getClass().getResourceAsStream("keystore.p12")) { ks.load(keystoreInputStream, "storepwd".toCharArray()); } cf.setKeyStore(ks); - cf.setKeyManagerPassword("keypwd"); cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testNoTsNoKs() throws Exception { cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testTrustAll() throws Exception { cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testNoTsResourceKs() throws Exception { - Resource keystoreResource = Resource.newSystemResource("keystore"); + Resource keystoreResource = Resource.newSystemResource("keystore.p12"); cf.setKeyStoreResource(keystoreResource); cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); cf.setTrustStoreResource(keystoreResource); cf.setTrustStorePassword(null); cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testResourceTsResourceKs() throws Exception { - Resource keystoreResource = Resource.newSystemResource("keystore"); - Resource truststoreResource = Resource.newSystemResource("keystore"); + Resource keystoreResource = Resource.newSystemResource("keystore.p12"); + Resource truststoreResource = Resource.newSystemResource("keystore.p12"); cf.setKeyStoreResource(keystoreResource); - cf.setTrustStoreResource(truststoreResource); cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); + cf.setTrustStoreResource(truststoreResource); cf.setTrustStorePassword("storepwd"); cf.start(); - assertTrue(cf.getSslContext() != null); - } - - @Test - public void testResourceTsResourceKsWrongPW() throws Exception - { - Resource keystoreResource = Resource.newSystemResource("keystore"); - Resource truststoreResource = Resource.newSystemResource("keystore"); - - cf.setKeyStoreResource(keystoreResource); - cf.setTrustStoreResource(truststoreResource); - cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("wrong_keypwd"); - cf.setTrustStorePassword("storepwd"); - - try (StacklessLogging ignore = new StacklessLogging(AbstractLifeCycle.class)) - { - java.security.UnrecoverableKeyException x = assertThrows( - java.security.UnrecoverableKeyException.class, () -> cf.start()); - assertThat(x.getMessage(), containsString("Cannot recover key")); - } + assertNotNull(cf.getSslContext()); } @Test public void testResourceTsWrongPWResourceKs() throws Exception { - Resource keystoreResource = Resource.newSystemResource("keystore"); - Resource truststoreResource = Resource.newSystemResource("keystore"); + Resource keystoreResource = Resource.newSystemResource("keystore.p12"); + Resource truststoreResource = Resource.newSystemResource("keystore.p12"); cf.setKeyStoreResource(keystoreResource); - cf.setTrustStoreResource(truststoreResource); cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); + cf.setTrustStoreResource(truststoreResource); cf.setTrustStorePassword("wrong_storepwd"); try (StacklessLogging ignore = new StacklessLogging(AbstractLifeCycle.class)) { IOException x = assertThrows(IOException.class, () -> cf.start()); - assertThat(x.getMessage(), containsString("Keystore was tampered with, or password was incorrect")); + assertThat(x.getMessage(), containsString("password was incorrect")); } } @Test - public void testNoKeyConfig() throws Exception + public void testNoKeyConfig() { try (StacklessLogging ignore = new StacklessLogging(AbstractLifeCycle.class)) { @@ -289,11 +262,10 @@ public class SslContextFactoryTest @Test public void testSNICertificates() throws Exception { - Resource keystoreResource = Resource.newSystemResource("snikeystore"); + Resource keystoreResource = Resource.newSystemResource("snikeystore.p12"); cf.setKeyStoreResource(keystoreResource); cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); cf.start(); @@ -331,8 +303,8 @@ public class SslContextFactoryTest public void testNonDefaultKeyStoreTypeUsedForTrustStore() throws Exception { cf = new SslContextFactory.Server(); - cf.setKeyStoreResource(Resource.newSystemResource("keystore.p12")); - cf.setKeyStoreType("pkcs12"); + cf.setKeyStoreResource(Resource.newSystemResource("keystore.jks")); + cf.setKeyStoreType("jks"); cf.setKeyStorePassword("storepwd"); cf.start(); cf.stop(); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509CertificateAdapter.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509CertificateAdapter.java index bfbf062a3e9..dad26dd3f6a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509CertificateAdapter.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509CertificateAdapter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.ssl; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index 04f84a5b264..a775049dce8 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -1,25 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.ssl; +import java.nio.file.Path; import java.security.cert.X509Certificate; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.PathResource; +import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -28,7 +32,7 @@ import static org.hamcrest.Matchers.is; public class X509Test { @Test - public void testIsCertSign_Normal() + public void testIsCertSignNormal() { X509Certificate bogusX509 = new X509CertificateAdapter() { @@ -45,7 +49,7 @@ public class X509Test } @Test - public void testIsCertSign_Normal_NoSupported() + public void testIsCertSignNormalNoSupported() { X509Certificate bogusX509 = new X509CertificateAdapter() { @@ -62,7 +66,7 @@ public class X509Test } @Test - public void testIsCertSign_NonStandard_Short() + public void testIsCertSignNonStandardShort() { X509Certificate bogusX509 = new X509CertificateAdapter() { @@ -79,7 +83,7 @@ public class X509Test } @Test - public void testIsCertSign_NonStandard_Shorter() + public void testIsCertSignNonStandardShorter() { X509Certificate bogusX509 = new X509CertificateAdapter() { @@ -95,7 +99,7 @@ public class X509Test } @Test - public void testIsCertSign_Normal_Null() + public void testIsCertSignNormalNull() { X509Certificate bogusX509 = new X509CertificateAdapter() { @@ -110,7 +114,7 @@ public class X509Test } @Test - public void testIsCertSign_Normal_Empty() + public void testIsCertSignNormalEmpty() { X509Certificate bogusX509 = new X509CertificateAdapter() { @@ -123,4 +127,44 @@ public class X509Test assertThat("Normal X509", X509.isCertSign(bogusX509), is(false)); } + + @Test + public void testServerClassWithSni() throws Exception + { + SslContextFactory serverSsl = new SslContextFactory.Server(); + Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); + serverSsl.setKeyStoreResource(new PathResource(keystorePath)); + serverSsl.setKeyStorePassword("storepwd"); + serverSsl.start(); + } + + @Test + public void testClientClassWithSni() throws Exception + { + SslContextFactory clientSsl = new SslContextFactory.Client(); + Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); + clientSsl.setKeyStoreResource(new PathResource(keystorePath)); + clientSsl.setKeyStorePassword("storepwd"); + clientSsl.start(); + } + + @Test + public void testServerClassWithoutSni() throws Exception + { + SslContextFactory serverSsl = new SslContextFactory.Server(); + Resource keystoreResource = Resource.newSystemResource("keystore.p12"); + serverSsl.setKeyStoreResource(keystoreResource); + serverSsl.setKeyStorePassword("storepwd"); + serverSsl.start(); + } + + @Test + public void testClientClassWithoutSni() throws Exception + { + SslContextFactory clientSsl = new SslContextFactory.Client(); + Resource keystoreResource = Resource.newSystemResource("keystore.p12"); + clientSsl.setKeyStoreResource(keystoreResource); + clientSsl.setKeyStorePassword("storepwd"); + clientSsl.start(); + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java index 82d1971ea77..5ae252e8d2a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.statistic; @@ -89,10 +89,7 @@ public class CounterStatisticTest for (int i = N; i-- > 0; ) { threads[i] = (i >= N / 2) - ? new Thread() - { - @Override - public void run() + ? new Thread(() -> { try { @@ -110,12 +107,9 @@ public class CounterStatisticTest if (random.nextInt(5) == 0) Thread.yield(); } - } - } - : new Thread() - { - @Override - public void run() + }) + + : new Thread(() -> { try { @@ -134,8 +128,7 @@ public class CounterStatisticTest if (random.nextInt(5) == 0) Thread.yield(); } - } - }; + }); threads[i].start(); } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java index 84408fc4b76..e73a848d245 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.statistic; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java index 9f48c5a76d0..81a00e80f31 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.statistic; @@ -35,15 +35,15 @@ public class SampleStatisticTest 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 110, 95, 105, 97, 103 }, - }; + }; private static double[][] results = - { /* {mean,stddev}*/ - {100.0, 0.0}, - {100.0, Math.sqrt((10 * 10 + 10 * 10) / 12.0)}, - {100.0, Math.sqrt((10 * 10 + 10 * 10 + 5 * 5 + 5 * 5 + 3 * 3 + 3 * 3) / 14.0)}, - {100.0, Math.sqrt((10 * 10 + 10 * 10 + 5 * 5 + 5 * 5 + 3 * 3 + 3 * 3) / 24.0)}, - {100.0, Math.sqrt((10 * 10 + 10 * 10 + 5 * 5 + 5 * 5 + 3 * 3 + 3 * 3) / 104.0)} + /* {mean,stddev}*/ + {{100.0, 0.0}, + {100.0, Math.sqrt((10 * 10 + 10 * 10) / 12.0)}, + {100.0, Math.sqrt((10 * 10 + 10 * 10 + 5 * 5 + 5 * 5 + 3 * 3 + 3 * 3) / 14.0)}, + {100.0, Math.sqrt((10 * 10 + 10 * 10 + 5 * 5 + 5 * 5 + 3 * 3 + 3 * 3) / 24.0)}, + {100.0, Math.sqrt((10 * 10 + 10 * 10 + 5 * 5 + 5 * 5 + 3 * 3 + 3 * 3) / 104.0)} }; @Test diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AbstractThreadPoolTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AbstractThreadPoolTest.java index 7d81923a5dd..8ee09014ae9 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AbstractThreadPoolTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AbstractThreadPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; @@ -44,10 +44,10 @@ public abstract class AbstractThreadPoolTest ProcessorUtils.setAvailableProcessors(originalCoreCount); } - abstract protected SizedThreadPool newPool(int max); + protected abstract SizedThreadPool newPool(int max); @Test - public void testBudget_constructMaxThenLease() + public void testBudgetConstructMaxThenLease() { SizedThreadPool pool = newPool(4); @@ -67,7 +67,7 @@ public abstract class AbstractThreadPoolTest } @Test - public void testBudget_LeaseThenSetMax() + public void testBudgetLeaseThenSetMax() { SizedThreadPool pool = newPool(4); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/LockerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AutoLockTest.java similarity index 50% rename from jetty-util/src/test/java/org/eclipse/jetty/util/thread/LockerTest.java rename to jetty-util/src/test/java/org/eclipse/jetty/util/thread/AutoLockTest.java index 967969d771d..baa78ad0abd 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/LockerTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AutoLockTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; @@ -26,19 +26,15 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -public class LockerTest +public class AutoLockTest { - public LockerTest() - { - } - @Test public void testLocked() { - Locker lock = new Locker(); + AutoLock lock = new AutoLock(); assertFalse(lock.isLocked()); - try (Locker.Lock l = lock.lock()) + try (AutoLock l = lock.lock()) { assertTrue(lock.isLocked()); } @@ -53,10 +49,10 @@ public class LockerTest @Test public void testLockedException() { - Locker lock = new Locker(); + AutoLock lock = new AutoLock(); assertFalse(lock.isLocked()); - try (Locker.Lock l = lock.lock()) + try (AutoLock l = lock.lock()) { assertTrue(lock.isLocked()); throw new Exception(); @@ -76,27 +72,23 @@ public class LockerTest @Test public void testContend() throws Exception { - final Locker lock = new Locker(); + AutoLock lock = new AutoLock(); final CountDownLatch held0 = new CountDownLatch(1); final CountDownLatch hold0 = new CountDownLatch(1); - Thread thread0 = new Thread() + Thread thread0 = new Thread(() -> { - @Override - public void run() + try (AutoLock l = lock.lock()) { - try (Locker.Lock l = lock.lock()) - { - held0.countDown(); - hold0.await(); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } + held0.countDown(); + hold0.await(); } - }; + catch (InterruptedException e) + { + e.printStackTrace(); + } + }); thread0.start(); held0.await(); @@ -104,22 +96,18 @@ public class LockerTest final CountDownLatch held1 = new CountDownLatch(1); final CountDownLatch hold1 = new CountDownLatch(1); - Thread thread1 = new Thread() + Thread thread1 = new Thread(() -> { - @Override - public void run() + try (AutoLock l = lock.lock()) { - try (Locker.Lock l = lock.lock()) - { - held1.countDown(); - hold1.await(); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } + held1.countDown(); + hold1.await(); } - }; + catch (InterruptedException e) + { + e.printStackTrace(); + } + }); thread1.start(); // thread1 will be spinning here assertFalse(held1.await(100, TimeUnit.MILLISECONDS)); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/EatWhatYouKillTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/EatWhatYouKillTest.java index 10b84e0d95f..4a6dbf0d403 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/EatWhatYouKillTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/EatWhatYouKillTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; @@ -24,7 +24,7 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.thread.strategy.EatWhatYouKill; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -61,7 +61,7 @@ public class EatWhatYouKillTest @Test public void testExceptionThrownByTask() throws Exception { - try (StacklessLogging stackLess = new StacklessLogging(EatWhatYouKill.class)) + try (StacklessLogging ignored = new StacklessLogging(EatWhatYouKill.class)) { AtomicReference detector = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(2); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ExecutorThreadPoolTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ExecutorThreadPoolTest.java index 9207bdcb21e..85a1ec5739a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ExecutorThreadPoolTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ExecutorThreadPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java index c96c6a6cd31..770a481b675 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java @@ -1,50 +1,103 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; import java.io.Closeable; -import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.thread.ThreadPool.SizedThreadPool; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.core.StringContains.containsString; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; public class QueuedThreadPoolTest extends AbstractThreadPoolTest { - private static final Logger LOG = Log.getLogger(QueuedThreadPoolTest.class); + private static final Logger LOG = LoggerFactory.getLogger(QueuedThreadPoolTest.class); private final AtomicInteger _jobs = new AtomicInteger(); + private static class TestQueuedThreadPool extends QueuedThreadPool + { + private final AtomicInteger _started; + private final CountDownLatch _enteredRemoveThread; + private final CountDownLatch _exitRemoveThread; + + public TestQueuedThreadPool(AtomicInteger started, CountDownLatch enteredRemoveThread, CountDownLatch exitRemoveThread) + { + _started = started; + _enteredRemoveThread = enteredRemoveThread; + _exitRemoveThread = exitRemoveThread; + } + + public void superStartThread() + { + super.startThread(); + } + + @Override + protected void startThread() + { + switch (_started.incrementAndGet()) + { + case 1: + case 2: + case 3: + super.startThread(); + break; + + case 4: + // deliberately not start thread + break; + + default: + throw new IllegalStateException("too many threads started"); + } + } + + @Override + protected void removeThread(Thread thread) + { + try + { + _enteredRemoveThread.countDown(); + _exitRemoveThread.await(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + + super.removeThread(thread); + } + } + private class RunningJob implements Runnable { final CountDownLatch _run = new CountDownLatch(1); @@ -63,11 +116,6 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest this(name, false); } - public RunningJob(boolean fail) - { - this(null, fail); - } - public RunningJob(String name, boolean fail) { _name = name; @@ -90,7 +138,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest } catch (Exception e) { - LOG.debug(e); + LOG.debug("RunningJob failed", e); } finally { @@ -121,7 +169,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest final CountDownLatch _closed = new CountDownLatch(1); @Override - public void close() throws IOException + public void close() { _closed.countDown(); } @@ -133,7 +181,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest QueuedThreadPool tp = new QueuedThreadPool(); tp.setMinThreads(2); tp.setMaxThreads(4); - tp.setIdleTimeout(900); + tp.setIdleTimeout(1000); tp.setThreadsPriority(Thread.NORM_PRIORITY - 1); tp.start(); @@ -144,44 +192,49 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest // Doesn't shrink to less than min threads Thread.sleep(3 * tp.getIdleTimeout() / 2); - waitForThreads(tp, 2); - waitForIdle(tp, 2); + assertThat(tp.getThreads(), is(2)); + assertThat(tp.getIdleThreads(), is(2)); // Run job0 RunningJob job0 = new RunningJob("JOB0"); tp.execute(job0); assertTrue(job0._run.await(10, TimeUnit.SECONDS)); - waitForIdle(tp, 1); + assertThat(tp.getThreads(), is(2)); + assertThat(tp.getIdleThreads(), is(1)); // Run job1 RunningJob job1 = new RunningJob("JOB1"); tp.execute(job1); assertTrue(job1._run.await(10, TimeUnit.SECONDS)); - waitForThreads(tp, 2); - waitForIdle(tp, 0); + assertThat(tp.getThreads(), is(2)); + assertThat(tp.getIdleThreads(), is(0)); // Run job2 RunningJob job2 = new RunningJob("JOB2"); tp.execute(job2); assertTrue(job2._run.await(10, TimeUnit.SECONDS)); - waitForThreads(tp, 3); - waitForIdle(tp, 0); + assertThat(tp.getThreads(), is(3)); + assertThat(tp.getIdleThreads(), is(0)); // Run job3 RunningJob job3 = new RunningJob("JOB3"); tp.execute(job3); assertTrue(job3._run.await(10, TimeUnit.SECONDS)); - waitForThreads(tp, 4); - waitForIdle(tp, 0); + assertThat(tp.getThreads(), is(4)); assertThat(tp.getIdleThreads(), is(0)); + + // Check no short term change Thread.sleep(100); + assertThat(tp.getThreads(), is(4)); assertThat(tp.getIdleThreads(), is(0)); // Run job4. will be queued RunningJob job4 = new RunningJob("JOB4"); tp.execute(job4); - assertFalse(job4._run.await(1, TimeUnit.SECONDS)); + assertFalse(job4._run.await(250, TimeUnit.MILLISECONDS)); assertThat(tp.getThreads(), is(4)); + assertThat(tp.getIdleThreads(), is(0)); + assertThat(tp.getQueueSize(), is(1)); // finish job 0 job0._stopping.countDown(); @@ -191,12 +244,13 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest assertTrue(job4._run.await(10, TimeUnit.SECONDS)); assertThat(tp.getThreads(), is(4)); assertThat(tp.getIdleThreads(), is(0)); + assertThat(tp.getQueueSize(), is(0)); - // finish job 1 + // finish job 1, and its thread will become idle job1._stopping.countDown(); assertTrue(job1._stopped.await(10, TimeUnit.SECONDS)); waitForIdle(tp, 1); - assertThat(tp.getThreads(), is(4)); + waitForThreads(tp, 4); // finish job 2,3,4 job2._stopping.countDown(); @@ -206,15 +260,17 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest assertTrue(job3._stopped.await(10, TimeUnit.SECONDS)); assertTrue(job4._stopped.await(10, TimeUnit.SECONDS)); - waitForIdle(tp, 4); - assertThat(tp.getThreads(), is(4)); + // At beginning of the test we waited 1.5*idleTimeout, but + // never actually shrunk the pool because it was at minThreads. + // Now that all jobs are finished, one thread will figure out + // that it will go idle and will shrink itself out of the pool. + // Give it some time to detect that, but not too much to shrink + // two threads. + Thread.sleep(tp.getIdleTimeout() / 4); - long duration = System.nanoTime(); - waitForThreads(tp, 3); - assertThat(tp.getIdleThreads(), is(3)); - duration = System.nanoTime() - duration; - assertThat(TimeUnit.NANOSECONDS.toMillis(duration), Matchers.greaterThan(tp.getIdleTimeout() / 2L)); - assertThat(TimeUnit.NANOSECONDS.toMillis(duration), Matchers.lessThan(tp.getIdleTimeout() * 2L)); + // Now we have 3 idle threads. + waitForIdle(tp, 3); + assertThat(tp.getThreads(), is(3)); tp.stop(); } @@ -450,23 +506,134 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest tp.stop(); } + @Test + public void testSteadyShrink() throws Exception + { + CountDownLatch latch = new CountDownLatch(1); + Runnable job = () -> + { + try + { + latch.await(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + }; + + QueuedThreadPool tp = new QueuedThreadPool(); + tp.setMinThreads(2); + tp.setMaxThreads(10); + int timeout = 500; + tp.setIdleTimeout(timeout); + tp.setThreadsPriority(Thread.NORM_PRIORITY - 1); + + tp.start(); + waitForIdle(tp, 2); + waitForThreads(tp, 2); + + for (int i = 0; i < 10; i++) + { + tp.execute(job); + } + + waitForThreads(tp, 10); + int threads = tp.getThreads(); + // let the jobs run + latch.countDown(); + + for (int i = 5; i-- > 0; ) + { + Thread.sleep(timeout / 2); + tp.execute(job); + } + + // Assert that steady rate of jobs doesn't prevent some idling out + assertThat(tp.getThreads(), lessThan(threads)); + threads = tp.getThreads(); + for (int i = 5; i-- > 0; ) + { + Thread.sleep(timeout / 2); + tp.execute(job); + } + assertThat(tp.getThreads(), lessThan(threads)); + } + + @Test + public void testEnsureThreads() throws Exception + { + AtomicInteger started = new AtomicInteger(0); + + CountDownLatch enteredRemoveThread = new CountDownLatch(1); + CountDownLatch exitRemoveThread = new CountDownLatch(1); + TestQueuedThreadPool tp = new TestQueuedThreadPool(started, enteredRemoveThread, exitRemoveThread); + + tp.setMinThreads(2); + tp.setMaxThreads(10); + tp.setIdleTimeout(400); + tp.setThreadsPriority(Thread.NORM_PRIORITY - 1); + + tp.start(); + waitForIdle(tp, 2); + waitForThreads(tp, 2); + + RunningJob job1 = new RunningJob(); + RunningJob job2 = new RunningJob(); + RunningJob job3 = new RunningJob(); + tp.execute(job1); + tp.execute(job2); + tp.execute(job3); + + waitForThreads(tp, 3); + waitForIdle(tp, 0); + + // We stop job3, the thread becomes idle, thread decides to shrink, and then blocks in removeThread(). + job3.stop(); + assertTrue(enteredRemoveThread.await(5, TimeUnit.SECONDS)); + waitForThreads(tp, 3); + waitForIdle(tp, 1); + + // Executing job4 will not start a new thread because we already have 1 idle thread. + RunningJob job4 = new RunningJob(); + tp.execute(job4); + + // Allow thread to exit from removeThread(). + // The 4th thread is not actually started in our startThread() until tp.superStartThread() is called. + // Delay by 1000ms to check that ensureThreads is only starting one thread even though it is slow to start. + assertThat(started.get(), is(3)); + exitRemoveThread.countDown(); + Thread.sleep(1000); + + // Now startThreads() should have been called 4 times. + // Actually start the thread, and job4 should be run. + assertThat(started.get(), is(4)); + tp.superStartThread(); + assertTrue(job4._run.await(5, TimeUnit.SECONDS)); + + job1.stop(); + job2.stop(); + job4.stop(); + tp.stop(); + } + @Test public void testMaxStopTime() throws Exception { QueuedThreadPool tp = new QueuedThreadPool(); - tp.setStopTimeout(500); + long stopTimeout = 500; + tp.setStopTimeout(stopTimeout); tp.start(); + CountDownLatch interruptedLatch = new CountDownLatch(1); tp.execute(() -> { - while (true) + try { - try - { - Thread.sleep(10000); - } - catch (InterruptedException expected) - { - } + Thread.sleep(10 * stopTimeout); + } + catch (InterruptedException expected) + { + interruptedLatch.countDown(); } }); @@ -475,6 +642,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest long afterStop = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); assertTrue(tp.isStopped()); assertTrue(afterStop - beforeStop < 1000); + assertTrue(interruptedLatch.await(5, TimeUnit.SECONDS)); } private void waitForIdle(QueuedThreadPool tp, int idle) @@ -492,7 +660,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest } now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); } - assertEquals(idle, tp.getIdleThreads()); + assertThat(tp.getIdleThreads(), is(idle)); } private void waitForReserved(QueuedThreadPool tp, int reserved) @@ -511,7 +679,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest } now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); } - assertEquals(reserved, reservedThreadExecutor.getAvailable()); + assertThat(reservedThreadExecutor.getAvailable(), is(reserved)); } private void waitForThreads(QueuedThreadPool tp, int threads) @@ -529,7 +697,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest } now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); } - assertEquals(threads, tp.getThreads()); + assertThat(tp.getThreads(), is(threads)); } @Test @@ -582,10 +750,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest @Test public void testConstructorMinMaxThreadsValidation() { - assertThrows(IllegalArgumentException.class, () -> - { - new QueuedThreadPool(4, 8); - }); + assertThrows(IllegalArgumentException.class, () -> new QueuedThreadPool(4, 8)); } @Test diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ReservedThreadExecutorTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ReservedThreadExecutorTest.java index 043a6af59bb..5be9cd3f12e 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ReservedThreadExecutorTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ReservedThreadExecutorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; @@ -32,6 +32,8 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -183,6 +185,26 @@ public class ReservedThreadExecutorTest assertThat(_reservedExecutor.getAvailable(), is(0)); } + @Test + public void testReservedIdleTimeoutWithOneReservedThread() throws Exception + { + long idleTimeout = 500; + _reservedExecutor.stop(); + _reservedExecutor.setIdleTimeout(idleTimeout, TimeUnit.MILLISECONDS); + _reservedExecutor.start(); + + assertThat(_reservedExecutor.tryExecute(NOOP), is(false)); + Thread thread = _executor.startThread(); + assertNotNull(thread); + waitForAvailable(1); + + Thread.sleep(2 * idleTimeout); + + waitForAvailable(0); + thread.join(2 * idleTimeout); + assertFalse(thread.isAlive()); + } + protected void waitForAvailable(int size) throws InterruptedException { long started = System.nanoTime(); @@ -211,11 +233,16 @@ public class ReservedThreadExecutorTest _queue.addLast(task); } - public void startThread() + public Thread startThread() { Runnable task = _queue.pollFirst(); if (task != null) - new Thread(task).start(); + { + Thread thread = new Thread(task); + thread.start(); + return thread; + } + return null; } } @@ -244,7 +271,6 @@ public class ReservedThreadExecutorTest public void stressTest() throws Exception { QueuedThreadPool pool = new QueuedThreadPool(20); - pool.setStopTimeout(10000); pool.start(); ReservedThreadExecutor reserved = new ReservedThreadExecutor(pool, 10); reserved.setIdleTimeout(0, null); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java index aedbe1bce1c..dee33a0351d 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.logging.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; @@ -70,6 +70,7 @@ public class SchedulerTest } catch (Exception ignore) { + // no op } }); } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java index 4facf1e73f4..9e80559145a 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SweeperTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SweeperTest.java index c3529baa672..c24aaef5ee5 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SweeperTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SweeperTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; @@ -21,7 +21,7 @@ package org.eclipse.jetty.util.thread; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.logging.StacklessLogging; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -94,7 +94,7 @@ public class SweeperTest @Test public void testSweepThrows() throws Exception { - try (StacklessLogging scope = new StacklessLogging(Sweeper.class)) + try (StacklessLogging ignored = new StacklessLogging(Sweeper.class)) { long period = 500; final CountDownLatch taskLatch = new CountDownLatch(2); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadClassLoaderScopeTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadClassLoaderScopeTest.java index b5399bdc595..8a64d304688 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadClassLoaderScopeTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadClassLoaderScopeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadFactoryTest.java new file mode 100644 index 00000000000..40fac5cf835 --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadFactoryTest.java @@ -0,0 +1,104 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.util.thread; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.MultiException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ThreadFactoryTest +{ + @Test + public void testThreadFactory() throws Exception + { + ThreadGroup threadGroup = new ThreadGroup("my-group"); + MyThreadFactory threadFactory = new MyThreadFactory(threadGroup); + + QueuedThreadPool qtp = new QueuedThreadPool(200, 10, 2000, 0, null, threadGroup, threadFactory); + try + { + qtp.start(); + + int testThreads = 2000; + CountDownLatch threadsLatch = new CountDownLatch(testThreads); + MultiException mex = new MultiException(); + + for (int i = 0; i < testThreads; i++) + { + qtp.execute(() -> + { + try + { + TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(20, 500)); + Thread thread = Thread.currentThread(); + + if (!thread.getName().startsWith("My-")) + { + mex.add(new AssertionError("Thread " + thread.getName() + " does not start with 'My-'")); + } + + if (!thread.getThreadGroup().getName().equalsIgnoreCase("my-group")) + { + mex.add(new AssertionError("Thread Group " + thread.getThreadGroup().getName() + " is not 'my-group'")); + } + + threadsLatch.countDown(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + }); + } + + assertTrue(threadsLatch.await(5, TimeUnit.SECONDS), "Did not see all tasks finish"); + mex.ifExceptionThrow(); + } + finally + { + qtp.stop(); + } + } + + public static class MyThreadFactory implements ThreadFactory + { + private final ThreadGroup threadGroup; + + public MyThreadFactory(ThreadGroup threadGroup) + { + this.threadGroup = threadGroup; + } + + @Override + public Thread newThread(Runnable runnable) + { + Thread thread = new Thread(threadGroup, runnable); + thread.setDaemon(false); + thread.setPriority(Thread.MIN_PRIORITY); + thread.setName("My-" + thread.getId()); + return thread; + } + } +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsumeTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsumeTest.java index 35776bdb17d..1eaf69cfdd9 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsumeTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsumeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread.strategy; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java index f72cb423ccd..95602729038 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread.strategy; @@ -122,14 +122,7 @@ public class ExecutionStrategyTest { if (tasks-- > 0) { - return new Runnable() - { - @Override - public void run() - { - latch.countDown(); - } - }; + return () -> latch.countDown(); } return null; @@ -175,15 +168,7 @@ public class ExecutionStrategyTest try { final CountDownLatch latch = q.take(); - return new Runnable() - { - @Override - public void run() - { - // System.err.println("RUN "+id); - latch.countDown(); - } - }; + return () -> latch.countDown(); } catch (InterruptedException e) { diff --git a/jetty-util/src/test/resources/jar-file-resource.jar b/jetty-util/src/test/resources/jar-file-resource.jar new file mode 100644 index 00000000000..de93283a837 Binary files /dev/null and b/jetty-util/src/test/resources/jar-file-resource.jar differ diff --git a/jetty-util/src/test/resources/jetty-logging.properties b/jetty-util/src/test/resources/jetty-logging.properties index 7367559fac9..c82f81c0424 100644 --- a/jetty-util/src/test/resources/jetty-logging.properties +++ b/jetty-util/src/test/resources/jetty-logging.properties @@ -1,5 +1,5 @@ # Setup default logging implementation for during testing -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.util.LEVEL=DEBUG #org.eclipse.jetty.util.PathWatcher.LEVEL=DEBUG #org.eclipse.jetty.util.thread.QueuedThreadPool.LEVEL=DEBUG diff --git a/jetty-util/src/test/resources/keystore b/jetty-util/src/test/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/jetty-util/src/test/resources/keystore and /dev/null differ diff --git a/jetty-util/src/test/resources/keystore.jks b/jetty-util/src/test/resources/keystore.jks new file mode 100644 index 00000000000..862cff37b3d Binary files /dev/null and b/jetty-util/src/test/resources/keystore.jks differ diff --git a/jetty-util/src/test/resources/keystore.p12 b/jetty-util/src/test/resources/keystore.p12 index b51c835024b..6fe9c5aedbe 100644 Binary files a/jetty-util/src/test/resources/keystore.p12 and b/jetty-util/src/test/resources/keystore.p12 differ diff --git a/jetty-util/src/test/resources/keystore_sni.p12 b/jetty-util/src/test/resources/keystore_sni.p12 new file mode 100644 index 00000000000..6cef99e930d Binary files /dev/null and b/jetty-util/src/test/resources/keystore_sni.p12 differ diff --git a/jetty-util/src/test/resources/snikeystore b/jetty-util/src/test/resources/snikeystore deleted file mode 100644 index 3c69266e062..00000000000 Binary files a/jetty-util/src/test/resources/snikeystore and /dev/null differ diff --git a/jetty-util/src/test/resources/snikeystore.p12 b/jetty-util/src/test/resources/snikeystore.p12 new file mode 100644 index 00000000000..1a0959c6ed7 Binary files /dev/null and b/jetty-util/src/test/resources/snikeystore.p12 differ diff --git a/jetty-util/src/test/resources/test-base-resource.jar b/jetty-util/src/test/resources/test-base-resource.jar new file mode 100644 index 00000000000..aa3066909b3 Binary files /dev/null and b/jetty-util/src/test/resources/test-base-resource.jar differ diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index bd3e2766b4c..76a0f1b4788 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -80,6 +80,10 @@ jetty-xml ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty @@ -87,6 +91,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper @@ -98,10 +107,5 @@ ${project.version} test - - org.eclipse.jetty.toolchain - jetty-test-helper - test - diff --git a/jetty-webapp/src/main/config/etc/webdefault.xml b/jetty-webapp/src/main/config/etc/webdefault.xml index 891bd28727a..39a9efc4381 100644 --- a/jetty-webapp/src/main/config/etc/webdefault.xml +++ b/jetty-webapp/src/main/config/etc/webdefault.xml @@ -194,107 +194,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + jsp org.eclipse.jetty.jsp.JettyJspServlet - - logVerbosityLevel - DEBUG - - - fork - false - xpoweredBy false compilerTargetVM - 1.7 + 1.8 compilerSourceVM - 1.7 + 1.8 - 0 diff --git a/jetty-webapp/src/main/java/module-info.java b/jetty-webapp/src/main/java/module-info.java index c1c2772eb62..fc1fd191d5a 100644 --- a/jetty-webapp/src/main/java/module-info.java +++ b/jetty-webapp/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.webapp.Configuration; @@ -22,15 +22,10 @@ module org.eclipse.jetty.webapp { exports org.eclipse.jetty.webapp; - requires java.instrument; - requires java.xml; - requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.security; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.servlet; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.xml; + requires transitive java.instrument; + requires transitive org.eclipse.jetty.servlet; + requires transitive org.eclipse.jetty.xml; + requires org.slf4j; uses Configuration; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbsoluteOrdering.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbsoluteOrdering.java index 1b7ce025f58..1ec88c15f61 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbsoluteOrdering.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbsoluteOrdering.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -48,7 +48,7 @@ public class AbsoluteOrdering implements Ordering //1. put everything into the list of named others, and take the named ones out of there, //assuming we will want to use the clause - Map others = new HashMap(_metaData.getNamedFragments()); + Map others = new HashMap(_metaData.getNamedFragmentDescriptors()); //2. for each name, take out of the list of others, add to tail of list int index = -1; @@ -59,7 +59,7 @@ public class AbsoluteOrdering implements Ordering FragmentDescriptor f = others.remove(item); if (f != null) { - Resource jar = _metaData.getJarForFragment(item); + Resource jar = _metaData.getJarForFragmentName(item); orderedList.add(jar); //take from others and put into final list in order, ignoring duplicate names //remove resource from list for resource matching name of descriptor tmp.remove(jar); diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbstractConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbstractConfiguration.java index fa357cb63c3..e06225c2770 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbstractConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/AbstractConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -26,7 +26,7 @@ import java.util.stream.Collectors; public class AbstractConfiguration implements Configuration { - private final boolean _disabledByDefault; + private final boolean _enabledByDefault; private final List _after = new ArrayList<>(); private final List _beforeThis = new ArrayList<>(); private final ClassMatcher _system = new ClassMatcher(); @@ -34,12 +34,12 @@ public class AbstractConfiguration implements Configuration protected AbstractConfiguration() { - this(false); + this(true); } - protected AbstractConfiguration(boolean disabledByDefault) + protected AbstractConfiguration(boolean enabledByDefault) { - _disabledByDefault = disabledByDefault; + _enabledByDefault = enabledByDefault; } /** @@ -196,9 +196,9 @@ public class AbstractConfiguration implements Configuration } @Override - public boolean isDisabledByDefault() + public boolean isEnabledByDefault() { - return _disabledByDefault; + return _enabledByDefault; } @Override diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java index 74fc930afa7..ac1ab598e65 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -25,8 +25,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedOperation; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A WebAppClassLoader that caches {@link #getResource(String)} results. @@ -37,7 +37,7 @@ import org.eclipse.jetty.util.log.Logger; @ManagedObject public class CachingWebAppClassLoader extends WebAppClassLoader { - private static final Logger LOG = Log.getLogger(CachingWebAppClassLoader.class); + private static final Logger LOG = LoggerFactory.getLogger(CachingWebAppClassLoader.class); private final Set _notFound = ConcurrentHashMap.newKeySet(); private final ConcurrentHashMap _cache = new ConcurrentHashMap<>(); @@ -104,8 +104,7 @@ public class CachingWebAppClassLoader extends WebAppClassLoader if (_notFound.add(name)) if (LOG.isDebugEnabled()) { - LOG.debug("Caching not found {}", name); - LOG.debug(nfe); + LOG.debug("Caching not found {}", name, nfe); } throw nfe; } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClassMatcher.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClassMatcher.java index 3a695cf4ac6..63ce3599f65 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClassMatcher.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClassMatcher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -43,9 +43,9 @@ import org.eclipse.jetty.util.IncludeExcludeSet; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A matcher for classes based on package and/or location and/or module/ @@ -70,9 +70,9 @@ import org.eclipse.jetty.util.resource.Resource; public class ClassMatcher extends AbstractSet { - private static final Logger LOG = Log.getLogger(ClassMatcher.class); + private static final Logger LOG = LoggerFactory.getLogger(ClassMatcher.class); - private static class Entry + public static class Entry { private final String _pattern; private final String _name; @@ -723,7 +723,7 @@ public class ClassMatcher extends AbstractSet } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to match against {}", clazz, e); } return false; } @@ -745,26 +745,49 @@ public class ClassMatcher extends AbstractSet } catch (URISyntaxException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return null; } }); } - - private static boolean combine(IncludeExcludeSet names, String name, IncludeExcludeSet locations, Supplier location) + + /** + * Match a class against inclusions and exclusions by name and location. + * Name based checks are performed before location checks. For a class to match, + * it must not be excluded by either name or location, and must either be explicitly + * included, or for there to be no inclusions. In the case where the location + * of the class is null, it will match if it is included by name, or + * if there are no location exclusions. + * + * @param names configured inclusions and exclusions by name + * @param name the name to check + * @param locations configured inclusions and exclusions by location + * @param location the location of the class (can be null) + * @return true if the class is not excluded but is included, or there are + * no inclusions. False otherwise. + */ + static boolean combine(IncludeExcludeSet names, String name, IncludeExcludeSet locations, Supplier location) { + // check the name set Boolean byName = names.isIncludedAndNotExcluded(name); + + // If we excluded by name, then no match if (Boolean.FALSE == byName) return false; + // check the location set URI uri = location.get(); - if (uri == null) - return locations.isEmpty() || locations.hasExcludes() && !locations.hasIncludes(); + Boolean byLocation = uri == null ? null : locations.isIncludedAndNotExcluded(uri); - Boolean byLocation = locations.isIncludedAndNotExcluded(uri); - if (Boolean.FALSE == byLocation) + // If we excluded by location or couldn't check location exclusion, then no match + if (Boolean.FALSE == byLocation || (locations.hasExcludes() && uri == null)) return false; - return Boolean.TRUE.equals(byName) || Boolean.TRUE.equals(byLocation) || !(names.hasIncludes() || locations.hasIncludes()); + // If there are includes, then we must be included to match. + if (names.hasIncludes() || locations.hasIncludes()) + return byName == Boolean.TRUE || byLocation == Boolean.TRUE; + + // Otherwise there are no includes and it was not excluded, so match + return true; } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configuration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configuration.java index 48e1bef7a26..7bce5454db7 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configuration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configuration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -34,12 +34,12 @@ import org.eclipse.jetty.util.TopologicalSort; *

      *

      Configuration instances are discovered by the {@link Configurations} class using either the * {@link ServiceLoader} mechanism or by an explicit call to {@link Configurations#setKnown(String...)}. - * By default, all Configurations that do not implement the {@link #isDisabledByDefault()} interface + * By default, all Configurations that do not return false from {@link #isEnabledByDefault()} * are applied to all {@link WebAppContext}s within the JVM. However a Server wide default {@link Configurations} * collection may also be defined with {@link Configurations#setServerDefault(org.eclipse.jetty.server.Server)}. * Furthermore, each individual Context may have its Configurations list explicitly set and/or amended with * {@link WebAppContext#setConfigurations(Configuration[])}, {@link WebAppContext#addConfiguration(Configuration...)} - * or {@link WebAppContext#getWebAppConfigurations()}. + * or {@link WebAppContext#getConfigurations()}. *

      *

      Since Jetty-9.4, Configurations are self ordering using the {@link #getDependencies()} and * {@link #getDependents()} methods for a {@link TopologicalSort} initiated by {@link Configurations#sort()} @@ -171,12 +171,12 @@ public interface Configuration void destroy(WebAppContext context) throws Exception; /** - * @return true if configuration is disabled by default + * @return true if configuration is enabled by default */ - boolean isDisabledByDefault(); + boolean isEnabledByDefault(); /** * @return true if configuration should be aborted */ boolean abort(WebAppContext context); -} \ No newline at end of file +} diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java index 9868d7f570a..c43eac366bd 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -37,11 +37,12 @@ import java.util.stream.Collectors; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.TopologicalSort; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An ordered list of {@link Configuration} instances. @@ -64,7 +65,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class Configurations extends AbstractList implements Dumpable { - private static final Logger LOG = Log.getLogger(Configurations.class); + private static final Logger LOG = LoggerFactory.getLogger(Configurations.class); private static final List __known = new ArrayList<>(); private static final List __unavailable = new ArrayList<>(); @@ -74,27 +75,26 @@ public class Configurations extends AbstractList implements Dumpa { if (__known.isEmpty()) { - ServiceLoader configs = ServiceLoader.load(Configuration.class); - for (Iterator i = configs.iterator(); i.hasNext(); ) + TypeUtil.serviceProviderStream(ServiceLoader.load(Configuration.class)).forEach(provider -> { try { - Configuration configuration = i.next(); + Configuration configuration = provider.get(); if (!configuration.isAvailable()) { if (LOG.isDebugEnabled()) LOG.debug("Configuration unavailable: " + configuration); __unavailable.add(configuration); - continue; + return; } __known.add(configuration); __knownByClassName.add(configuration.getClass().getName()); } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Unable to get known Configuration", e); } - } + }); sort(__known); if (LOG.isDebugEnabled()) @@ -209,7 +209,7 @@ public class Configurations extends AbstractList implements Dumpa if (configurations == null) { configurations = new Configurations(Configurations.getKnown().stream() - .filter(c -> !c.isDisabledByDefault()) + .filter(c -> c.isEnabledByDefault()) .map(c -> c.getClass().getName()) .toArray(String[]::new)); } @@ -279,6 +279,27 @@ public class Configurations extends AbstractList implements Dumpa } } + public T get(Class configClass) + { + for (Configuration configuration : _configurations) + { + if (configClass.isAssignableFrom(configuration.getClass())) + return (T)configuration; + } + return null; + } + + public List getConfigurations(Class configClass) + { + List list = new ArrayList<>(); + for (Configuration configuration : _configurations) + { + if (configClass.isAssignableFrom(configuration.getClass())) + list.add((T)configuration); + } + return list; + } + public void clear() { _configurations.clear(); diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DecoratingListener.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DecoratingListener.java new file mode 100644 index 00000000000..07baed4fdc2 --- /dev/null +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DecoratingListener.java @@ -0,0 +1,62 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.webapp; + +import org.eclipse.jetty.servlet.ServletContextHandler; + +/** + * An extended org.eclipse.jetty.servlet.DecoratingListener. + * The context attribute "org.eclipse.jetty.webapp.DecoratingListener" if + * not set, is set to the name of the attribute this listener listens for. + */ +public class DecoratingListener extends org.eclipse.jetty.servlet.DecoratingListener +{ + public static final String DECORATOR_ATTRIBUTE = "org.eclipse.jetty.webapp.decorator"; + + public DecoratingListener() + { + this(DECORATOR_ATTRIBUTE); + } + + public DecoratingListener(String attributeName) + { + this(WebAppContext.getCurrentWebAppContext(), attributeName); + } + + public DecoratingListener(ServletContextHandler context) + { + this(context, DECORATOR_ATTRIBUTE); + } + + public DecoratingListener(ServletContextHandler context, String attributeName) + { + super(context, attributeName); + checkAndSetAttributeName(); + } + + protected void checkAndSetAttributeName() + { + // If not set (by another DecoratingListener), flag the attribute that are + // listening for. If more than one DecoratingListener is used then this + // attribute reflects only the first. + if (getServletContext().getAttribute(getClass().getName()) != null) + throw new IllegalStateException("Multiple DecoratingListeners detected"); + getServletContext().setAttribute(getClass().getName(), getAttributeName()); + } +} diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java index a494ece0ef2..c8c3d85ad24 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java index 6e0e6b41f17..73d8ec543e8 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java @@ -1,23 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; +import java.util.Objects; + import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlParser; @@ -26,30 +28,21 @@ public abstract class Descriptor protected Resource _xml; protected XmlParser.Node _root; protected String _dtd; - protected boolean _validating; public Descriptor(Resource xml) { - _xml = xml; + _xml = Objects.requireNonNull(xml); } - public abstract XmlParser ensureParser() - throws ClassNotFoundException; - - public void setValidating(boolean validating) - { - _validating = validating; - } - - public void parse() + public void parse(XmlParser parser) throws Exception { if (_root == null) { + Objects.requireNonNull(parser); try { - XmlParser parser = ensureParser(); _root = parser.parse(_xml.getInputStream()); _dtd = parser.getDTD(); } @@ -60,6 +53,11 @@ public abstract class Descriptor } } + public boolean isParsed() + { + return _root != null; + } + public Resource getResource() { return _xml; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DescriptorProcessor.java index 03871812607..2e74a814a54 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DescriptorProcessor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DescriptorProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java index 4cd240bbbe0..54c8219e3a1 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java @@ -1,27 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * DiscoveredAnnotation @@ -31,7 +31,7 @@ import org.eclipse.jetty.util.resource.Resource; */ public abstract class DiscoveredAnnotation { - private static final Logger LOG = Log.getLogger(DiscoveredAnnotation.class); + private static final Logger LOG = LoggerFactory.getLogger(DiscoveredAnnotation.class); protected WebAppContext _context; protected String _className; @@ -52,6 +52,11 @@ public abstract class DiscoveredAnnotation _resource = resource; } + public String getClassName() + { + return _className; + } + public Resource getResource() { return _resource; @@ -81,7 +86,13 @@ public abstract class DiscoveredAnnotation } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to load {}", _className, e); } } + + @Override + public String toString() + { + return getClass().getName() + "[" + getClassName() + "," + getResource() + "]"; + } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java index 587991e9bd9..a0cbfa1e901 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -66,11 +66,11 @@ public class FragmentConfiguration extends AbstractConfiguration { if (key.isDirectory()) //tolerate the case where the library is a directory, not a jar. useful for OSGi for example { - metaData.addFragment(key, frags.get(key)); + metaData.addFragmentDescriptor(key, new FragmentDescriptor(frags.get(key))); } else //the standard case: a jar most likely inside WEB-INF/lib { - metaData.addFragment(key, frags.get(key)); + metaData.addFragmentDescriptor(key, new FragmentDescriptor(frags.get(key))); } } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java index ececeef9979..feda54dbf71 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/FragmentDescriptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -60,10 +60,10 @@ public class FragmentDescriptor extends WebDescriptor } @Override - public void parse() + public void parse(XmlParser parser) throws Exception { - super.parse(); + super.parse(parser); processName(); } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java index a9f8de9502f..79bcc151737 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JaasConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JaasConfiguration.java index bf5cd0b9ed3..c0fe0531378 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JaasConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JaasConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -21,8 +21,8 @@ package org.eclipse.jetty.webapp; import java.util.ServiceLoader; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      JAAS Configuration

      @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JaasConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(JaasConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(JaasConfiguration.class); public JaasConfiguration() { @@ -54,7 +54,7 @@ public class JaasConfiguration extends AbstractConfiguration } catch (Throwable e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return false; } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java index 1fc0a909cb2..d5d1c152d15 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -21,10 +21,10 @@ package org.eclipse.jetty.webapp; import java.io.IOException; import java.util.Map; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JettyWebConfiguration. @@ -33,7 +33,7 @@ import org.eclipse.jetty.xml.XmlConfiguration; */ public class JettyWebXmlConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(JettyWebXmlConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyWebXmlConfiguration.class); public static final String PROPERTY_WEB_INF_URI = "web-inf.uri"; public static final String PROPERTY_WEB_INF = "web-inf"; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JmxConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JmxConfiguration.java index 215a33ae2a9..b3cd43540b5 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JmxConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JmxConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -21,8 +21,8 @@ package org.eclipse.jetty.webapp; import java.util.ServiceLoader; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      JMX Configuration

      @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JmxConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(JmxConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(JmxConfiguration.class); public JmxConfiguration() { @@ -53,7 +53,7 @@ public class JmxConfiguration extends AbstractConfiguration } catch (Throwable e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return false; } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JndiConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JndiConfiguration.java index b1f454edd4b..a4587c26e62 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JndiConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JndiConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -21,8 +21,8 @@ package org.eclipse.jetty.webapp; import java.util.ServiceLoader; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      JNDI Configuration

      @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JndiConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(JndiConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(JndiConfiguration.class); public JndiConfiguration() { @@ -54,7 +54,7 @@ public class JndiConfiguration extends AbstractConfiguration } catch (Throwable e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return false; } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JspConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JspConfiguration.java index 789853333fe..cc4cf28e518 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JspConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/JspConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -21,8 +21,8 @@ package org.eclipse.jetty.webapp; import java.util.ServiceLoader; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      JSP Configuration

      @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class JspConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(JspConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(JspConfiguration.class); public JspConfiguration() { @@ -56,7 +56,7 @@ public class JspConfiguration extends AbstractConfiguration } catch (Throwable e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return false; } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java index 0758e441616..5afc94ae9b9 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -24,12 +24,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import javax.servlet.ServletContext; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.EmptyResource; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MetaData @@ -38,42 +39,72 @@ import org.eclipse.jetty.util.resource.Resource; */ public class MetaData { - private static final Logger LOG = Log.getLogger(MetaData.class); + private static final Logger LOG = LoggerFactory.getLogger(MetaData.class); public static final String VALIDATE_XML = "org.eclipse.jetty.webapp.validateXml"; public static final String ORDERED_LIBS = "javax.servlet.context.orderedLibs"; public static final Resource NON_FRAG_RESOURCE = EmptyResource.INSTANCE; - protected Map _origins = new HashMap(); + protected Map _origins = new HashMap<>(); protected WebDescriptor _webDefaultsRoot; protected WebDescriptor _webXmlRoot; - protected final List _webOverrideRoots = new ArrayList(); + protected final List _webOverrideRoots = new ArrayList<>(); protected boolean _metaDataComplete; - protected final List _descriptorProcessors = new ArrayList(); - protected final List _webFragmentRoots = new ArrayList(); - protected final Map _webFragmentNameMap = new HashMap(); - protected final Map _webFragmentResourceMap = new HashMap(); - protected final Map> _annotations = new HashMap>(); - protected final List _webInfClasses = new ArrayList(); - protected final List _webInfJars = new ArrayList(); - protected final List _orderedContainerResources = new ArrayList(); - protected final List _orderedWebInfResources = new ArrayList(); + protected final List _descriptorProcessors = new ArrayList<>(); + protected final List _webFragmentRoots = new ArrayList<>(); + protected final Map _webFragmentNameMap = new HashMap<>(); + protected final Map _webFragmentResourceMap = new HashMap<>(); + protected final Map> _annotations = new HashMap<>(); + protected final List _webInfClasses = new ArrayList<>(); + protected final List _webInfJars = new ArrayList<>(); + protected final List _orderedContainerResources = new ArrayList<>(); + protected final List _orderedWebInfResources = new ArrayList<>(); protected Ordering _ordering;//can be set to RelativeOrdering by web-default.xml, web.xml, web-override.xml protected boolean _allowDuplicateFragmentNames = false; protected boolean _validateXml = false; + public enum Complete + { + NotSet, True, False + } + + /** + * Metadata regarding where a deployable element was declared: + * by annotation or by descriptor. + */ public static class OriginInfo { + /** + * Identifier for the deployable element + */ private final String name; + + /** + * Origin of the deployable element + */ private final Origin origin; + + /** + * Reference to the descriptor, if declared in one + */ private final Descriptor descriptor; + + /** + * Reference to the annotation, if declared by one + */ private final Annotation annotation; + + /** + * The class containing the annotation, if declared by one + */ private final Class annotated; public OriginInfo(String n, Annotation a, Class ac) { + if (Objects.isNull(n)) + throw new IllegalArgumentException("No name"); name = n; - origin = Origin.Annotation; + origin = Origin.of(a); descriptor = null; annotation = a; annotated = ac; @@ -81,24 +112,21 @@ public class MetaData public OriginInfo(String n, Descriptor d) { + if (Objects.isNull(n)) + throw new IllegalArgumentException("No name"); + if (Objects.isNull(d)) + throw new IllegalArgumentException("No descriptor"); name = n; + origin = Origin.of(d); descriptor = d; annotation = null; annotated = null; - if (d == null) - throw new IllegalArgumentException("No descriptor"); - if (d instanceof FragmentDescriptor) - origin = Origin.WebFragment; - else if (d instanceof OverrideDescriptor) - origin = Origin.WebOverride; - else if (d instanceof DefaultsDescriptor) - origin = Origin.WebDefaults; - else - origin = Origin.WebXml; } public OriginInfo(String n) { + if (Objects.isNull(n)) + throw new IllegalArgumentException("No name"); name = n; origin = Origin.API; annotation = null; @@ -159,12 +187,16 @@ public class MetaData _allowDuplicateFragmentNames = false; } - public void setDefaults(Resource webDefaults) + /** + * Set the web-default.xml. + * + * @param descriptor the web-default.xml + */ + public void setDefaultsDescriptor(DefaultsDescriptor descriptor) throws Exception { - _webDefaultsRoot = new DefaultsDescriptor(webDefaults); - _webDefaultsRoot.setValidating(isValidateXml()); - _webDefaultsRoot.parse(); + _webDefaultsRoot = descriptor; + _webDefaultsRoot.parse(WebDescriptor.getParser(isValidateXml())); if (_webDefaultsRoot.isOrdered()) { Ordering ordering = getOrdering(); @@ -185,13 +217,15 @@ public class MetaData } } - public void setWebXml(Resource webXml) + /** + * @param descriptor the web.xml descriptor + */ + public void setWebDescriptor(WebDescriptor descriptor) throws Exception { - _webXmlRoot = new WebDescriptor(webXml); - _webXmlRoot.setValidating(isValidateXml()); - _webXmlRoot.parse(); - _metaDataComplete = _webXmlRoot.getMetaDataComplete() == MetaDataComplete.True; + _webXmlRoot = descriptor; + _webXmlRoot.parse(WebDescriptor.getParser(isValidateXml())); + _metaDataComplete = WebDescriptor.isMetaDataComplete(_webXmlRoot); if (_webXmlRoot.isOrdered()) { @@ -213,14 +247,17 @@ public class MetaData } } - public void addOverride(Resource override) + /** + * Add a override-web.xml descriptor. + * + * @param descriptor the override-web.xml + */ + public void addOverrideDescriptor(OverrideDescriptor descriptor) throws Exception { - OverrideDescriptor webOverrideRoot = new OverrideDescriptor(override); - webOverrideRoot.setValidating(false); - webOverrideRoot.parse(); + descriptor.parse(WebDescriptor.getParser(isValidateXml())); - switch (webOverrideRoot.getMetaDataComplete()) + switch (descriptor.getMetaDataComplete()) { case True: _metaDataComplete = true; @@ -232,14 +269,14 @@ public class MetaData break; } - if (webOverrideRoot.isOrdered()) + if (descriptor.isOrdered()) { Ordering ordering = getOrdering(); if (ordering == null) ordering = new AbsoluteOrdering(this); - List order = webOverrideRoot.getOrdering(); + List order = descriptor.getOrdering(); for (String s : order) { if (s.equalsIgnoreCase("others")) @@ -251,29 +288,29 @@ public class MetaData //set or reset the ordering to cause the webinf jar ordering to be recomputed setOrdering(ordering); } - _webOverrideRoots.add(webOverrideRoot); + _webOverrideRoots.add(descriptor); } /** - * Add a web-fragment.xml + * Add a web-fragment.xml, and the jar it is contained in. * - * @param jarResource the jar the fragment is contained in - * @param xmlResource the resource representing the xml file + * @param jarResource the jar of the fragment + * @param descriptor web-fragment.xml * @throws Exception if unable to add fragment */ - public void addFragment(Resource jarResource, Resource xmlResource) + public void addFragmentDescriptor(Resource jarResource, FragmentDescriptor descriptor) throws Exception { if (_metaDataComplete) return; //do not process anything else if web.xml/web-override.xml set metadata-complete + Objects.requireNonNull(jarResource); + Objects.requireNonNull(descriptor); + //Metadata-complete is not set, or there is no web.xml - FragmentDescriptor descriptor = new FragmentDescriptor(xmlResource); _webFragmentResourceMap.put(jarResource, descriptor); _webFragmentRoots.add(descriptor); - - descriptor.setValidating(isValidateXml()); - descriptor.parse(); + descriptor.parse(WebDescriptor.getParser(isValidateXml())); if (descriptor.getName() != null) { @@ -298,8 +335,8 @@ public class MetaData } /** - * Annotations not associated with a WEB-INF/lib fragment jar. - * These are from WEB-INF/classes or the ??container path?? + * Annotations such as WebServlet, WebFilter, WebListener that + * can be discovered by scanning unloaded classes. * * @param annotations the list of discovered annotations to add */ @@ -315,7 +352,8 @@ public class MetaData /** * Add an annotation that has been discovered on a class, method or field within a resource - * eg a jar or dir. + * eg a jar or dir. The annotation may also have no associated resource, or that resource + * may be a system or container resource. * * This method is synchronized as it is anticipated that it may be called by many threads * during the annotation scanning phase. @@ -327,21 +365,69 @@ public class MetaData if (annotation == null) return; - //if no resource associated with an annotation or the resource is not one of the WEB-INF/lib jars, - //map it to empty resource + //if no resource associated with an annotation map it to empty resource - these + //annotations will always be processed first + Resource enclosingResource = EmptyResource.INSTANCE; Resource resource = annotation.getResource(); - if (resource == null || !_webInfJars.contains(resource)) - resource = EmptyResource.INSTANCE; + if (resource != null) + { + //check if any of the web-inf classes dirs is a parent + enclosingResource = getEnclosingResource(_webInfClasses, resource); - List list = _annotations.get(resource); + //check if any of the web-inf jars is a parent + if (enclosingResource == null) + enclosingResource = getEnclosingResource(_webInfJars, resource); + + //check if any of the container resources is a parent + if (enclosingResource == null) + enclosingResource = getEnclosingResource(_orderedContainerResources, resource); + + //Couldn't find a parent resource in any of the known resources, map it to the empty resource + if (enclosingResource == null) + enclosingResource = EmptyResource.INSTANCE; + } + + List list = _annotations.get(enclosingResource); if (list == null) { - list = new ArrayList(); - _annotations.put(resource, list); + list = new ArrayList<>(); + _annotations.put(enclosingResource, list); } + list.add(annotation); } + /** + * Check if the resource is contained within one of the list of resources. + * In other words, check if the given resource is a sub-resource of one + * of the list of resources. + * + * @param resources the list of resources to check against + * @param resource the resource for which to find the parent resource + * @return the resource from the list that contains the given resource. + */ + private Resource getEnclosingResource(List resources, Resource resource) + { + Resource enclosingResource = null; + try + { + for (Resource r : resources) + { + if (Resource.isContainedIn(resource, r)) + { + enclosingResource = r; + break; + } + } + return enclosingResource; + } + catch (Exception e) + { + LOG.warn("Not contained within?", e); + return null; + } + } + public void addDescriptorProcessor(DescriptorProcessor p) { _descriptorProcessors.add(p); @@ -375,9 +461,9 @@ public class MetaData // Set the ordered lib attribute List orderedWebInfJars = null; - if (getOrdering() != null) + if (isOrdered()) { - orderedWebInfJars = getOrderedWebInfJars(); + orderedWebInfJars = getWebInfResources(true); List orderedLibs = new ArrayList(); for (Resource webInfJar : orderedWebInfJars) { @@ -387,7 +473,7 @@ public class MetaData int j = fullname.lastIndexOf("/", i); orderedLibs.add(fullname.substring(j + 1, i + 4)); } - context.setAttribute(ServletContext.ORDERED_LIBS, orderedLibs); + context.setAttribute(ServletContext.ORDERED_LIBS, Collections.unmodifiableList(orderedLibs)); } // set the webxml version @@ -397,40 +483,29 @@ public class MetaData context.getServletContext().setEffectiveMinorVersion(_webXmlRoot.getMinorVersion()); } + //process web-defaults.xml, web.xml and override-web.xmls for (DescriptorProcessor p : _descriptorProcessors) { - p.process(context, getWebDefault()); - p.process(context, getWebXml()); - for (WebDescriptor wd : getOverrideWebs()) + p.process(context, getDefaultsDescriptor()); + p.process(context, getWebDescriptor()); + for (WebDescriptor wd : getOverrideDescriptors()) { - LOG.debug("process {} {}", context, wd); + LOG.debug("process {} {} {}", context, p, wd); p.process(context, wd); } } - //get an apply the annotations that are not associated with a fragment (and hence for - //which no ordering applies - List nonFragAnnotations = _annotations.get(NON_FRAG_RESOURCE); - if (nonFragAnnotations != null) - { - for (DiscoveredAnnotation a : nonFragAnnotations) - { - LOG.debug("apply {}", a); - a.apply(); - } - } - - //apply the annotations that are associated with a fragment, according to the - //established ordering - List resources = null; - - if (getOrdering() != null) - resources = orderedWebInfJars; - else - resources = getWebInfJars(); + List resources = new ArrayList<>(); + resources.add(EmptyResource.INSTANCE); //always apply annotations with no resource first + resources.addAll(_orderedContainerResources); //next all annotations from container path + resources.addAll(_webInfClasses);//next everything from web-inf classes + resources.addAll(getWebInfResources(isOrdered())); //finally annotations (in order) from webinf path for (Resource r : resources) { + //Process the web-fragment.xml before applying annotations from a fragment. + //Note that some fragments, or resources that aren't fragments won't have + //a descriptor. FragmentDescriptor fd = _webFragmentResourceMap.get(r); if (fd != null) { @@ -441,10 +516,13 @@ public class MetaData } } - List fragAnnotations = _annotations.get(r); - if (fragAnnotations != null) + //Then apply the annotations - note that if metadata is complete + //either overall or for a fragment, those annotations won't have + //been discovered. + List annotations = _annotations.get(r); + if (annotations != null) { - for (DiscoveredAnnotation a : fragAnnotations) + for (DiscoveredAnnotation a : annotations) { LOG.debug("apply {}", a); a.apply(); @@ -453,6 +531,13 @@ public class MetaData } } + /** + * A webapp is distributable if web.xml is metadata-complete and + * distributable=true, or if metadata-complete is false, but all + * web-fragments.xml are distributable=true. + * + * @return true if the webapp is distributable, false otherwise + */ public boolean isDistributable() { boolean distributable = ( @@ -464,9 +549,9 @@ public class MetaData distributable &= d.isDistributable(); } - if (getOrdering() != null) + if (isOrdered()) { - List orderedResources = getOrderedWebInfJars(); + List orderedResources = getWebInfResources(true); for (Resource r : orderedResources) { FragmentDescriptor d = _webFragmentResourceMap.get(r); @@ -477,44 +562,24 @@ public class MetaData return distributable; } - public WebDescriptor getWebXml() + public WebDescriptor getWebDescriptor() { return _webXmlRoot; } - public List getOverrideWebs() + public List getOverrideDescriptors() { return _webOverrideRoots; } - public WebDescriptor getWebDefault() + public WebDescriptor getDefaultsDescriptor() { return _webDefaultsRoot; } - public List getFragments() + public boolean isOrdered() { - return _webFragmentRoots; - } - - public List getOrderedWebInfJars() - { - return _orderedWebInfResources; - } - - public List getOrderedFragments() - { - List list = new ArrayList(); - if (getOrdering() == null) - return list; - - for (Resource r : getOrderedWebInfJars()) - { - FragmentDescriptor fd = _webFragmentResourceMap.get(r); - if (fd != null) - list.add(fd); - } - return list; + return getOrdering() != null; } public Ordering getOrdering() @@ -528,32 +593,60 @@ public class MetaData orderFragments(); } - public FragmentDescriptor getFragment(Resource jar) - { - return _webFragmentResourceMap.get(jar); - } - - public FragmentDescriptor getFragment(String name) + /** + * @param name the name specified in a web-fragment.xml + * @return the web-fragment.xml that defines that name or null + */ + public FragmentDescriptor getFragmentDescriptor(String name) { return _webFragmentNameMap.get(name); } - public Resource getJarForFragment(String name) + /** + * @param descriptorResource the web-fragment.xml location as a Resource + * @return the FrgmentDescriptor for the web-fragment.xml, or null if none exists + */ + public FragmentDescriptor getFragmentDescriptor(Resource descriptorResource) { - FragmentDescriptor f = getFragment(name); + return _webFragmentRoots.stream().filter(d -> d.getResource().equals(descriptorResource)).findFirst().orElse(null); + } + + /** + * @param name the name specified in a web-fragment.xml + * @return the jar that contains the web-fragment.xml with the given name or null + */ + public Resource getJarForFragmentName(String name) + { + Resource jar = null; + + FragmentDescriptor f = getFragmentDescriptor(name); if (f == null) return null; - Resource jar = null; - for (Resource r : _webFragmentResourceMap.keySet()) + for (Map.Entry entry : _webFragmentResourceMap.entrySet()) { - if (_webFragmentResourceMap.get(r).equals(f)) - jar = r; + if (entry.getValue().equals(f)) + jar = entry.getKey(); } return jar; } - public Map getNamedFragments() + /** + * Get the web-fragment.xml related to a jar + * + * @param jar the jar to check for a mapping to web-fragment.xml + * @return the FragmentDescriptor or null if no web-fragment.xml is associated with the jar + */ + public FragmentDescriptor getFragmentDescriptorForJar(Resource jar) + { + return _webFragmentResourceMap.get(jar); + } + + /** + * @return a map of name to FragmentDescriptor, for those FragmentDescriptors that + * define a name element. + */ + public Map getNamedFragmentDescriptors() { return Collections.unmodifiableMap(_webFragmentNameMap); } @@ -586,6 +679,9 @@ public class MetaData public void setOrigin(String name, Descriptor d) { + if (name == null) + return; + OriginInfo x = new OriginInfo(name, d); _origins.put(name, x); } @@ -613,19 +709,22 @@ public class MetaData return _metaDataComplete; } - public void addWebInfJar(Resource newResource) + public void addWebInfResource(Resource newResource) { _webInfJars.add(newResource); } - public List getWebInfJars() + public List getWebInfResources(boolean withOrdering) { - return Collections.unmodifiableList(_webInfJars); + if (!withOrdering) + return Collections.unmodifiableList(_webInfJars); + else + return Collections.unmodifiableList(_orderedWebInfResources); } public List getContainerResources() { - return _orderedContainerResources; + return Collections.unmodifiableList(_orderedContainerResources); } public void addContainerResource(Resource jar) @@ -633,14 +732,14 @@ public class MetaData _orderedContainerResources.add(jar); } - public void setWebInfClassesDirs(List dirs) + public void setWebInfClassesResources(List dirs) { _webInfClasses.addAll(dirs); } - public List getWebInfClassesDirs() + public List getWebInfClassesResources() { - return _webInfClasses; + return Collections.unmodifiableList(_webInfClasses); } public boolean isAllowDuplicateFragmentNames() @@ -650,11 +749,11 @@ public class MetaData public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames) { - this._allowDuplicateFragmentNames = allowDuplicateFragmentNames; + _allowDuplicateFragmentNames = allowDuplicateFragmentNames; } /** - * @return the validateXml + * @return true if the parser validates, false otherwise */ public boolean isValidateXml() { @@ -662,7 +761,7 @@ public class MetaData } /** - * @param validateXml the validateXml to set + * @param validateXml if true xml syntax is validated by the parser, false otherwise */ public void setValidateXml(boolean validateXml) { diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaDataComplete.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaDataComplete.java deleted file mode 100644 index 860e3d5b4f4..00000000000 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaDataComplete.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.webapp; - -public enum MetaDataComplete -{ - NotSet, True, False -} diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java index 476f863edb1..b45e52a088b 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -42,11 +42,11 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.eclipse.jetty.util.PatternMatcher; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.EmptyResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MetaInfConfiguration @@ -67,7 +67,7 @@ import org.eclipse.jetty.util.resource.ResourceCollection; */ public class MetaInfConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(MetaInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(MetaInfConfiguration.class); public static final String USE_CONTAINER_METAINF_CACHE = "org.eclipse.jetty.metainf.useCache"; public static final boolean DEFAULT_USE_CONTAINER_METAINF_CACHE = true; @@ -144,7 +144,7 @@ public class MetaInfConfiguration extends AbstractConfiguration @Override public void matched(URI uri) throws Exception { - _context.getMetaData().addWebInfJar(Resource.newResource(uri)); + _context.getMetaData().addWebInfResource(Resource.newResource(uri)); } } @@ -169,7 +169,7 @@ public class MetaInfConfiguration extends AbstractConfiguration findAndFilterWebAppPaths(context); //No pattern to appy to classes, just add to metadata - context.getMetaData().setWebInfClassesDirs(findClassDirs(context)); + context.getMetaData().setWebInfClassesResources(findClassDirs(context)); scanJars(context); } @@ -358,7 +358,7 @@ public class MetaInfConfiguration extends AbstractConfiguration List scanTypes = new ArrayList<>(__allScanTypes); if (context.getMetaData().isMetaDataComplete() || (context.getServletContext().getEffectiveMajorVersion() < 3) && !context.isConfigurationDiscovered()) scanTypes.remove(METAINF_FRAGMENTS); - scanJars(context, context.getMetaData().getWebInfJars(), false, scanTypes); + scanJars(context, context.getMetaData().getWebInfResources(false), false, scanTypes); } /** @@ -789,7 +789,7 @@ public class MetaInfConfiguration extends AbstractConfiguration } catch (Exception ex) { - LOG.warn(Log.EXCEPTION, ex); + LOG.warn("Unable to load WEB-INF file {}", files[f], ex); } } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Ordering.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Ordering.java index 7bb40e2fb7a..0269799ac84 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Ordering.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Ordering.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Origin.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Origin.java index b2f90fc32c2..fbc2a811560 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Origin.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Origin.java @@ -1,24 +1,42 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; public enum Origin { - NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation, API -} + NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation, API; + + public static Origin of(Object o) + { + if (o == null) + return null; + if (o instanceof java.lang.annotation.Annotation) + return Annotation; + if (o instanceof FragmentDescriptor) + return WebFragment; + else if (o instanceof OverrideDescriptor) + return WebOverride; + else if (o instanceof DefaultsDescriptor) + return WebDefaults; + else if (o instanceof WebDescriptor) + return WebXml; + else + return API; + } +} \ No newline at end of file diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java index e2073e6eb3c..a8431a88e37 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/OverrideDescriptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/RelativeOrdering.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/RelativeOrdering.java index 79263bcb772..d06b976ce31 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/RelativeOrdering.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/RelativeOrdering.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -52,7 +52,7 @@ public class RelativeOrdering implements Ordering // Pass 1: split the jars into 'before others', 'others' or 'after others' for (Resource jar : jars) { - FragmentDescriptor fragment = _metaData.getFragment(jar); + FragmentDescriptor fragment = _metaData.getFragmentDescriptorForJar(jar); if (fragment == null) others.add(jar); @@ -79,7 +79,7 @@ public class RelativeOrdering implements Ordering Set referenced = new HashSet<>(); for (Resource jar : jars) { - FragmentDescriptor fragment = _metaData.getFragment(jar); + FragmentDescriptor fragment = _metaData.getFragmentDescriptorForJar(jar); if (fragment != null) { @@ -87,7 +87,7 @@ public class RelativeOrdering implements Ordering // and remember that the dependency has been referenced. for (String name : fragment.getAfters()) { - Resource after = _metaData.getJarForFragment(name); + Resource after = _metaData.getJarForFragmentName(name); sort.addDependency(jar, after); referenced.add(after); } @@ -96,7 +96,7 @@ public class RelativeOrdering implements Ordering // and remember that the dependency has been referenced. for (String name : fragment.getBefores()) { - Resource before = _metaData.getJarForFragment(name); + Resource before = _metaData.getJarForFragmentName(name); sort.addDependency(before, jar); referenced.add(before); } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ServletsConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ServletsConfiguration.java index 8c3c52fdac7..9d76ea4c7c3 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ServletsConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ServletsConfiguration.java @@ -1,26 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

      Jetty Servlets Configuration

      @@ -30,7 +30,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class ServletsConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(ServletsConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(ServletsConfiguration.class); public ServletsConfiguration() { @@ -52,7 +52,7 @@ public class ServletsConfiguration extends AbstractConfiguration } catch (Throwable e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return false; } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java index 89a9fc04122..44e4e411463 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -21,7 +21,6 @@ package org.eclipse.jetty.webapp; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; -import java.util.EventListener; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -30,6 +29,7 @@ import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import javax.servlet.DispatcherType; import javax.servlet.MultipartConfigElement; import javax.servlet.SessionTrackingMode; @@ -50,11 +50,11 @@ import org.eclipse.jetty.servlet.ServletMapping; import org.eclipse.jetty.servlet.Source; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.xml.XmlParser; import org.eclipse.jetty.xml.XmlParser.Node; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * StandardDescriptorProcessor. @@ -63,7 +63,7 @@ import org.eclipse.jetty.xml.XmlParser.Node; */ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { - private static final Logger LOG = Log.getLogger(StandardDescriptorProcessor.class); + private static final Logger LOG = LoggerFactory.getLogger(StandardDescriptorProcessor.class); public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor"; @@ -95,11 +95,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor registerVisitor("filter", this.getClass().getMethod("visitFilter", __signature)); registerVisitor("filter-mapping", this.getClass().getMethod("visitFilterMapping", __signature)); registerVisitor("listener", this.getClass().getMethod("visitListener", __signature)); - registerVisitor("distributable", this.getClass().getMethod("visitDistributable", __signature)); registerVisitor("deny-uncovered-http-methods", this.getClass().getMethod("visitDenyUncoveredHttpMethods", __signature)); registerVisitor("default-context-path", this.getClass().getMethod("visitDefaultContextPath", __signature)); - registerVisitor("request-encoding", this.getClass().getMethod("visitRequestEncoding", __signature)); - registerVisitor("response-encoding", this.getClass().getMethod("visitResponseEncoding", __signature)); + registerVisitor("request-character-encoding", this.getClass().getMethod("visitRequestCharacterEncoding", __signature)); + registerVisitor("response-character-encoding", this.getClass().getMethod("visitResponseCharacterEncoding", __signature)); } catch (Exception e) { @@ -153,7 +152,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { String name = node.getString("param-name", false, true); String value = node.getString("param-value", false, true); - switch (context.getMetaData().getOrigin("context-param." + name)) + Origin origin = context.getMetaData().getOrigin("context-param." + name); + switch (origin) { case NotSet: { @@ -185,7 +185,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } if (LOG.isDebugEnabled()) LOG.debug("ContextParam: " + name + "=" + value); @@ -226,7 +226,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String originName = name + ".servlet.init-param." + pname; Descriptor originDescriptor = context.getMetaData().getOriginDescriptor(originName); - switch (context.getMetaData().getOrigin(originName)) + Origin origin = context.getMetaData().getOrigin(originName); + switch (origin) { case NotSet: { @@ -257,7 +258,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -283,7 +284,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (servletClass != null) { ((WebDescriptor)descriptor).addClassName(servletClass); - switch (context.getMetaData().getOrigin(name + ".servlet.servlet-class")) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.servlet-class"); + switch (origin) { case NotSet: { @@ -312,7 +314,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -342,11 +344,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor catch (Exception e) { LOG.warn("Cannot parse load-on-startup " + s + ". Please use integer"); - LOG.ignore(e); + LOG.trace("IGNORED", e); } } - switch (context.getMetaData().getOrigin(name + ".servlet.load-on-startup")) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.load-on-startup"); + switch (origin) { case NotSet: { @@ -375,7 +378,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -389,7 +392,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this); - switch (context.getMetaData().getOrigin(name + ".servlet.role-name." + roleName)) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.role-name." + roleName); + switch (origin) { case NotSet: { @@ -417,7 +421,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } else @@ -433,7 +437,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (roleName != null) { - switch (context.getMetaData().getOrigin(name + ".servlet.run-as")) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.run-as"); + switch (origin) { case NotSet: { @@ -462,7 +467,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } } @@ -471,7 +476,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (async != null) { boolean val = async.length() == 0 || Boolean.parseBoolean(async); - switch (context.getMetaData().getOrigin(name + ".servlet.async-supported")) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.async-supported"); + switch (origin) { case NotSet: { @@ -500,7 +506,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -508,7 +514,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (enabled != null) { boolean isEnabled = enabled.length() == 0 || Boolean.parseBoolean(enabled); - switch (context.getMetaData().getOrigin(name + ".servlet.enabled")) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.enabled"); + switch (origin) { case NotSet: { @@ -537,7 +544,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -558,7 +565,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor (maxRequest == null || "".equals(maxRequest) ? -1L : Long.parseLong(maxRequest)), (threshold == null || "".equals(threshold) ? 0 : Integer.parseInt(threshold))); - switch (context.getMetaData().getOrigin(name + ".servlet.multipart-config")) + Origin origin = context.getMetaData().getOrigin(name + ".servlet.multipart-config"); + switch (origin) { case NotSet: { @@ -596,7 +604,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } } @@ -610,7 +618,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor // declared in web.xml overrides the mapping for the servlet specified in the web-fragment.xml String servletName = node.getString("servlet-name", false, true); - switch (context.getMetaData().getOrigin(servletName + ".servlet.mappings")) + Origin origin = context.getMetaData().getOrigin(servletName + ".servlet.mappings"); + switch (origin) { case NotSet: { @@ -638,7 +647,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -650,11 +659,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor XmlParser.Node tNode = node.get("session-timeout"); if (tNode != null) { - java.math.BigDecimal asDecimal = new java.math.BigDecimal(tNode.toString(false, true)); - if (asDecimal.compareTo(org.eclipse.jetty.server.session.SessionHandler.MAX_INACTIVE_MINUTES) > 0) - throw new IllegalStateException("Max session-timeout in minutes is " + org.eclipse.jetty.server.session.SessionHandler.MAX_INACTIVE_MINUTES); - - context.getSessionHandler().setMaxInactiveInterval(asDecimal.intValueExact() * 60); + long mins = Long.parseLong(tNode.toString(false, true)); + if (TimeUnit.MINUTES.toSeconds(mins) > Integer.MAX_VALUE) + throw new IllegalStateException("Max session-timeout in minutes is " + TimeUnit.SECONDS.toMinutes(Integer.MAX_VALUE)); + context.getServletContext().setSessionTimeout((int)mins); } //Servlet Spec 3.0 @@ -688,7 +696,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(o); } while (iter.hasNext()) @@ -709,7 +717,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String name = cookieConfig.getString("name", false, true); if (name != null) { - switch (context.getMetaData().getOrigin("cookie-config.name")) + Origin origin = context.getMetaData().getOrigin("cookie-config.name"); + switch (origin) { case NotSet: { @@ -738,7 +747,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -746,7 +755,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String domain = cookieConfig.getString("domain", false, true); if (domain != null) { - switch (context.getMetaData().getOrigin("cookie-config.domain")) + Origin origin = context.getMetaData().getOrigin("cookie-config.domain"); + switch (origin) { case NotSet: { @@ -775,7 +785,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -783,7 +793,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String path = cookieConfig.getString("path", false, true); if (path != null) { - switch (context.getMetaData().getOrigin("cookie-config.path")) + Origin origin = context.getMetaData().getOrigin("cookie-config.path"); + switch (origin) { case NotSet: { @@ -812,7 +823,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -820,7 +831,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String comment = cookieConfig.getString("comment", false, true); if (comment != null) { - switch (context.getMetaData().getOrigin("cookie-config.comment")) + Origin origin = context.getMetaData().getOrigin("cookie-config.comment"); + switch (origin) { case NotSet: { @@ -849,7 +861,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -858,7 +870,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (tNode != null) { boolean httpOnly = Boolean.parseBoolean(tNode.toString(false, true)); - switch (context.getMetaData().getOrigin("cookie-config.http-only")) + Origin origin = context.getMetaData().getOrigin("cookie-config.http-only"); + switch (origin) { case NotSet: { @@ -887,7 +900,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -896,7 +909,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (tNode != null) { boolean secure = Boolean.parseBoolean(tNode.toString(false, true)); - switch (context.getMetaData().getOrigin("cookie-config.secure")) + Origin origin = context.getMetaData().getOrigin("cookie-config.secure"); + switch (origin) { case NotSet: { @@ -925,7 +939,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -934,7 +948,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (tNode != null) { int maxAge = Integer.parseInt(tNode.toString(false, true)); - switch (context.getMetaData().getOrigin("cookie-config.max-age")) + Origin origin = context.getMetaData().getOrigin("cookie-config.max-age"); + switch (origin) { case NotSet: { @@ -963,7 +978,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } } @@ -977,7 +992,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String mimeType = node.getString("mime-type", false, true); if (extension != null) { - switch (context.getMetaData().getOrigin("extension." + extension)) + Origin origin = context.getMetaData().getOrigin("extension." + extension); + switch (origin) { case NotSet: { @@ -1006,14 +1022,15 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } } public void visitWelcomeFileList(WebAppContext context, Descriptor descriptor, XmlParser.Node node) { - switch (context.getMetaData().getOrigin("welcome-file-list")) + Origin origin = context.getMetaData().getOrigin("welcome-file-list"); + switch (origin) { case NotSet: { @@ -1051,7 +1068,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -1066,7 +1083,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (encoding != null) { - switch (context.getMetaData().getOrigin("locale-encoding." + locale)) + Origin origin = context.getMetaData().getOrigin("locale-encoding." + locale); + switch (origin) { case NotSet: { @@ -1095,7 +1113,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } } @@ -1119,7 +1137,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Missing leading '/' for location: " + location); ErrorPageErrorHandler handler = (ErrorPageErrorHandler)context.getErrorHandler(); String originName = "error." + error; - switch (context.getMetaData().getOrigin(originName)) + Origin origin = context.getMetaData().getOrigin(originName); + switch (origin) { case NotSet: { @@ -1159,7 +1178,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -1539,7 +1558,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor } catch (CloneNotSupportedException e) { - LOG.warn(e); + LOG.warn("Unable to clone {}", scBase, e); } } @@ -1552,7 +1571,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (method != null) { //handle auth-method merge - switch (context.getMetaData().getOrigin("auth-method")) + Origin origin = context.getMetaData().getOrigin("auth-method"); + switch (origin) { case NotSet: { @@ -1581,13 +1601,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } //handle realm-name merge XmlParser.Node name = node.get("realm-name"); String nameStr = (name == null ? "default" : name.toString(false, true)); - switch (context.getMetaData().getOrigin("realm-name")) + Origin originRealmName = context.getMetaData().getOrigin("realm-name"); + switch (originRealmName) { case NotSet: { @@ -1616,7 +1637,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(originRealmName); } if (Constraint.__FORM_AUTH.equalsIgnoreCase(context.getSecurityHandler().getAuthMethod())) @@ -1634,7 +1655,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor errorPageName = errorPage.toString(false, true); //handle form-login-page - switch (context.getMetaData().getOrigin("form-login-page")) + Origin originFormLoginPage = context.getMetaData().getOrigin("form-login-page"); + switch (originFormLoginPage) { case NotSet: { @@ -1663,11 +1685,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(originFormLoginPage); } //handle form-error-page - switch (context.getMetaData().getOrigin("form-error-page")) + Origin originFormErrorPage = context.getMetaData().getOrigin("form-error-page"); + switch (originFormErrorPage) { case NotSet: { @@ -1696,7 +1719,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(originFormErrorPage); } } else @@ -1737,7 +1760,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { ((WebDescriptor)descriptor).addClassName(filterClass); - switch (context.getMetaData().getOrigin(name + ".filter.filter-class")) + Origin origin = context.getMetaData().getOrigin(name + ".filter.filter-class"); + switch (origin) { case NotSet: { @@ -1766,7 +1790,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -1777,7 +1801,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor String pname = paramNode.getString("param-name", false, true); String pvalue = paramNode.getString("param-value", false, true); - switch (context.getMetaData().getOrigin(name + ".filter.init-param." + pname)) + Origin origin = context.getMetaData().getOrigin(name + ".filter.init-param." + pname); + switch (origin) { case NotSet: { @@ -1807,7 +1832,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } @@ -1817,7 +1842,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (async != null) { boolean val = async.length() == 0 || Boolean.parseBoolean(async); - switch (context.getMetaData().getOrigin(name + ".filter.async-supported")) + Origin origin = context.getMetaData().getOrigin(name + ".filter.async-supported"); + switch (origin) { case NotSet: { @@ -1846,7 +1872,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } } @@ -1858,7 +1884,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor //Maintenance update 3.0a to spec: // Updated 8.2.3.g.v to say elements are additive across web-fragments. String filterName = node.getString("filter-name", false, true); - switch (context.getMetaData().getOrigin(filterName + ".filter.mappings")) + Origin origin = context.getMetaData().getOrigin(filterName + ".filter.mappings"); + switch (origin) { case NotSet: { @@ -1885,14 +1912,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor break; } default: - LOG.warn(new Throwable()); // TODO throw ISE? + unknownOrigin(origin); } } public void visitListener(WebAppContext context, Descriptor descriptor, XmlParser.Node node) { String className = node.getString("listener-class", false, true); - EventListener listener = null; try { if (className != null && className.length() > 0) @@ -1920,14 +1946,6 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor } } - public void visitDistributable(WebAppContext context, Descriptor descriptor, XmlParser.Node node) - { - // the element has no content, so its simple presence - // indicates that the webapp is distributable... - //Servlet Spec 3.0 p.74 distributable only if all fragments are distributable - ((WebDescriptor)descriptor).setDistributable(true); - } - /** * Servlet spec 3.1. When present in web.xml, this means that http methods that are * not covered by security constraints should have access denied. @@ -1983,11 +2001,17 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor * @param node the xml node * @since Servlet 4.0 */ - public void visitRequestEncoding(WebAppContext context, Descriptor descriptor, XmlParser.Node node) + public void visitRequestCharacterEncoding(WebAppContext context, Descriptor descriptor, XmlParser.Node node) { - // TODO - LOG.warn("Not implemented {}", node); - // TODO + //As per spec, this element can only appear in web.xml, never in a fragment. Jetty will + //allow it to be specified in webdefault.xml, web.xml, and web-override.xml. + if (!(descriptor instanceof FragmentDescriptor)) + { + String encoding = node.toString(false, true); + context.setAttribute("request-character-encoding", encoding); + context.setDefaultRequestCharacterEncoding(encoding); + context.getMetaData().setOrigin("request-character-encoding", descriptor); + } } /** @@ -1999,9 +2023,21 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor * @param node the xml node * @since Servlet 4.0 */ - public void visitResponseEncoding(WebAppContext context, Descriptor descriptor, XmlParser.Node node) + public void visitResponseCharacterEncoding(WebAppContext context, Descriptor descriptor, XmlParser.Node node) { - // TODO - LOG.warn("Not implemented {}", node); + //As per spec, this element can only appear in web.xml, never in a fragment. Jetty will + //allow it to be specified in webdefault.xml, web.xml, and web-override.xml. + if (!(descriptor instanceof FragmentDescriptor)) + { + String encoding = node.toString(false, true); + context.setAttribute("response-character-encoding", encoding); + context.setDefaultResponseCharacterEncoding(encoding); + context.getMetaData().setOrigin("response-character-encoding", descriptor); + } + } + + private void unknownOrigin(Origin origin) + { + LOG.warn("Unknown descriptor origin {}", origin, new Throwable()); // TODO throw ISE? } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java index af7bfc29f14..82806a3eb7e 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -43,10 +43,10 @@ import org.eclipse.jetty.util.ClassVisibilityChecker; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ClassLoader for HttpContext. @@ -73,7 +73,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility registerAsParallelCapable(); } - private static final Logger LOG = Log.getLogger(WebAppClassLoader.class); + private static final Logger LOG = LoggerFactory.getLogger(WebAppClassLoader.class); private static final ThreadLocal __loadServerClasses = new ThreadLocal<>(); private final Context _context; @@ -342,7 +342,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility } catch (Exception ex) { - LOG.warn(Log.EXCEPTION, ex); + LOG.warn("Unable to load WEB-INF/lib JAR {}", files[f], ex); } } } @@ -585,6 +585,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility * @param name the name of the class to load * @param checkSystemResource if true and the class isn't a system class we return it * @return the loaded class + * @throws ClassNotFoundException if the class cannot be found */ protected Class loadAsResource(final String name, boolean checkSystemResource) throws ClassNotFoundException { diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppConfiguration.java index f4dd9927976..1aadd5f6cdc 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 0b53e1de0b4..5b55d08712f 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -67,10 +67,10 @@ import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Web Application Context Handler. @@ -95,7 +95,7 @@ import org.eclipse.jetty.util.resource.ResourceCollection; *
        *
      • Add all Server class inclusions from all known configurations {@link Configurations#getKnown()}
      • *
      • {@link #loadConfigurations()}, which uses either explicitly set Configurations or takes the server - * default (which is all known non {@link Configuration#isDisabledByDefault()} Configurations.
      • + * default (which is all known {@link Configuration#isEnabledByDefault()} Configurations. *
      • Sort the configurations using {@link TopologicalSort} in {@link Configurations#sort()}.
      • *
      • Add all Server class exclusions from this webapps {@link Configurations}
      • *
      • Add all System classes inclusions and exclusions for this webapps {@link Configurations}
      • @@ -154,7 +154,7 @@ import org.eclipse.jetty.util.resource.ResourceCollection; @ManagedObject("Web Application ContextHandler") public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context { - static final Logger LOG = Log.getLogger(WebAppContext.class); + static final Logger LOG = LoggerFactory.getLogger(WebAppContext.class); public static final String TEMPDIR = "javax.servlet.context.tempdir"; public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir"; @@ -183,10 +183,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL "org.eclipse.jetty." // hide jetty classes ); - private final Configurations _configurations = new Configurations(); private final ClassMatcher _systemClasses = new ClassMatcher(__dftSystemClasses); private final ClassMatcher _serverClasses = new ClassMatcher(__dftServerClasses); + private Configurations _configurations; private String _defaultsDescriptor = WEB_DEFAULTS_XML; private String _descriptor = null; private final List _overrideDescriptors = new ArrayList<>(); @@ -318,7 +318,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL { super.setDisplayName(servletContextName); ClassLoader cl = getClassLoader(); - if (cl != null && cl instanceof WebAppClassLoader && servletContextName != null) + if (cl instanceof WebAppClassLoader && servletContextName != null) ((WebAppClassLoader)cl).setName(servletContextName); } @@ -344,7 +344,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL public void setResourceAlias(String alias, String uri) { if (_resourceAliases == null) - _resourceAliases = new HashMap(5); + _resourceAliases = new HashMap<>(5); _resourceAliases.put(alias, uri); } @@ -386,9 +386,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL return _resourceAliases.remove(alias); } - /* (non-Javadoc) - * @see org.eclipse.jetty.server.server.handler.ContextHandler#setClassLoader(java.lang.ClassLoader) - */ @Override public void setClassLoader(ClassLoader classLoader) { @@ -398,7 +395,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL if (name == null) name = getContextPath(); - if (classLoader != null && classLoader instanceof WebAppClassLoader && getDisplayName() != null) + if (classLoader instanceof WebAppClassLoader && getDisplayName() != null) ((WebAppClassLoader)classLoader).setName(name); } @@ -423,13 +420,13 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); if (ioe == null) ioe = e; } } - if (ioe != null && ioe instanceof MalformedURLException) + if (ioe instanceof MalformedURLException) throw (MalformedURLException)ioe; return resource; @@ -527,9 +524,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL _configurations.postConfigure(this); } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() - */ @Override protected void doStart() throws Exception { @@ -537,7 +531,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL { _metadata.setAllowDuplicateFragmentNames(isAllowDuplicateFragmentNames()); Boolean validate = (Boolean)getAttribute(MetaData.VALIDATE_XML); - _metadata.setValidateXml((validate != null && validate.booleanValue())); + _metadata.setValidateXml((validate != null && validate)); preConfigure(); super.doStart(); postConfigure(); @@ -556,32 +550,26 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL } } - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - } - @Override public void destroy() { // Prepare for configuration MultiException mx = new MultiException(); - for (Configuration configuration : _configurations) + if (_configurations != null) { - try + for (Configuration configuration : _configurations) { - configuration.destroy(this); - } - catch (Exception e) - { - mx.add(e); + try + { + configuration.destroy(this); + } + catch (Exception e) + { + mx.add(e); + } } } - _configurations.clear(); + _configurations = null; super.destroy(); mx.ifExceptionThrowRuntime(); } @@ -615,10 +603,9 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL /** * @return Returns the configurations. */ - public Configurations getWebAppConfigurations() + public Configurations getConfigurations() { - if (_configurations.size() == 0) - loadConfigurations(); + loadConfigurations(); return _configurations; } @@ -885,10 +872,18 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL protected void loadConfigurations() { //if the configuration instances have been set explicitly, use them - if (!_configurations.isEmpty()) + if (_configurations != null) return; + if (isStarted()) + throw new IllegalStateException(); + _configurations = newConfigurations(); + } - _configurations.add(Configurations.getServerDefault(getServer()).toArray()); + protected Configurations newConfigurations() + { + Configurations configurations = new Configurations(); + configurations.add(Configurations.getServerDefault(getServer()).toArray()); + return configurations; } @Override @@ -921,16 +916,18 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL { if (_war != null) { - if (_war.indexOf("/webapps/") >= 0) - name = _war.substring(_war.indexOf("/webapps/") + 8); + int webapps = _war.indexOf("/webapps/"); + if (webapps >= 0) + name = _war.substring(webapps + 8); else name = _war; } else if (getResourceBase() != null) { name = getResourceBase(); - if (name.indexOf("/webapps/") >= 0) - name = name.substring(name.indexOf("/webapps/") + 8); + int webapps = name.indexOf("/webapps/"); + if (webapps >= 0) + name = name.substring(webapps + 8); } else { @@ -946,7 +943,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL new DumpableCollection("Serverclasses " + name, serverClasses), new DumpableCollection("Configurations " + name, _configurations), new DumpableCollection("Handler attributes " + name, ((AttributesMap)getAttributes()).getAttributeEntrySet()), - new DumpableCollection("Context attributes " + name, ((Context)getServletContext()).getAttributeEntrySet()), + new DumpableCollection("Context attributes " + name, getServletContext().getAttributeEntrySet()), + new DumpableCollection("EventListeners " + this, getEventListeners()), new DumpableCollection("Initparams " + name, getInitParams().entrySet()) ); } @@ -957,14 +955,14 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL */ public void setConfigurationClasses(String[] configurations) { - if (isStarted()) - throw new IllegalStateException(); + if (_configurations == null) + _configurations = new Configurations(); _configurations.set(configurations); } public void setConfigurationClasses(List configurations) { - setConfigurationClasses(configurations.toArray(new String[configurations.size()])); + setConfigurationClasses(configurations.toArray(new String[0])); } /** @@ -972,15 +970,13 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL */ public void setConfigurations(Configuration[] configurations) { - if (isStarted()) - throw new IllegalStateException(); + if (_configurations == null) + _configurations = new Configurations(); _configurations.set(configurations); } public void addConfiguration(Configuration... configuration) { - if (isStarted()) - throw new IllegalStateException(); loadConfigurations(); _configurations.add(configuration); } @@ -988,12 +984,19 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL public T getConfiguration(Class configClass) { loadConfigurations(); - for (Configuration configuration : _configurations) - { - if (configClass.isAssignableFrom(configuration.getClass())) - return (T)configuration; - } - return null; + return _configurations.get(configClass); + } + + public void removeConfiguration(Configuration... configurations) + { + if (_configurations != null) + _configurations.remove(configurations); + } + + public void removeConfiguration(Class... configurations) + { + if (_configurations != null) + _configurations.remove(configurations); } /** @@ -1064,27 +1067,22 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL } @Override - public void setEventListeners(EventListener[] eventListeners) + public boolean removeEventListener(EventListener listener) { - if (_sessionHandler != null) - _sessionHandler.clearEventListeners(); - - super.setEventListeners(eventListeners); - } - - @Override - public void removeEventListener(EventListener listener) - { - super.removeEventListener(listener); - if ((listener instanceof HttpSessionActivationListener) || - (listener instanceof HttpSessionAttributeListener) || - (listener instanceof HttpSessionBindingListener) || - (listener instanceof HttpSessionListener) || - (listener instanceof HttpSessionIdListener)) + if (super.removeEventListener(listener)) { - if (_sessionHandler != null) - _sessionHandler.removeEventListener(listener); + if ((listener instanceof HttpSessionActivationListener) || + (listener instanceof HttpSessionAttributeListener) || + (listener instanceof HttpSessionBindingListener) || + (listener instanceof HttpSessionListener) || + (listener instanceof HttpSessionIdListener)) + { + if (_sessionHandler != null) + _sessionHandler.removeEventListener(listener); + } + return true; } + return false; } /** @@ -1165,7 +1163,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL } catch (IOException e) { - LOG.warn(Log.EXCEPTION, e); + LOG.warn("Unable to find canonical path for {}", dir, e); } } @@ -1311,7 +1309,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL if (_ownClassLoader) { ClassLoader loader = getClassLoader(); - if (loader != null && loader instanceof URLClassLoader) + if (loader instanceof URLClassLoader) ((URLClassLoader)loader).close(); setClassLoader(null); } @@ -1324,7 +1322,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL @Override public Set setServletSecurity(Dynamic registration, ServletSecurityElement servletSecurityElement) { - Set unchangedURLMappings = new HashSet(); + Set unchangedURLMappings = new HashSet<>(); //From javadoc for ServletSecurityElement: /* If a URL pattern of this ServletRegistration is an exact target of a security-constraint that @@ -1398,7 +1396,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL public class Context extends ServletContextHandler.Context { - @Override public void checkListener(Class listener) throws IllegalStateException { diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java index a1d2ccc5dd1..e0e911c48e7 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -24,10 +24,10 @@ import java.util.Iterator; import java.util.List; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xml.sax.InputSource; /** @@ -37,34 +37,51 @@ import org.xml.sax.InputSource; */ public class WebDescriptor extends Descriptor { - private static final Logger LOG = Log.getLogger(WebDescriptor.class); + private static final Logger LOG = LoggerFactory.getLogger(WebDescriptor.class); - protected static XmlParser _nonValidatingStaticParser; - protected MetaDataComplete _metaDataComplete; - protected int _majorVersion = 3; //default to container version + public static XmlParser __nonValidatingStaticParser = newParser(false); + protected MetaData.Complete _metaDataComplete; + protected int _majorVersion = 4; //default to container version protected int _minorVersion = 0; - protected ArrayList _classNames = new ArrayList(); + protected ArrayList _classNames = new ArrayList<>(); protected boolean _distributable; - protected boolean _isOrdered = false; - protected List _ordering = new ArrayList(); + protected List _ordering = new ArrayList<>(); - @Override - public XmlParser ensureParser() throws ClassNotFoundException + /** + * Check if the descriptor is metadata-complete. + * + * @param d the descriptor (web.xml, web-fragment.xml, + * web-default.xml, web-override.xml) to check + * @return true iff metadata-complete=true is declared in the + * descriptor + */ + public static boolean isMetaDataComplete(WebDescriptor d) { - synchronized (WebDescriptor.class) - { - if (_nonValidatingStaticParser == null) - _nonValidatingStaticParser = newParser(false); - } + return (d != null && d.getMetaDataComplete() == MetaData.Complete.True); + } - if (!isValidating()) - return _nonValidatingStaticParser; + /** + * Get a parser for parsing web descriptor content. + * + * @param validating true if the parser should validate syntax, false otherwise + * @return an XmlParser for web descriptors + */ + public static XmlParser getParser(boolean validating) + { + if (!validating) + return __nonValidatingStaticParser; else return newParser(true); } - public static XmlParser newParser(boolean validating) throws ClassNotFoundException + /** + * Create a new parser for parsing web descriptors. + * + * @param validating if true, the parser will validate syntax + * @return an XmlParser + */ + public static XmlParser newParser(boolean validating) { XmlParser xmlParser = new XmlParser(validating) { @@ -130,7 +147,7 @@ public class WebDescriptor extends Descriptor } catch (Exception e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } finally { @@ -218,15 +235,16 @@ public class WebDescriptor extends Descriptor } @Override - public void parse() + public void parse(XmlParser parser) throws Exception { - super.parse(); + super.parse(parser); processVersion(); processOrdering(); + processDistributable(); } - public MetaDataComplete getMetaDataComplete() + public MetaData.Complete getMetaDataComplete() { return _metaDataComplete; } @@ -266,14 +284,14 @@ public class WebDescriptor extends Descriptor } if (_majorVersion <= 2 && _minorVersion < 5) - _metaDataComplete = MetaDataComplete.True; // does not apply before 2.5 + _metaDataComplete = MetaData.Complete.True; // does not apply before 2.5 else { String s = (String)_root.getAttribute("metadata-complete"); if (s == null) - _metaDataComplete = MetaDataComplete.NotSet; + _metaDataComplete = MetaData.Complete.NotSet; else - _metaDataComplete = Boolean.valueOf(s).booleanValue() ? MetaDataComplete.True : MetaDataComplete.False; + _metaDataComplete = Boolean.valueOf(s).booleanValue() ? MetaData.Complete.True : MetaData.Complete.False; } if (LOG.isDebugEnabled()) @@ -309,6 +327,14 @@ public class WebDescriptor extends Descriptor } } + public void processDistributable() + { + XmlParser.Node distributable = _root.get("distributable"); + if (distributable == null) + return; //no element + _distributable = true; + } + public void addClassName(String className) { if (!_classNames.contains(className)) @@ -320,27 +346,11 @@ public class WebDescriptor extends Descriptor return _classNames; } - public void setDistributable(boolean distributable) - { - _distributable = distributable; - } - public boolean isDistributable() { return _distributable; } - @Override - public void setValidating(boolean validating) - { - _validating = validating; - } - - public boolean isValidating() - { - return _validating; - } - public boolean isOrdered() { return _isOrdered; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index a25f4e399bf..04caf29857b 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -1,43 +1,47 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; import java.io.File; import java.io.IOException; +import java.net.URI; import java.util.Locale; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.JarFileResource; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WebInfConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(WebInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(WebInfConfiguration.class); public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured"; + public static final String TEMPORARY_RESOURCE_BASE = "org.eclipse.jetty.webapp.tmpResourceBase"; protected Resource _preUnpackBaseResource; @@ -95,9 +99,6 @@ public class WebInfConfiguration extends AbstractConfiguration context.setBaseResource(_preUnpackBaseResource); } - /** - * @see org.eclipse.jetty.webapp.AbstractConfiguration#cloneConfigure(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.WebAppContext) - */ @Override public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception { @@ -338,8 +339,11 @@ public class WebInfConfiguration extends AbstractConfiguration } if (extractedWebAppDir == null) + { // Then extract it if necessary to the temporary location extractedWebAppDir = new File(context.getTempDirectory(), "webapp"); + context.setAttribute(TEMPORARY_RESOURCE_BASE, extractedWebAppDir); + } if (webApp.getFile() != null && webApp.getFile().isDirectory()) { @@ -493,7 +497,7 @@ public class WebInfConfiguration extends AbstractConfiguration } } - //Resource base + // Resource base try { Resource resource = context.getBaseResource(); @@ -502,27 +506,21 @@ public class WebInfConfiguration extends AbstractConfiguration if (context.getWar() == null || context.getWar().length() == 0) throw new IllegalStateException("No resourceBase or war set for context"); - // Set dir or WAR + // Set dir or WAR to resource resource = context.newResource(context.getWar()); } - if (resource.getURI().getPath() != null) - { - String tmp = URIUtil.decodePath(resource.getURI().getPath()); - if (tmp.endsWith("/")) - tmp = tmp.substring(0, tmp.length() - 1); - if (tmp.endsWith("!")) - tmp = tmp.substring(0, tmp.length() - 1); - //get just the last part which is the filename - int i = tmp.lastIndexOf("/"); - canonicalName.append(tmp.substring(i + 1, tmp.length())); - } + String resourceBaseName = getResourceBaseName(resource); + canonicalName.append(resourceBaseName); canonicalName.append("-"); } catch (Exception e) { - LOG.warn("Can't generate resourceBase as part of webapp tmp dir name " + e); - LOG.debug(e); + if (LOG.isDebugEnabled()) + { + LOG.debug("Can't get resource base name", e); + } + canonicalName.append("-"); // empty resourceBaseName segment } //Context name @@ -549,6 +547,44 @@ public class WebInfConfiguration extends AbstractConfiguration canonicalName.append("-"); - return canonicalName.toString(); + return StringUtil.sanitizeFileSystemName(canonicalName.toString()); + } + + protected static String getResourceBaseName(Resource resource) + { + // Use File System and File interface if present + try + { + File resourceFile = resource.getFile(); + if ((resourceFile != null) && (resource instanceof JarFileResource)) + { + resourceFile = ((JarFileResource)resource).getJarFile(); + } + + if (resourceFile != null) + { + return resourceFile.getName(); + } + } + catch (IOException e) + { + if (LOG.isDebugEnabled()) + { + LOG.debug("Resource has no File reference: {}", resource); + } + } + + // Use URI itself. + URI uri = resource.getURI(); + if (uri == null) + { + if (LOG.isDebugEnabled()) + { + LOG.debug("Resource has no URI reference: {}", resource); + } + return ""; + } + + return URIUtil.getUriLastPathSegment(uri); } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java index d57e9c683d5..0d587e6305d 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -22,16 +22,16 @@ import java.io.IOException; import java.net.MalformedURLException; import org.eclipse.jetty.servlet.ErrorPageErrorHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Configure by parsing default web.xml and web.xml */ public class WebXmlConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(WebXmlConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(WebXmlConfiguration.class); public WebXmlConfiguration() { @@ -57,16 +57,16 @@ public class WebXmlConfiguration extends AbstractConfiguration if (dftResource == null) dftResource = context.newResource(defaultsDescriptor); } - context.getMetaData().setDefaults(dftResource); + context.getMetaData().setDefaultsDescriptor(new DefaultsDescriptor(dftResource)); } //parse, but don't process web.xml Resource webxml = findWebXml(context); if (webxml != null) { - context.getMetaData().setWebXml(webxml); - context.getServletContext().setEffectiveMajorVersion(context.getMetaData().getWebXml().getMajorVersion()); - context.getServletContext().setEffectiveMinorVersion(context.getMetaData().getWebXml().getMinorVersion()); + context.getMetaData().setWebDescriptor(new WebDescriptor(webxml)); + context.getServletContext().setEffectiveMajorVersion(context.getMetaData().getWebDescriptor().getMajorVersion()); + context.getServletContext().setEffectiveMinorVersion(context.getMetaData().getWebDescriptor().getMinorVersion()); } //parse but don't process override-web.xml @@ -77,7 +77,7 @@ public class WebXmlConfiguration extends AbstractConfiguration Resource orideResource = Resource.newSystemResource(overrideDescriptor); if (orideResource == null) orideResource = context.newResource(overrideDescriptor); - context.getMetaData().addOverride(orideResource); + context.getMetaData().addOverrideDescriptor(new OverrideDescriptor(orideResource)); } } } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/package-info.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/package-info.java index 65968d02fa2..3ef3359b9f3 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/package-info.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-webapp/src/test/java/org/acme/webapp/ClassInJarA.java b/jetty-webapp/src/test/java/org/acme/webapp/ClassInJarA.java index bf8e54badb2..480cf58fbd4 100644 --- a/jetty-webapp/src/test/java/org/acme/webapp/ClassInJarA.java +++ b/jetty-webapp/src/test/java/org/acme/webapp/ClassInJarA.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.acme.webapp; diff --git a/jetty-webapp/src/test/java/org/acme/webapp/TestAnnotation.java b/jetty-webapp/src/test/java/org/acme/webapp/TestAnnotation.java new file mode 100644 index 00000000000..9b5d0c23e7d --- /dev/null +++ b/jetty-webapp/src/test/java/org/acme/webapp/TestAnnotation.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.acme.webapp; + +import java.util.List; + +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.webapp.DiscoveredAnnotation; +import org.eclipse.jetty.webapp.WebAppContext; + +public class TestAnnotation extends DiscoveredAnnotation +{ + private List applications; + + public TestAnnotation(WebAppContext context, String className, Resource resource, List applications) + { + super(context, className, resource); + this.applications = applications; + } + + @Override + public void apply() + { + if (applications != null) + applications.add(this); + } + + @Override + public String toString() + { + return getClassName(); + } +} diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClassMatcherTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClassMatcherTest.java index 3c5d889ed24..535911a141d 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClassMatcherTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ClassMatcherTest.java @@ -1,27 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; import java.net.URI; import java.util.Arrays; +import java.util.function.Supplier; +import org.eclipse.jetty.util.IncludeExcludeSet; import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.webapp.ClassMatcher.ByLocationOrModule; +import org.eclipse.jetty.webapp.ClassMatcher.ByPackageOrName; +import org.eclipse.jetty.webapp.ClassMatcher.Entry; import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -36,7 +41,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class ClassMatcherTest { private final ClassMatcher _pattern = new ClassMatcher(); - + + protected static Supplier NULL_SUPPLIER = new Supplier() + { + public URI get() + { + return null; + } + }; + @BeforeEach public void before() { @@ -120,13 +133,13 @@ public class ClassMatcherTest public void testIncludedLocations() throws Exception { // jar from JVM classloader - URI loc_string = TypeUtil.getLocationOfClass(String.class); + URI locString = TypeUtil.getLocationOfClass(String.class); // a jar from maven repo jar - URI loc_junit = TypeUtil.getLocationOfClass(Test.class); + URI locJunit = TypeUtil.getLocationOfClass(Test.class); // class file - URI loc_test = TypeUtil.getLocationOfClass(ClassMatcherTest.class); + URI locTest = TypeUtil.getLocationOfClass(ClassMatcherTest.class); ClassMatcher pattern = new ClassMatcher(); pattern.include("something"); @@ -135,10 +148,10 @@ public class ClassMatcherTest assertThat(pattern.match(ClassMatcherTest.class), Matchers.is(false)); // Add directory for both JVM classes - pattern.include(loc_string.toASCIIString()); + pattern.include(locString.toASCIIString()); // Add jar for individual class and classes directory - pattern.include(loc_junit.toString(), loc_test.toString()); + pattern.include(locJunit.toString(), locTest.toString()); assertThat(pattern.match(String.class), Matchers.is(true)); assertThat(pattern.match(Test.class), Matchers.is(true)); @@ -156,16 +169,16 @@ public class ClassMatcherTest public void testIncludedLocationsOrModule() throws Exception { // jar from JVM classloader - URI mod_string = TypeUtil.getLocationOfClass(String.class); - // System.err.println(mod_string); + URI modString = TypeUtil.getLocationOfClass(String.class); + // System.err.println(modString); // a jar from maven repo jar - URI loc_junit = TypeUtil.getLocationOfClass(Test.class); - // System.err.println(loc_junit); + URI locJunit = TypeUtil.getLocationOfClass(Test.class); + // System.err.println(locJunit); // class file - URI loc_test = TypeUtil.getLocationOfClass(ClassMatcherTest.class); - // System.err.println(loc_test); + URI locTest = TypeUtil.getLocationOfClass(ClassMatcherTest.class); + // System.err.println(locTest); ClassMatcher pattern = new ClassMatcher(); pattern.include("something"); @@ -177,7 +190,7 @@ public class ClassMatcherTest pattern.include("jrt:/java.base"); // Add jar for individual class and classes directory - pattern.include(loc_junit.toString(), loc_test.toString()); + pattern.include(locJunit.toString(), locTest.toString()); assertThat(pattern.match(String.class), Matchers.is(true)); assertThat(pattern.match(Test.class), Matchers.is(true)); @@ -195,16 +208,16 @@ public class ClassMatcherTest public void testExcludeLocations() throws Exception { // jar from JVM classloader - URI loc_string = TypeUtil.getLocationOfClass(String.class); - // System.err.println(loc_string); + URI locString = TypeUtil.getLocationOfClass(String.class); + // System.err.println(locString); // a jar from maven repo jar - URI loc_junit = TypeUtil.getLocationOfClass(Test.class); - // System.err.println(loc_junit); + URI locJunit = TypeUtil.getLocationOfClass(Test.class); + // System.err.println(locJunit); // class file - URI loc_test = TypeUtil.getLocationOfClass(ClassMatcherTest.class); - // System.err.println(loc_test); + URI locTest = TypeUtil.getLocationOfClass(ClassMatcherTest.class); + // System.err.println(locTest); ClassMatcher pattern = new ClassMatcher(); @@ -216,10 +229,10 @@ public class ClassMatcherTest assertThat(pattern.match(ClassMatcherTest.class), Matchers.is(true)); // Add directory for both JVM classes - pattern.exclude(loc_string.toString()); + pattern.exclude(locString.toString()); // Add jar for individual class and classes directory - pattern.exclude(loc_junit.toString(), loc_test.toString()); + pattern.exclude(locJunit.toString(), locTest.toString()); assertThat(pattern.match(String.class), Matchers.is(false)); assertThat(pattern.match(Test.class), Matchers.is(false)); @@ -232,16 +245,16 @@ public class ClassMatcherTest public void testExcludeLocationsOrModule() throws Exception { // jar from JVM classloader - URI mod_string = TypeUtil.getLocationOfClass(String.class); - // System.err.println(mod_string); + URI modString = TypeUtil.getLocationOfClass(String.class); + // System.err.println(modString); // a jar from maven repo jar - URI loc_junit = TypeUtil.getLocationOfClass(Test.class); - // System.err.println(loc_junit); + URI locJunit = TypeUtil.getLocationOfClass(Test.class); + // System.err.println(locJunit); // class file - URI loc_test = TypeUtil.getLocationOfClass(ClassMatcherTest.class); - // System.err.println(loc_test); + URI locTest = TypeUtil.getLocationOfClass(ClassMatcherTest.class); + // System.err.println(locTest); ClassMatcher pattern = new ClassMatcher(); @@ -256,12 +269,50 @@ public class ClassMatcherTest pattern.exclude("jrt:/java.base/"); // Add jar for individual class and classes directory - pattern.exclude(loc_junit.toString(), loc_test.toString()); + pattern.exclude(locJunit.toString(), locTest.toString()); assertThat(pattern.match(String.class), Matchers.is(false)); assertThat(pattern.match(Test.class), Matchers.is(false)); assertThat(pattern.match(ClassMatcherTest.class), Matchers.is(false)); } + + @Test + public void testWithNullLocation() throws Exception + { + ClassMatcher matcher = new ClassMatcher(); + + IncludeExcludeSet names = new IncludeExcludeSet<>(ByPackageOrName.class); + IncludeExcludeSet locations = new IncludeExcludeSet<>(ByLocationOrModule.class); + + //Test no name or location includes or excludes - should match + assertThat(ClassMatcher.combine(names, "a.b.c", locations, NULL_SUPPLIER), Matchers.is(true)); + + names.include(matcher.newEntry("a.b.", true)); + names.exclude(matcher.newEntry("d.e.", false)); + + //Test explicit include by name no locations - should match + assertThat(ClassMatcher.combine(names, "a.b.c", locations, NULL_SUPPLIER), Matchers.is(true)); + + //Test explicit exclude by name no locations - should not match + assertThat(ClassMatcher.combine(names, "d.e.f", locations, NULL_SUPPLIER), Matchers.is(false)); + + //Test include by name with location includes - should match + locations.include(matcher.newEntry("file:/foo/bar", true)); + assertThat(ClassMatcher.combine(names, "a.b.c", locations, NULL_SUPPLIER), Matchers.is(true)); + + //Test include by name but with location exclusions - should not match + locations.clear(); + locations.exclude(matcher.newEntry("file:/high/low", false)); + assertThat(ClassMatcher.combine(names, "a.b.c", locations, NULL_SUPPLIER), Matchers.is(false)); + + //Test neither included or excluded by name, but with location exclusions - should not match + assertThat(ClassMatcher.combine(names, "g.b.r", locations, NULL_SUPPLIER), Matchers.is(false)); + + //Test neither included nor excluded by name, but with location inclusions - should not match + locations.clear(); + locations.include(matcher.newEntry("file:/foo/bar", true)); + assertThat(ClassMatcher.combine(names, "g.b.r", locations, NULL_SUPPLIER), Matchers.is(false)); + } @Test public void testLarge() diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ConfigurationsTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ConfigurationsTest.java index 386685a5a69..02c8632211e 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ConfigurationsTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/ConfigurationsTest.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static java.util.stream.Collectors.toList; @@ -36,6 +37,12 @@ public class ConfigurationsTest Configurations.cleanKnown(); } + @BeforeEach + public void setup() + { + Configurations.cleanKnown(); + } + @Test public void testSetKnown() { diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/HugeResourceTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/HugeResourceTest.java index 361ffffa677..78c3c85f964 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/HugeResourceTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/HugeResourceTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -48,6 +48,8 @@ import org.eclipse.jetty.client.util.MultiPartContentProvider; import org.eclipse.jetty.client.util.PathContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.DefaultHandler; @@ -166,7 +168,8 @@ public class HugeResourceTest public void startServer() throws Exception { server = new Server(); - ServerConnector connector = new ServerConnector(server); + HttpConfiguration httpConfig = new HttpConfiguration(); + ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig)); connector.setPort(0); server.addConnector(connector); @@ -258,7 +261,7 @@ public class HugeResourceTest @ParameterizedTest @MethodSource("staticFiles") - public void testUpload_Multipart(String filename, long expectedSize) throws Exception + public void testUploadMultipart(String filename, long expectedSize) throws Exception { MultiPartContentProvider multipart = new MultiPartContentProvider(); Path inputFile = staticBase.resolve(filename); @@ -266,6 +269,7 @@ public class HugeResourceTest multipart.addFilePart(name, filename, new PathContentProvider(inputFile), null); URI destUri = server.getURI().resolve("/multipart"); + client.setIdleTimeout(90_000); Request request = client.newRequest(destUri).method(HttpMethod.POST).content(multipart); ContentResponse response = request.send(); assertThat("HTTP Response Code", response.getStatus(), is(200)); diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/MetaInfConfigurationTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/MetaInfConfigurationTest.java index 94f1db88e3d..599872a30d6 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/MetaInfConfigurationTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/MetaInfConfigurationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -88,7 +88,7 @@ public class MetaInfConfigurationTest MetaInfConfiguration meta25 = new TestableMetaInfConfiguration(MetaInfConfiguration.__allScanTypes, Arrays.asList(MetaInfConfiguration.METAINF_TLDS, MetaInfConfiguration.METAINF_RESOURCES)); WebAppContext context25 = new WebAppContext(); - context25.getMetaData().setWebXml(Resource.newResource(web25)); + context25.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web25))); context25.getServletContext().setEffectiveMajorVersion(2); context25.getServletContext().setEffectiveMinorVersion(5); meta25.preConfigure(context25); @@ -98,7 +98,7 @@ public class MetaInfConfigurationTest MetaInfConfiguration.__allScanTypes); WebAppContext context25b = new WebAppContext(); context25b.setConfigurationDiscovered(true); - context25b.getMetaData().setWebXml(Resource.newResource(web25)); + context25b.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web25))); context25b.getServletContext().setEffectiveMajorVersion(2); context25b.getServletContext().setEffectiveMinorVersion(5); meta25b.preConfigure(context25b); @@ -107,7 +107,7 @@ public class MetaInfConfigurationTest MetaInfConfiguration meta31 = new TestableMetaInfConfiguration(MetaInfConfiguration.__allScanTypes, Arrays.asList(MetaInfConfiguration.METAINF_TLDS, MetaInfConfiguration.METAINF_RESOURCES)); WebAppContext context31 = new WebAppContext(); - context31.getMetaData().setWebXml(Resource.newResource(web31)); + context31.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31))); context31.getServletContext().setEffectiveMajorVersion(3); context31.getServletContext().setEffectiveMinorVersion(1); meta31.preConfigure(context31); @@ -117,7 +117,7 @@ public class MetaInfConfigurationTest MetaInfConfiguration.__allScanTypes); WebAppContext context31false = new WebAppContext(); context31false.setConfigurationDiscovered(true); - context31false.getMetaData().setWebXml(Resource.newResource(web31false)); + context31false.getMetaData().setWebDescriptor(new WebDescriptor(Resource.newResource(web31false))); context31false.getServletContext().setEffectiveMajorVersion(3); context31false.getServletContext().setEffectiveMinorVersion(1); meta31false.preConfigure(context31false); diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java index 4ad28f4637b..87a7152bb33 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/OrderingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -51,45 +51,30 @@ public class OrderingTest _name = name; } - /** - * @see org.eclipse.jetty.util.resource.Resource#addPath(java.lang.String) - */ @Override public Resource addPath(String path) throws IOException, MalformedURLException { return null; } - /** - * @see org.eclipse.jetty.util.resource.Resource#delete() - */ @Override public boolean delete() throws SecurityException { return false; } - /** - * @see org.eclipse.jetty.util.resource.Resource#exists() - */ @Override public boolean exists() { return false; } - /** - * @see org.eclipse.jetty.util.resource.Resource#getFile() - */ @Override public File getFile() throws IOException { return null; } - /** - * @see org.eclipse.jetty.util.resource.Resource#getInputStream() - */ @Override public InputStream getInputStream() throws IOException { @@ -102,9 +87,6 @@ public class OrderingTest return null; } - /** - * @see org.eclipse.jetty.util.resource.Resource#getName() - */ @Override public String getName() { @@ -117,62 +99,41 @@ public class OrderingTest return null; } - /** - * @see org.eclipse.jetty.util.resource.Resource#isContainedIn(org.eclipse.jetty.util.resource.Resource) - */ @Override public boolean isContainedIn(Resource r) throws MalformedURLException { return false; } - /** - * @see org.eclipse.jetty.util.resource.Resource#isDirectory() - */ @Override public boolean isDirectory() { return false; } - /** - * @see org.eclipse.jetty.util.resource.Resource#lastModified() - */ @Override public long lastModified() { return 0; } - /** - * @see org.eclipse.jetty.util.resource.Resource#length() - */ @Override public long length() { return 0; } - /** - * @see org.eclipse.jetty.util.resource.Resource#list() - */ @Override public String[] list() { return null; } - /** - * @see org.eclipse.jetty.util.resource.Resource#close() - */ @Override public void close() { } - /** - * @see org.eclipse.jetty.util.resource.Resource#renameTo(org.eclipse.jetty.util.resource.Resource) - */ @Override public boolean renameTo(Resource dest) throws SecurityException { @@ -517,11 +478,11 @@ public class OrderingTest final Resource jarResource = new TestResource("A"); metadata.setOrdering(new RelativeOrdering(metadata)); - metadata.addWebInfJar(jarResource); + metadata.addWebInfResource(jarResource); metadata.orderFragments(); - assertEquals(1, metadata.getOrderedWebInfJars().size()); + assertEquals(1, metadata.getWebInfResources(true).size()); metadata.orderFragments(); - assertEquals(1, metadata.getOrderedWebInfJars().size()); + assertEquals(1, metadata.getWebInfResources(true).size()); } @Test @@ -664,7 +625,7 @@ public class OrderingTest TestResource jar4 = new TestResource("D"); resources.add(jar4); TestResource r4 = new TestResource("D/web-fragment.xml"); - FragmentDescriptor f4 = new FragmentDescriptor((Resource)null); + FragmentDescriptor f4 = new FragmentDescriptor(r4); f4._name = "D"; metaData._webFragmentNameMap.put(f4._name, f4); metaData._webFragmentResourceMap.put(jar4, f4); @@ -672,7 +633,7 @@ public class OrderingTest TestResource jar5 = new TestResource("E"); resources.add(jar5); TestResource r5 = new TestResource("E/web-fragment.xml"); - FragmentDescriptor f5 = new FragmentDescriptor((Resource)null); + FragmentDescriptor f5 = new FragmentDescriptor(r5); f5._name = "E"; metaData._webFragmentNameMap.put(f5._name, f5); metaData._webFragmentResourceMap.put(jar5, f5); @@ -680,7 +641,7 @@ public class OrderingTest TestResource jar6 = new TestResource("plain"); resources.add(jar6); TestResource r6 = new TestResource("plain/web-fragment.xml"); - FragmentDescriptor f6 = new FragmentDescriptor((Resource)null); + FragmentDescriptor f6 = new FragmentDescriptor(r6); f6._name = FragmentDescriptor.NAMELESS + "1"; metaData._webFragmentNameMap.put(f6._name, f6); metaData._webFragmentResourceMap.put(jar6, f6); @@ -936,7 +897,7 @@ public class OrderingTest TestResource jar4 = new TestResource("D"); resources.add(jar4); TestResource r4 = new TestResource("D/web-fragment.xml"); - FragmentDescriptor f4 = new FragmentDescriptor((Resource)null); + FragmentDescriptor f4 = new FragmentDescriptor(r4); f4._name = "D"; metaData._webFragmentNameMap.put(f4._name, f4); metaData._webFragmentResourceMap.put(jar4, f4); @@ -944,7 +905,7 @@ public class OrderingTest TestResource jar5 = new TestResource("E"); resources.add(jar5); TestResource r5 = new TestResource("E/web-fragment.xml"); - FragmentDescriptor f5 = new FragmentDescriptor((Resource)null); + FragmentDescriptor f5 = new FragmentDescriptor(r5); f5._name = "E"; metaData._webFragmentNameMap.put(f5._name, f5); metaData._webFragmentResourceMap.put(jar5, f5); @@ -952,7 +913,7 @@ public class OrderingTest TestResource jar6 = new TestResource("plain"); resources.add(jar6); TestResource r6 = new TestResource("plain/web-fragment.xml"); - FragmentDescriptor f6 = new FragmentDescriptor((Resource)null); + FragmentDescriptor f6 = new FragmentDescriptor(r6); f6._name = FragmentDescriptor.NAMELESS + "1"; metaData._webFragmentNameMap.put(f6._name, f6); metaData._webFragmentResourceMap.put(jar6, f6); diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/StandardDescriptorProcessorTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/StandardDescriptorProcessorTest.java new file mode 100644 index 00000000000..05c9a0e597e --- /dev/null +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/StandardDescriptorProcessorTest.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.webapp; + +import java.io.File; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StandardDescriptorProcessorTest +{ + //TODO add tests for other methods + + @Test + public void testVisitSessionConfig() throws Exception + { + File webXml = MavenTestingUtils.getTestResourceFile("web-session-config.xml"); + Server server = new Server(); + WebAppContext wac = new WebAppContext(); + wac.setServer(server); + wac.setResourceBase(MavenTestingUtils.getTargetTestingDir("testSessionConfig").getAbsolutePath()); + wac.setDescriptor(webXml.toURI().toURL().toString()); + wac.start(); + assertEquals(54, TimeUnit.SECONDS.toMinutes(wac.getSessionHandler().getMaxInactiveInterval())); + } +} diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/TestMetaData.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/TestMetaData.java new file mode 100644 index 00000000000..1b226cc6926 --- /dev/null +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/TestMetaData.java @@ -0,0 +1,203 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.webapp; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.acme.webapp.TestAnnotation; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.EmptyResource; +import org.eclipse.jetty.util.resource.Resource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestMetaData +{ + File fragFile; + File nonFragFile; + Resource fragResource; + Resource nonFragResource; + Resource webfragxml; + Resource containerDir; + Resource webInfClassesDir; + WebAppContext wac; + TestAnnotation annotationA; + TestAnnotation annotationB; + TestAnnotation annotationC; + TestAnnotation annotationD; + TestAnnotation annotationE; + List applications; + + @BeforeEach + public void setUp() throws Exception + { + File jarDir = new File(MavenTestingUtils.getTestResourcesDir(), "fragments"); + assertTrue(jarDir.exists()); + fragFile = new File(jarDir, "zeta.jar"); + assertTrue(fragFile.exists()); + fragResource = Resource.newResource(fragFile); + nonFragFile = new File(jarDir, "sigma.jar"); + nonFragResource = Resource.newResource(nonFragFile); + assertTrue(nonFragFile.exists()); + webfragxml = Resource.newResource("jar:" + fragFile.toURI().toString() + "!/META-INF/web-fragment.xml"); + containerDir = Resource.newResource(MavenTestingUtils.getTargetTestingDir("container")); + webInfClassesDir = Resource.newResource(MavenTestingUtils.getTargetTestingDir("webinfclasses")); + wac = new WebAppContext(); + applications = new ArrayList<>(); + annotationA = new TestAnnotation(wac, "com.acme.A", fragResource, applications); + annotationB = new TestAnnotation(wac, "com.acme.B", nonFragResource, applications); + annotationC = new TestAnnotation(wac, "com.acme.C", null, applications); + annotationD = new TestAnnotation(wac, "com.acme.D", containerDir, applications); + annotationE = new TestAnnotation(wac, "com.acme.E", webInfClassesDir, applications); + } + + @Test + public void testAddWebInfResource() throws Exception + { + assertTrue(wac.getMetaData().getWebInfResources(false).isEmpty()); + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + assertTrue(wac.getMetaData().getWebInfResources(false).contains(fragResource)); + assertTrue(wac.getMetaData().getWebInfResources(false).contains(nonFragResource)); + } + + @Test + public void testGetFragmentForJar() throws Exception + { + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + wac.getMetaData().addFragmentDescriptor(fragResource, new FragmentDescriptor(webfragxml)); + assertThrows(NullPointerException.class, () -> + { + wac.getMetaData().addFragmentDescriptor(nonFragResource, null); + }); + + assertNotNull(wac.getMetaData().getFragmentDescriptorForJar(fragResource)); + assertNull(wac.getMetaData().getFragmentDescriptorForJar(nonFragResource)); + assertNull(wac.getMetaData().getFragmentDescriptorForJar(null)); + } + + @Test + public void testGetFragmentDescriptorByName() throws Exception + { + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + FragmentDescriptor fragDescriptor = new FragmentDescriptor(webfragxml); + wac.getMetaData().addFragmentDescriptor(fragResource, fragDescriptor); + assertNotNull(wac.getMetaData().getFragmentDescriptor(fragDescriptor.getName())); + } + + @Test + public void testGetFragmentDescriptorByLocation() throws Exception + { + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + FragmentDescriptor fragDescriptor = new FragmentDescriptor(webfragxml); + wac.getMetaData().addFragmentDescriptor(fragResource, fragDescriptor); + assertNotNull(wac.getMetaData().getFragmentDescriptor(webfragxml)); + } + + @Test + public void testGetJarForFragmentName() throws Exception + { + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + wac.getMetaData().addFragmentDescriptor(fragResource, new FragmentDescriptor(webfragxml)); + FragmentDescriptor descriptor = wac.getMetaData().getFragmentDescriptorForJar(fragResource); + assertNotNull(descriptor); + + assertNotNull(wac.getMetaData().getJarForFragmentName(descriptor.getName())); + assertNull(wac.getMetaData().getJarForFragmentName(null)); + assertNull(wac.getMetaData().getJarForFragmentName("")); + assertNull(wac.getMetaData().getJarForFragmentName("xxx")); + } + + @Test + public void testAddDiscoveredAnnotation() throws Exception + { + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + wac.getMetaData().addFragmentDescriptor(fragResource, new FragmentDescriptor(webfragxml)); + wac.getMetaData().addContainerResource(containerDir); + wac.getMetaData().setWebInfClassesResources(Collections.singletonList(webInfClassesDir)); + + wac.getMetaData().addDiscoveredAnnotation(annotationA); + wac.getMetaData().addDiscoveredAnnotation(annotationB); + wac.getMetaData().addDiscoveredAnnotation(annotationC); + wac.getMetaData().addDiscoveredAnnotation(annotationD); + wac.getMetaData().addDiscoveredAnnotation(annotationE); + + //test an annotation from a web-inf lib fragment + List list = wac.getMetaData()._annotations.get(fragResource); + assertThat(list, contains(annotationA)); + assertThat(list, hasSize(1)); + + //test an annotation from a web-inf lib fragment without a descriptor + list = wac.getMetaData()._annotations.get(nonFragResource); + assertThat(list, contains(annotationB)); + assertThat(list, hasSize(1)); + + //test an annotation that didn't have an associated resource + list = wac.getMetaData()._annotations.get(EmptyResource.INSTANCE); + assertThat(list, contains(annotationC)); + assertThat(list, hasSize(1)); + + //test an annotation that came from the container path + list = wac.getMetaData()._annotations.get(containerDir); + assertThat(list, contains(annotationD)); + assertThat(list, hasSize(1)); + + //test an annoation from web-inf classes + list = wac.getMetaData()._annotations.get(webInfClassesDir); + assertThat(list, contains(annotationE)); + assertThat(list, hasSize(1)); + } + + @Test + public void testResolve() throws Exception + { + wac.getMetaData().addWebInfResource(fragResource); + wac.getMetaData().addWebInfResource(nonFragResource); + wac.getMetaData().addFragmentDescriptor(fragResource, new FragmentDescriptor(webfragxml)); + wac.getMetaData().addContainerResource(containerDir); + wac.getMetaData().setWebInfClassesResources(Collections.singletonList(webInfClassesDir)); + + wac.getMetaData().addDiscoveredAnnotation(annotationA); + wac.getMetaData().addDiscoveredAnnotation(annotationB); + wac.getMetaData().addDiscoveredAnnotation(annotationC); + wac.getMetaData().addDiscoveredAnnotation(annotationD); + wac.getMetaData().addDiscoveredAnnotation(annotationE); + + wac.getMetaData().resolve(wac); + //test that annotations are applied from resources in order: + //no resource associated, container resources, web-inf classes resources, web-inf lib resources + assertThat(applications, contains(annotationC, annotationD, annotationE, annotationA, annotationB)); + } +} \ No newline at end of file diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/URLStreamHandlerUtil.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/URLStreamHandlerUtil.java index fbfbb0aa6be..695aa55d88f 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/URLStreamHandlerUtil.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/URLStreamHandlerUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java index 46fbbe61000..51db274b7e1 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderUrlStreamTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderUrlStreamTest.java index 50c1618444a..1f557667e17 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderUrlStreamTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppClassLoaderUrlStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java index 20e90ef451d..17c9fc6336c 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.webapp; @@ -79,6 +79,65 @@ public class WebAppContextTest Configurations.cleanKnown(); } + @Test + public void testDefaultContextPath() throws Exception + { + Server server = new Server(); + File webXml = MavenTestingUtils.getTestResourceFile("web-with-default-context-path.xml"); + File webXmlEmptyPath = MavenTestingUtils.getTestResourceFile("web-with-empty-default-context-path.xml"); + File webDefaultXml = MavenTestingUtils.getTestResourceFile("web-default-with-default-context-path.xml"); + File overrideWebXml = MavenTestingUtils.getTestResourceFile("override-web-with-default-context-path.xml"); + assertNotNull(webXml); + assertNotNull(webDefaultXml); + assertNotNull(overrideWebXml); + assertNotNull(webXmlEmptyPath); + + try + { + WebAppContext wac = new WebAppContext(); + wac.setResourceBase(MavenTestingUtils.getTargetTestingDir().getAbsolutePath()); + server.setHandler(wac); + + //test that an empty default-context-path defaults to root + wac.setDescriptor(webXmlEmptyPath.getAbsolutePath()); + server.start(); + assertEquals("/", wac.getContextPath()); + + server.stop(); + + //test web-default.xml value is used + wac.setDescriptor(null); + wac.setDefaultsDescriptor(webDefaultXml.getAbsolutePath()); + server.start(); + assertEquals("/one", wac.getContextPath()); + + server.stop(); + + //test web.xml value is used + wac.setDescriptor(webXml.getAbsolutePath()); + server.start(); + assertEquals("/two", wac.getContextPath()); + + server.stop(); + + //test override-web.xml value is used + wac.setOverrideDescriptor(overrideWebXml.getAbsolutePath()); + server.start(); + assertEquals("/three", wac.getContextPath()); + + server.stop(); + + //test that explicitly set context path is used instead + wac.setContextPath("/foo"); + server.start(); + assertEquals("/foo", wac.getContextPath()); + } + finally + { + server.stop(); + } + } + @Test public void testSessionListeners() { @@ -90,7 +149,7 @@ public class WebAppContextTest server.setHandler(wac); wac.addEventListener(new MySessionListener()); - Collection listeners = wac.getSessionHandler().getBeans(org.eclipse.jetty.webapp.WebAppContextTest.MySessionListener.class); + Collection listeners = wac.getSessionHandler().getBeans(MySessionListener.class); assertNotNull(listeners); assertEquals(1, listeners.size()); } @@ -99,8 +158,8 @@ public class WebAppContextTest public void testConfigurationClassesFromDefault() { Configurations.cleanKnown(); - String[] known_and_enabled = Configurations.getKnown().stream() - .filter(c -> !c.isDisabledByDefault()) + String[] knownAndEnabled = Configurations.getKnown().stream() + .filter(c -> c.isEnabledByDefault()) .map(c -> c.getClass().getName()) .toArray(String[]::new); @@ -108,10 +167,10 @@ public class WebAppContextTest //test if no classnames set, its the defaults WebAppContext wac = new WebAppContext(); - assertThat(wac.getWebAppConfigurations().stream() + assertThat(wac.getConfigurations().stream() .map(c -> c.getClass().getName()) .collect(Collectors.toList()), - Matchers.containsInAnyOrder(known_and_enabled)); + Matchers.containsInAnyOrder(knownAndEnabled)); String[] classNames = wac.getConfigurationClasses(); assertNotNull(classNames); @@ -126,7 +185,7 @@ public class WebAppContextTest Configurations.cleanKnown(); WebAppContext wac = new WebAppContext(); wac.setServer(new Server()); - assertThat(wac.getWebAppConfigurations().stream().map(c -> c.getClass().getName()).collect(Collectors.toList()), + assertThat(wac.getConfigurations().stream().map(c -> c.getClass().getName()).collect(Collectors.toList()), Matchers.contains( "org.eclipse.jetty.webapp.JmxConfiguration", "org.eclipse.jetty.webapp.WebInfConfiguration", @@ -144,14 +203,14 @@ public class WebAppContextTest Configuration[] configs = {new WebInfConfiguration()}; WebAppContext wac = new WebAppContext(); wac.setConfigurations(configs); - assertThat(wac.getWebAppConfigurations(), Matchers.contains(configs)); + assertThat(wac.getConfigurations(), Matchers.contains(configs)); //test that explicit config instances override any from server String[] classNames = {"x.y.z"}; Server server = new Server(); server.setAttribute(Configuration.ATTR, classNames); wac.setServer(server); - assertThat(wac.getWebAppConfigurations(), Matchers.contains(configs)); + assertThat(wac.getConfigurations(), Matchers.contains(configs)); } @Test @@ -424,6 +483,6 @@ public class WebAppContextTest context.setServer(new Server()); new MetaInfConfiguration().preConfigure(context); assertEquals(Arrays.asList("acme.jar", "alpha.jar", "omega.jar"), - context.getMetaData().getWebInfJars().stream().map(r -> r.getURI().toString().replaceFirst(".+/", "")).collect(Collectors.toList())); + context.getMetaData().getWebInfResources(false).stream().map(r -> r.getURI().toString().replaceFirst(".+/", "")).collect(Collectors.toList())); } } diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java new file mode 100644 index 00000000000..e1598a96759 --- /dev/null +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java @@ -0,0 +1,102 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.webapp; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.stream.Stream; + +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; +import org.eclipse.jetty.util.resource.PathResource; +import org.eclipse.jetty.util.resource.Resource; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * WebInfConfigurationTest + */ +@ExtendWith(WorkDirExtension.class) +public class WebInfConfigurationTest +{ + public WorkDir workDir; + + public static Stream rawResourceNames() + { + return Stream.of( + Arguments.of("/", ""), + Arguments.of("/a", "a") + ); + } + + @ParameterizedTest + @MethodSource("rawResourceNames") + public void testTinyGetResourceBaseName(String rawPath, String expectedName) throws IOException + { + Resource resource = Resource.newResource(rawPath); + assertThat(WebInfConfiguration.getResourceBaseName(resource), is(expectedName)); + } + + public static Stream fileBaseResourceNames() + { + return Stream.of( + Arguments.of("test.war", "test.war"), + Arguments.of("a/b/c/test.war", "test.war"), + Arguments.of("bar%2Fbaz/test.war", "test.war"), + Arguments.of("fizz buzz/test.war", "test.war"), + Arguments.of("another one/bites the dust/", "bites the dust"), + Arguments.of("another+one/bites+the+dust/", "bites+the+dust"), + Arguments.of("another%20one/bites%20the%20dust/", "bites%20the%20dust"), + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck + Arguments.of("spanish/n\u00FAmero.war", "n\u00FAmero.war"), + Arguments.of("spanish/n%C3%BAmero.war", "n%C3%BAmero.war"), + Arguments.of("a/b!/", "b!"), + Arguments.of("a/b!/c/", "c"), + Arguments.of("a/b!/c/d/", "d"), + Arguments.of("a/b%21/", "b%21") + ); + } + + @ParameterizedTest + @MethodSource("fileBaseResourceNames") + public void testPathGetResourceBaseName(String basePath, String expectedName) throws IOException + { + Path root = workDir.getPath(); + Path base = root.resolve(basePath); + if (basePath.endsWith("/")) + { + // we are working with a directory. + FS.ensureDirExists(base); + } + else + { + FS.ensureDirExists(base.getParent()); + FS.touch(base); + } + + Resource resource = new PathResource(base); + assertThat(WebInfConfiguration.getResourceBaseName(resource), is(expectedName)); + } +} diff --git a/jetty-webapp/src/test/resources/fragments/sigma.jar b/jetty-webapp/src/test/resources/fragments/sigma.jar new file mode 100644 index 00000000000..40dadb7a52c Binary files /dev/null and b/jetty-webapp/src/test/resources/fragments/sigma.jar differ diff --git a/jetty-webapp/src/test/resources/fragments/zeta.jar b/jetty-webapp/src/test/resources/fragments/zeta.jar new file mode 100644 index 00000000000..6e5ebb196d9 Binary files /dev/null and b/jetty-webapp/src/test/resources/fragments/zeta.jar differ diff --git a/jetty-webapp/src/test/resources/jetty-logging.properties b/jetty-webapp/src/test/resources/jetty-logging.properties index 9e7b0a45e6d..3d9406bcb9b 100644 --- a/jetty-webapp/src/test/resources/jetty-logging.properties +++ b/jetty-webapp/src/test/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl # org.eclipse.jetty.LEVEL=DEBUG # org.eclipse.jetty.webapp.LEVEL=DEBUG # org.eclipse.jetty.util.LEVEL=DEBUG diff --git a/jetty-webapp/src/test/resources/override-web-with-default-context-path.xml b/jetty-webapp/src/test/resources/override-web-with-default-context-path.xml new file mode 100644 index 00000000000..6e4b27ea699 --- /dev/null +++ b/jetty-webapp/src/test/resources/override-web-with-default-context-path.xml @@ -0,0 +1,10 @@ + + + + Test 4 WebApp + /three + + diff --git a/jetty-webapp/src/test/resources/web-default-with-default-context-path.xml b/jetty-webapp/src/test/resources/web-default-with-default-context-path.xml new file mode 100644 index 00000000000..1b89bf2dcf1 --- /dev/null +++ b/jetty-webapp/src/test/resources/web-default-with-default-context-path.xml @@ -0,0 +1,10 @@ + + + + Test 4 WebApp + /one + + diff --git a/jetty-webapp/src/test/resources/web-session-config.xml b/jetty-webapp/src/test/resources/web-session-config.xml new file mode 100644 index 00000000000..3a76ef2493b --- /dev/null +++ b/jetty-webapp/src/test/resources/web-session-config.xml @@ -0,0 +1,12 @@ + + + + Test 4 WebApp + + 54 + + + diff --git a/jetty-webapp/src/test/resources/web-with-default-context-path.xml b/jetty-webapp/src/test/resources/web-with-default-context-path.xml new file mode 100644 index 00000000000..82614beaf0e --- /dev/null +++ b/jetty-webapp/src/test/resources/web-with-default-context-path.xml @@ -0,0 +1,10 @@ + + + + Test 4 WebApp + /two + + diff --git a/jetty-webapp/src/test/resources/web-with-empty-default-context-path.xml b/jetty-webapp/src/test/resources/web-with-empty-default-context-path.xml new file mode 100644 index 00000000000..f4ad38d48af --- /dev/null +++ b/jetty-webapp/src/test/resources/web-with-empty-default-context-path.xml @@ -0,0 +1,10 @@ + + + + Test 4 WebApp + + + diff --git a/jetty-websocket/javax-websocket-client/src/main/java/module-info.java b/jetty-websocket/javax-websocket-client/src/main/java/module-info.java deleted file mode 100644 index 98e3d7ae491..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/module-info.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -import javax.websocket.ContainerProvider; - -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainerProvider; - -module org.eclipse.jetty.websocket.javax.client -{ - exports org.eclipse.jetty.websocket.javax.client; - - requires jetty.websocket.api; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.websocket.core; - requires org.eclipse.jetty.websocket.javax.common; - - provides ContainerProvider with JavaxWebSocketClientContainerProvider; -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/AnnotatedClientEndpointConfig.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/AnnotatedClientEndpointConfig.java deleted file mode 100644 index de554162f9c..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/AnnotatedClientEndpointConfig.java +++ /dev/null @@ -1,118 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.websocket.ClientEndpoint; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Extension; - -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; - -public class AnnotatedClientEndpointConfig implements ClientEndpointConfig -{ - private final ClientEndpoint annotation; - private final List> decoders; - private final List> encoders; - private final List extensions; - private final List preferredSubprotocols; - private final Configurator configurator; - private Map userProperties; - - public AnnotatedClientEndpointConfig(ClientEndpoint anno) - { - this.annotation = anno; - this.decoders = Collections.unmodifiableList(Arrays.asList(anno.decoders())); - this.encoders = Collections.unmodifiableList(Arrays.asList(anno.encoders())); - this.preferredSubprotocols = Collections.unmodifiableList(Arrays.asList(anno.subprotocols())); - - // no extensions declared in annotation - this.extensions = Collections.emptyList(); - // no userProperties in annotation - this.userProperties = new HashMap<>(); - - if (anno.configurator() == null) - { - this.configurator = EmptyConfigurator.INSTANCE; - } - else - { - try - { - this.configurator = anno.configurator().getDeclaredConstructor().newInstance(); - } - catch (Exception e) - { - StringBuilder err = new StringBuilder(); - err.append("Unable to instantiate ClientEndpoint.configurator() of "); - err.append(anno.configurator().getName()); - err.append(" defined as annotation in "); - err.append(anno.getClass().getName()); - throw new InvalidWebSocketException(err.toString(), e); - } - } - } - - public ClientEndpoint getAnnotation() - { - return annotation; - } - - @Override - public Configurator getConfigurator() - { - return configurator; - } - - @Override - public List> getDecoders() - { - return decoders; - } - - @Override - public List> getEncoders() - { - return encoders; - } - - @Override - public List getExtensions() - { - return extensions; - } - - @Override - public List getPreferredSubprotocols() - { - return preferredSubprotocols; - } - - @Override - public Map getUserProperties() - { - return userProperties; - } -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/DelegatedJavaxClientUpgradeRequest.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/DelegatedJavaxClientUpgradeRequest.java deleted file mode 100644 index d09d7e0f793..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/DelegatedJavaxClientUpgradeRequest.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import java.net.URI; -import java.security.Principal; - -import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; -import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; - -/** - * Representing the Jetty {@link org.eclipse.jetty.client.HttpClient}'s {@link org.eclipse.jetty.client.HttpRequest} - * in the {@link UpgradeRequest} interface. - */ -public class DelegatedJavaxClientUpgradeRequest implements UpgradeRequest -{ - private final ClientUpgradeRequest delegate; - - public DelegatedJavaxClientUpgradeRequest(ClientUpgradeRequest delegate) - { - this.delegate = delegate; - } - - @Override - public Principal getUserPrincipal() - { - // User Principal not available from Client API - return null; - } - - @Override - public URI getRequestURI() - { - return delegate.getURI(); - } -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/DelegatedJavaxClientUpgradeResponse.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/DelegatedJavaxClientUpgradeResponse.java deleted file mode 100644 index 2709aa88746..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/DelegatedJavaxClientUpgradeResponse.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.javax.common.UpgradeResponse; - -/** - * Representing the Jetty {@link org.eclipse.jetty.client.HttpClient}'s {@link HttpResponse} - * in the {@link UpgradeResponse} interface. - */ -public class DelegatedJavaxClientUpgradeResponse implements UpgradeResponse -{ - private HttpResponse delegate; - - public DelegatedJavaxClientUpgradeResponse(HttpResponse response) - { - this.delegate = response; - } - - @Override - public String getAcceptedSubProtocol() - { - return this.delegate.getHeaders().get(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL); - } - - @Override - public List getExtensions() - { - List rawExtensions = delegate.getHeaders().getValuesList(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); - if (rawExtensions == null || rawExtensions.isEmpty()) - return Collections.emptyList(); - - return rawExtensions.stream().map((parameterizedName) -> ExtensionConfig.parse(parameterizedName)).collect(Collectors.toList()); - } -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/EmptyClientEndpointConfig.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/EmptyClientEndpointConfig.java deleted file mode 100644 index 16718872d74..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/EmptyClientEndpointConfig.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Extension; - -public class EmptyClientEndpointConfig implements ClientEndpointConfig -{ - private final List> decoders; - private final List> encoders; - private final List extensions; - private final List preferredSubprotocols; - private final Configurator configurator; - private Map userProperties; - - public EmptyClientEndpointConfig() - { - this.decoders = new ArrayList<>(); - this.encoders = new ArrayList<>(); - this.preferredSubprotocols = new ArrayList<>(); - this.extensions = new ArrayList<>(); - this.userProperties = new HashMap<>(); - this.configurator = EmptyConfigurator.INSTANCE; - } - - @Override - public Configurator getConfigurator() - { - return configurator; - } - - @Override - public List> getDecoders() - { - return decoders; - } - - @Override - public List> getEncoders() - { - return encoders; - } - - @Override - public List getExtensions() - { - return extensions; - } - - @Override - public List getPreferredSubprotocols() - { - return preferredSubprotocols; - } - - @Override - public Map getUserProperties() - { - return userProperties; - } -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/EmptyConfigurator.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/EmptyConfigurator.java deleted file mode 100644 index 839c5e698df..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/EmptyConfigurator.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import java.util.List; -import java.util.Map; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.HandshakeResponse; - -public class EmptyConfigurator extends ClientEndpointConfig.Configurator -{ - public static final EmptyConfigurator INSTANCE = new EmptyConfigurator(); - - @Override - public void afterResponse(HandshakeResponse hr) - { - // do nothing - } - - @Override - public void beforeRequest(Map> headers) - { - // do nothing - } -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java deleted file mode 100644 index d726e26cb8e..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import java.net.URI; - -import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; -import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; -import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; - -public class JavaxClientUpgradeRequest extends ClientUpgradeRequest -{ - private final JavaxWebSocketClientContainer containerContext; - private final JavaxWebSocketFrameHandler frameHandler; - - public JavaxClientUpgradeRequest(JavaxWebSocketClientContainer clientContainer, WebSocketCoreClient coreClient, URI requestURI, Object websocketPojo) - { - super(coreClient, requestURI); - this.containerContext = clientContainer; - - UpgradeRequest upgradeRequest = new DelegatedJavaxClientUpgradeRequest(this); - frameHandler = containerContext.newFrameHandler(websocketPojo, upgradeRequest); - } - - @Override - public void upgrade(HttpResponse response, HttpConnectionOverHTTP httpConnection) - { - frameHandler.setUpgradeRequest(new DelegatedJavaxClientUpgradeRequest(this)); - frameHandler.setUpgradeResponse(new DelegatedJavaxClientUpgradeResponse(response)); - super.upgrade(response, httpConnection); - } - - @Override - public FrameHandler getFrameHandler() - { - return frameHandler; - } -} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientFrameHandlerFactory.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientFrameHandlerFactory.java deleted file mode 100644 index 1db249ed7fc..00000000000 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientFrameHandlerFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.client; - -import javax.websocket.ClientEndpoint; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; - -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerMetadata; -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils; - -public class JavaxWebSocketClientFrameHandlerFactory extends JavaxWebSocketFrameHandlerFactory -{ - public JavaxWebSocketClientFrameHandlerFactory(JavaxWebSocketContainer container) - { - super(container, InvokerUtils.PARAM_IDENTITY); - } - - @Override - public JavaxWebSocketFrameHandlerMetadata createMetadata(Class endpointClass, EndpointConfig endpointConfig) - { - if (javax.websocket.Endpoint.class.isAssignableFrom(endpointClass)) - { - return createEndpointMetadata((Class)endpointClass, endpointConfig); - } - - if (endpointClass.getAnnotation(ClientEndpoint.class) == null) - { - return null; - } - - JavaxWebSocketFrameHandlerMetadata metadata = new JavaxWebSocketFrameHandlerMetadata(endpointConfig); - return discoverJavaxFrameHandlerMetadata(endpointClass, metadata); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/module-info.java b/jetty-websocket/javax-websocket-common/src/main/java/module-info.java deleted file mode 100644 index 85af50b04e0..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/module-info.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -module org.eclipse.jetty.websocket.javax.common -{ - exports org.eclipse.jetty.websocket.javax.common; - exports org.eclipse.jetty.websocket.javax.common.decoders; - exports org.eclipse.jetty.websocket.javax.common.encoders; - exports org.eclipse.jetty.websocket.javax.common.messages; - exports org.eclipse.jetty.websocket.javax.common.util; - - requires jetty.websocket.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.websocket.core; -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/BasicEndpointConfig.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/BasicEndpointConfig.java deleted file mode 100644 index 3f284352e54..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/BasicEndpointConfig.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -/** - * Basic EndpointConfig (used when no EndpointConfig is provided or discovered) - */ -public class BasicEndpointConfig implements EndpointConfig -{ - private List> decoders; - private List> encoders; - private Map userProperties; - - public BasicEndpointConfig() - { - decoders = Collections.emptyList(); - encoders = Collections.emptyList(); - userProperties = new HashMap<>(); - } - - @Override - public List> getDecoders() - { - return decoders; - } - - @Override - public List> getEncoders() - { - return encoders; - } - - @Override - public Map getUserProperties() - { - return userProperties; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/CompletableFutureCallback.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/CompletableFutureCallback.java deleted file mode 100644 index 92b33f6167f..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/CompletableFutureCallback.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.concurrent.CompletableFuture; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public class CompletableFutureCallback extends CompletableFuture implements Callback -{ - private static final Logger LOG = Log.getLogger(CompletableFutureCallback.class); - - @Override - public void failed(Throwable cause) - { - if (LOG.isDebugEnabled()) - LOG.debug("failed()", cause); - - completeExceptionally(cause); - } - - @Override - public void succeeded() - { - if (LOG.isDebugEnabled()) - LOG.debug("succeeded()"); - - complete(this); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/DuplicateCoderException.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/DuplicateCoderException.java deleted file mode 100644 index 021552966e7..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/DuplicateCoderException.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -/** - * Thrown when a duplicate coder is encountered when attempting to identify a Endpoint's metadata ({@link javax.websocket.Decoder} or {@link javax.websocket.Encoder}) - * TODO: is this still needed? - */ -public class DuplicateCoderException extends InvalidWebSocketException -{ - private static final long serialVersionUID = -3049181444035417170L; - - public DuplicateCoderException(String message) - { - super(message); - } - - public DuplicateCoderException(String message, Throwable cause) - { - super(message, cause); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InitException.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InitException.java deleted file mode 100644 index a5c71bd3fb3..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InitException.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -/** - * Exception during initialization of the Endpoint - */ -public class InitException extends IllegalStateException -{ - private static final long serialVersionUID = -4691138423037387558L; - - public InitException(String message, Throwable cause) - { - super(message, cause); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InvalidWebSocketException.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InvalidWebSocketException.java deleted file mode 100644 index 04f9457da4e..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InvalidWebSocketException.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import org.eclipse.jetty.websocket.core.WebSocketException; - -/** - * Indicating that the provided Class is not a valid WebSocket per the chosen API. - */ -@SuppressWarnings("serial") -public class InvalidWebSocketException extends WebSocketException -{ - public InvalidWebSocketException(String message) - { - super(message); - } - - public InvalidWebSocketException(String message, Throwable cause) - { - super(message, cause); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketBasicRemote.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketBasicRemote.java deleted file mode 100644 index facff847978..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketBasicRemote.java +++ /dev/null @@ -1,160 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.nio.ByteBuffer; -import javax.websocket.EncodeException; -import javax.websocket.RemoteEndpoint; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.common.util.TextUtil; - -import static java.nio.charset.StandardCharsets.UTF_8; - -public class JavaxWebSocketBasicRemote extends JavaxWebSocketRemoteEndpoint implements RemoteEndpoint.Basic -{ - private static final Logger LOG = Log.getLogger(JavaxWebSocketBasicRemote.class); - - protected JavaxWebSocketBasicRemote(JavaxWebSocketSession session, FrameHandler.CoreSession coreSession) - { - super(session, coreSession); - } - - @Override - public OutputStream getSendStream() throws IOException - { - return newMessageOutputStream(); - } - - @Override - public Writer getSendWriter() throws IOException - { - return newMessageWriter(); - } - - @Override - public void sendBinary(ByteBuffer data) throws IOException - { - assertMessageNotNull(data); - if (LOG.isDebugEnabled()) - { - LOG.debug("sendBinary({})", BufferUtil.toDetailString(data)); - } - try (SharedBlockingCallback.Blocker b = session.getBlocking().acquire()) - { - sendFrame(new Frame(OpCode.BINARY).setPayload(data), b, false); - } - } - - @Override - public void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException - { - assertMessageNotNull(partialByte); - if (LOG.isDebugEnabled()) - { - LOG.debug("sendBinary({},{})", BufferUtil.toDetailString(partialByte), isLast); - } - try (SharedBlockingCallback.Blocker b = session.getBlocking().acquire()) - { - Frame frame; - switch (messageType) - { - case -1: - // New message! - frame = new Frame(OpCode.BINARY); - break; - case OpCode.TEXT: - throw new IllegalStateException("Cannot send a partial BINARY message: TEXT message in progress"); - case OpCode.BINARY: - frame = new Frame(OpCode.CONTINUATION); - break; - default: - throw new IllegalStateException("Cannot send a partial BINARY message: unrecognized active message type " + OpCode.name(messageType)); - } - - frame.setPayload(partialByte); - frame.setFin(isLast); - sendFrame(frame, b, false); - } - } - - @Override - public void sendObject(Object data) throws IOException, EncodeException - { - try (SharedBlockingCallback.Blocker b = session.getBlocking().acquire()) - { - super.sendObject(data, b); - } - } - - @Override - public void sendText(String text) throws IOException - { - assertMessageNotNull(text); - if (LOG.isDebugEnabled()) - { - LOG.debug("sendText({})", TextUtil.hint(text)); - } - try (SharedBlockingCallback.Blocker b = session.getBlocking().acquire()) - { - sendFrame(new Frame(OpCode.TEXT).setPayload(text), b, false); - } - } - - @Override - public void sendText(String partialMessage, boolean isLast) throws IOException - { - assertMessageNotNull(partialMessage); - if (LOG.isDebugEnabled()) - { - LOG.debug("sendText({},{})", TextUtil.hint(partialMessage), isLast); - } - try (SharedBlockingCallback.Blocker b = session.getBlocking().acquire()) - { - Frame frame; - switch (messageType) - { - case -1: - // New message! - frame = new Frame(OpCode.TEXT); - break; - case OpCode.TEXT: - frame = new Frame(OpCode.CONTINUATION); - break; - case OpCode.BINARY: - throw new IllegalStateException("Cannot send a partial TEXT message: BINARY message in progress"); - default: - throw new IllegalStateException("Cannot send a partial TEXT message: unrecognized active message type " + OpCode.name(messageType)); - } - - frame.setPayload(BufferUtil.toBuffer(partialMessage, UTF_8)); - frame.setFin(isLast); - sendFrame(frame, b, false); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtensionConfig.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtensionConfig.java deleted file mode 100644 index 725332930cc..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtensionConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import javax.websocket.Extension; - -import org.eclipse.jetty.websocket.core.ExtensionConfig; - -public class JavaxWebSocketExtensionConfig extends ExtensionConfig -{ - public JavaxWebSocketExtensionConfig(Extension ext) - { - super(ext.getName()); - for (Extension.Parameter param : ext.getParameters()) - { - this.setParameter(param.getName(), param.getValue()); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketPongMessage.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketPongMessage.java deleted file mode 100644 index 5c498c9def9..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketPongMessage.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.nio.ByteBuffer; -import javax.websocket.PongMessage; - -import org.eclipse.jetty.util.BufferUtil; - -public class JavaxWebSocketPongMessage implements PongMessage -{ - private final ByteBuffer data; - - public JavaxWebSocketPongMessage(ByteBuffer buf) - { - this.data = buf; - } - - @Override - public ByteBuffer getApplicationData() - { - if (data == null) - { - return BufferUtil.EMPTY_BUFFER; - } - return data.slice(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSessionListener.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSessionListener.java deleted file mode 100644 index bf4088f6e87..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSessionListener.java +++ /dev/null @@ -1,26 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -public interface JavaxWebSocketSessionListener -{ - void onJavaxWebSocketSessionOpened(JavaxWebSocketSession session); - - void onJavaxWebSocketSessionClosed(JavaxWebSocketSession session); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketUpgradeRequest.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketUpgradeRequest.java deleted file mode 100644 index 20118204892..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketUpgradeRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.net.URI; -import java.util.List; -import java.util.Map; - -public interface JavaxWebSocketUpgradeRequest -{ - boolean isSecure(); - - Map> getParameterMap(); - - String getProtocolVersion(); - - URI getRequestURI(); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketUpgradeResponse.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketUpgradeResponse.java deleted file mode 100644 index 9774898a50d..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketUpgradeResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.List; - -import org.eclipse.jetty.websocket.core.ExtensionConfig; - -public interface JavaxWebSocketUpgradeResponse -{ - String getAcceptedSubProtocol(); - - List getExtensions(); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/MessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/MessageSink.java deleted file mode 100644 index 5f9f23af787..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/MessageSink.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; - -/** - * Sink consumer for messages (used for multiple frames with continuations, - * and also to allow for streaming APIs) - */ -public interface MessageSink -{ - /** - * Consume the frame payload to the message. - * - * @param frame the frame, its payload (and fin state) to append - * @param callback the callback for how the frame was consumed - */ - void accept(Frame frame, Callback callback); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PathParamProvider.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PathParamProvider.java deleted file mode 100644 index 0cf3ee36ca3..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PathParamProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.Map; - -/** - * Optional interface for custom {@link javax.websocket.EndpointConfig} implementations - * in Jetty to expose Path Param values used during the {@link JavaxWebSocketFrameHandler} - * resolution of methods. - *

        - * Mostly a feature of the JSR356 Server implementation and its {@code @javax.websocket.server.PathParam} annotation. - *

        - */ -public interface PathParamProvider -{ - Map getPathParams(); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SendHandlerCallback.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SendHandlerCallback.java deleted file mode 100644 index 72829b1bfa2..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SendHandlerCallback.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import javax.websocket.SendHandler; -import javax.websocket.SendResult; - -import org.eclipse.jetty.util.Callback; - -/** - * Wrapper of user provided {@link SendHandler} to Jetty internal {@link Callback} - */ -public class SendHandlerCallback implements Callback -{ - private final SendHandler sendHandler; - - public SendHandlerCallback(SendHandler sendHandler) - { - this.sendHandler = sendHandler; - } - - @Override - public void failed(Throwable x) - { - sendHandler.onResult(new SendResult(x)); - } - - @Override - public void succeeded() - { - sendHandler.onResult(new SendResult()); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java deleted file mode 100644 index 3af932dac42..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; -import javax.websocket.Session; - -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.LifeCycle; - -public class SessionTracker extends AbstractLifeCycle implements JavaxWebSocketSessionListener -{ - private CopyOnWriteArraySet sessions = new CopyOnWriteArraySet<>(); - - public Set getSessions() - { - return Collections.unmodifiableSet(sessions); - } - - @Override - public void onJavaxWebSocketSessionOpened(JavaxWebSocketSession session) - { - sessions.add(session); - } - - @Override - public void onJavaxWebSocketSessionClosed(JavaxWebSocketSession session) - { - sessions.remove(session); - } - - @Override - protected void doStop() throws Exception - { - for (JavaxWebSocketSession session : sessions) - { - LifeCycle.stop(session); - } - super.doStop(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequest.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequest.java deleted file mode 100644 index 5c47e21fe85..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequest.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.net.URI; -import java.security.Principal; - -public interface UpgradeRequest -{ - /** - * For {@link javax.websocket.Session#getUserPrincipal()} - * - * @return the User {@link Principal} present during the Upgrade Request - */ - Principal getUserPrincipal(); - - /** - * For obtaining {@link javax.websocket.server.PathParam} values from Request URI path - * - * @return the request URI - */ - URI getRequestURI(); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequestAdapter.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequestAdapter.java deleted file mode 100644 index 2a7499d7734..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequestAdapter.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.net.URI; -import java.security.Principal; - -public class UpgradeRequestAdapter implements UpgradeRequest -{ - private URI requestURI; - - public UpgradeRequestAdapter() - { - /* anonymous, no requestURI, upgrade request */ - } - - public UpgradeRequestAdapter(URI uri) - { - this.requestURI = uri; - } - - @Override - public Principal getUserPrincipal() - { - return null; - } - - @Override - public URI getRequestURI() - { - return requestURI; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeResponse.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeResponse.java deleted file mode 100644 index f1f05389d4b..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.List; - -import org.eclipse.jetty.websocket.core.ExtensionConfig; - -public interface UpgradeResponse -{ - String getAcceptedSubProtocol(); - - List getExtensions(); -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeResponseAdapter.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeResponseAdapter.java deleted file mode 100644 index c33ce33fd56..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeResponseAdapter.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.Collections; -import java.util.List; - -import org.eclipse.jetty.websocket.core.ExtensionConfig; - -public class UpgradeResponseAdapter implements UpgradeResponse -{ - private final String acceptedSubProtocol; - private final List extensions; - - public UpgradeResponseAdapter() - { - this(null, Collections.emptyList()); - } - - public UpgradeResponseAdapter(String acceptedSubProtocol, List extensions) - { - this.acceptedSubProtocol = acceptedSubProtocol; - this.extensions = extensions; - } - - /** - * Get the accepted WebSocket protocol. - * - * @return the accepted WebSocket protocol. - */ - @Override - public String getAcceptedSubProtocol() - { - return acceptedSubProtocol; - } - - /** - * Get the list of extensions that should be used for the websocket. - * - * @return the list of negotiated extensions to use. - */ - @Override - public List getExtensions() - { - return extensions; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AbstractDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AbstractDecoder.java deleted file mode 100644 index 77acc3005b4..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AbstractDecoder.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import javax.websocket.Decoder; -import javax.websocket.EndpointConfig; - -public abstract class AbstractDecoder implements Decoder -{ - @Override - public void destroy() - { - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/BooleanDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/BooleanDecoder.java deleted file mode 100644 index c0cf801b79e..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/BooleanDecoder.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import javax.websocket.DecodeException; -import javax.websocket.Decoder; - -/** - * Default implementation of the {@link javax.websocket.Decoder.Text} Message to {@link Boolean} decoder. - *

        - * Note: delegates to {@link Boolean#parseBoolean(String)} and will only support "true" and "false" as boolean values. - */ -public class BooleanDecoder extends AbstractDecoder implements Decoder.Text -{ - public static final BooleanDecoder INSTANCE = new BooleanDecoder(); - - @Override - public Boolean decode(String s) throws DecodeException - { - return Boolean.parseBoolean(s); - } - - @Override - public boolean willDecode(String s) - { - if (s == null) - { - return false; - } - return true; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteArrayDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteArrayDecoder.java deleted file mode 100644 index ef88a60e25c..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteArrayDecoder.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import java.nio.ByteBuffer; -import javax.websocket.DecodeException; -import javax.websocket.Decoder; - -import org.eclipse.jetty.util.BufferUtil; - -public class ByteArrayDecoder extends AbstractDecoder implements Decoder.Binary -{ - public static final ByteArrayDecoder INSTANCE = new ByteArrayDecoder(); - - @Override - public byte[] decode(ByteBuffer bytes) throws DecodeException - { - return BufferUtil.toArray(bytes); - } - - @Override - public boolean willDecode(ByteBuffer bytes) - { - return true; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteBufferDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteBufferDecoder.java deleted file mode 100644 index 22f6568e34a..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteBufferDecoder.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import java.nio.ByteBuffer; -import javax.websocket.DecodeException; -import javax.websocket.Decoder; - -public class ByteBufferDecoder extends AbstractDecoder implements Decoder.Binary -{ - public static final ByteBufferDecoder INSTANCE = new ByteBufferDecoder(); - - @Override - public ByteBuffer decode(ByteBuffer bytes) throws DecodeException - { - return bytes; - } - - @Override - public boolean willDecode(ByteBuffer bytes) - { - return true; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/InputStreamDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/InputStreamDecoder.java deleted file mode 100644 index 3fbe996713e..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/InputStreamDecoder.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import java.io.IOException; -import java.io.InputStream; -import javax.websocket.DecodeException; -import javax.websocket.Decoder; -import javax.websocket.EndpointConfig; - -public class InputStreamDecoder implements Decoder.BinaryStream -{ - @Override - public InputStream decode(InputStream is) throws DecodeException, IOException - { - return is; - } - - @Override - public void destroy() - { - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ReaderDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ReaderDecoder.java deleted file mode 100644 index a0fb6fbd339..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ReaderDecoder.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import java.io.IOException; -import java.io.Reader; -import javax.websocket.DecodeException; -import javax.websocket.Decoder; -import javax.websocket.EndpointConfig; - -public class ReaderDecoder implements Decoder.TextStream -{ - @Override - public Reader decode(Reader reader) throws DecodeException, IOException - { - return reader; - } - - @Override - public void destroy() - { - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/StringDecoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/StringDecoder.java deleted file mode 100644 index 0bd1a348650..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/StringDecoder.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.decoders; - -import javax.websocket.DecodeException; -import javax.websocket.Decoder; - -/** - * Default implementation of the {@link javax.websocket.Decoder.Text} Message to {@link String} decoder - */ -public class StringDecoder extends AbstractDecoder implements Decoder.Text -{ - public static final StringDecoder INSTANCE = new StringDecoder(); - - @Override - public String decode(String s) throws DecodeException - { - return s; - } - - @Override - public boolean willDecode(String s) - { - return true; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AbstractEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AbstractEncoder.java deleted file mode 100644 index a4c93614b6d..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AbstractEncoder.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -public abstract class AbstractEncoder implements Encoder -{ - @Override - public void destroy() - { - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/BooleanEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/BooleanEncoder.java deleted file mode 100644 index 92696e1f55b..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/BooleanEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Boolean} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class BooleanEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Boolean object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteArrayEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteArrayEncoder.java deleted file mode 100644 index ef94b204bea..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteArrayEncoder.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import java.nio.ByteBuffer; -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -public class ByteArrayEncoder implements Encoder.Binary -{ - @Override - public void destroy() - { - /* do nothing */ - } - - @Override - public ByteBuffer encode(byte[] object) throws EncodeException - { - return ByteBuffer.wrap(object); - } - - @Override - public void init(EndpointConfig config) - { - /* do nothing */ - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteBufferEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteBufferEncoder.java deleted file mode 100644 index 6afb93ad7ca..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteBufferEncoder.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import java.nio.ByteBuffer; -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -public class ByteBufferEncoder implements Encoder.Binary -{ - @Override - public void destroy() - { - /* do nothing */ - } - - @Override - public ByteBuffer encode(ByteBuffer object) throws EncodeException - { - return object; - } - - @Override - public void init(EndpointConfig config) - { - /* do nothing */ - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteEncoder.java deleted file mode 100644 index 0bba080dd2f..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Byte} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class ByteEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Byte object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/CharacterEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/CharacterEncoder.java deleted file mode 100644 index a3b5e395c17..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/CharacterEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Character} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class CharacterEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Character object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/DoubleEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/DoubleEncoder.java deleted file mode 100644 index 83e86191cb9..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/DoubleEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Double} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class DoubleEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Double object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/FloatEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/FloatEncoder.java deleted file mode 100644 index e6f1c0cb73b..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/FloatEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Float} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class FloatEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Float object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/IntegerEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/IntegerEncoder.java deleted file mode 100644 index 4d2a969fb28..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/IntegerEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Integer} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class IntegerEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Integer object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/LongEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/LongEncoder.java deleted file mode 100644 index 9379ed5acaa..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/LongEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Long} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class LongEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Long object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ShortEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ShortEncoder.java deleted file mode 100644 index f2f10377544..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ShortEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link Short} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class ShortEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(Short object) throws EncodeException - { - if (object == null) - { - return null; - } - return object.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/StringEncoder.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/StringEncoder.java deleted file mode 100644 index 46eb791a87e..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/StringEncoder.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.encoders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; - -/** - * Default encoder for {@link String} to {@link javax.websocket.Encoder.Text} Message encoder - */ -public class StringEncoder extends AbstractEncoder implements Encoder.Text -{ - @Override - public String encode(String object) throws EncodeException - { - return object; - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSink.java deleted file mode 100644 index 74ccbd17dde..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSink.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.util.Objects; - -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.MessageSink; - -public abstract class AbstractMessageSink implements MessageSink -{ - protected final JavaxWebSocketSession session; - protected final MethodHandle methodHandle; - - public AbstractMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - this.session = Objects.requireNonNull(session, "JavaxWebSocketSession"); - this.methodHandle = Objects.requireNonNull(methodHandle, "MethodHandle"); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ByteArrayMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ByteArrayMessageSink.java deleted file mode 100644 index 2d9100ab3af..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ByteArrayMessageSink.java +++ /dev/null @@ -1,104 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.ByteArrayOutputStream; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.nio.ByteBuffer; -import java.util.Objects; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; - -public class ByteArrayMessageSink extends AbstractMessageSink -{ - private static final byte[] EMPTY_BUFFER = new byte[0]; - private static final int BUFFER_SIZE = 65535; - private ByteArrayOutputStream out; - private int size; - - public ByteArrayMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - - Objects.requireNonNull(methodHandle, "MethodHandle"); - // byte[] buf - MethodType onMessageType = MethodType.methodType(Void.TYPE, byte[].class); - if (methodHandle.type().changeReturnType(void.class) != onMessageType.changeReturnType(void.class)) - { - throw InvalidSignatureException.build(onMessageType, methodHandle.type()); - } - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - - size += payload.remaining(); - if (session.getMaxBinaryMessageBufferSize() > 0 && size > session.getMaxBinaryMessageBufferSize()) - { - throw new MessageTooLargeException(String.format("Binary message too large: (actual) %,d > (configured max binary buffer size) %,d", - size, session.getMaxBinaryMessageBufferSize())); - } - - if (out == null) - out = new ByteArrayOutputStream(BUFFER_SIZE); - - BufferUtil.writeTo(payload, out); - } - - if (frame.isFin()) - { - if (out != null) - { - byte[] buf = out.toByteArray(); - methodHandle.invoke(buf); - } - else - methodHandle.invoke(EMPTY_BUFFER); - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - finally - { - if (frame.isFin()) - { - // reset - out = null; - size = 0; - } - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ByteBufferMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ByteBufferMessageSink.java deleted file mode 100644 index ed939a05540..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ByteBufferMessageSink.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.ByteArrayOutputStream; -import java.lang.invoke.MethodHandle; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; - -public class ByteBufferMessageSink extends AbstractMessageSink -{ - private static final int BUFFER_SIZE = 65535; - private ByteArrayOutputStream out; - private int size; - - public ByteBufferMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - - size += payload.remaining(); - if (session.getMaxBinaryMessageBufferSize() > 0 && size > session.getMaxBinaryMessageBufferSize()) - { - throw new MessageTooLargeException(String.format("Binary message too large: (actual) %,d > (configured max binary buffer size) %,d", - size, session.getMaxBinaryMessageBufferSize())); - } - - if (out == null) - out = new ByteArrayOutputStream(BUFFER_SIZE); - - BufferUtil.writeTo(payload, out); - payload.position(payload.limit()); // consume buffer - } - - if (frame.isFin()) - { - if (out != null) - methodHandle.invoke(ByteBuffer.wrap(out.toByteArray())); - else - methodHandle.invoke(BufferUtil.EMPTY_BUFFER); - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - finally - { - if (frame.isFin()) - { - // reset - out = null; - size = 0; - } - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/CallbackBuffer.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/CallbackBuffer.java deleted file mode 100644 index fc2ea7f786d..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/CallbackBuffer.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.nio.ByteBuffer; -import java.util.Objects; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; - -public class CallbackBuffer -{ - public ByteBuffer buffer; - public Callback callback; - - public CallbackBuffer(Callback callback, ByteBuffer buffer) - { - Objects.requireNonNull(buffer, "buffer"); - this.callback = callback; - this.buffer = buffer; - } - - @Override - public String toString() - { - return String.format("CallbackBuffer[%s,%s]", BufferUtil.toDetailString(buffer), callback.getClass().getSimpleName()); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedMessageSink.java deleted file mode 100644 index 51893a953ba..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedMessageSink.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import javax.websocket.Decoder; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.MessageSink; - -public abstract class DecodedMessageSink extends AbstractMessageSink -{ - protected final Logger logger; - private final T decoder; - private final MethodHandle rawMethodHandle; - private final MessageSink rawMessageSink; - - public DecodedMessageSink(JavaxWebSocketSession session, T decoder, MethodHandle methodHandle) - throws NoSuchMethodException, IllegalAccessException - { - super(session, methodHandle); - this.logger = Log.getLogger(this.getClass()); - this.decoder = decoder; - this.rawMethodHandle = newRawMethodHandle(); - this.rawMessageSink = newRawMessageSink(session, rawMethodHandle); - } - - protected abstract MethodHandle newRawMethodHandle() - throws NoSuchMethodException, IllegalAccessException; - - protected abstract MessageSink newRawMessageSink(JavaxWebSocketSession session, MethodHandle rawMethodHandle); - - public T getDecoder() - { - return decoder; - } - - @Override - public void accept(Frame frame, Callback callback) - { - this.rawMessageSink.accept(frame, callback); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DispatchedMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DispatchedMessageSink.java deleted file mode 100644 index a875db1f7d5..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DispatchedMessageSink.java +++ /dev/null @@ -1,178 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.MessageSink; - -/** - * Centralized logic for Dispatched Message Handling. - *

        - * A Dispatched MessageSink can consist of 1 or more {@link #accept(Frame, Callback)} calls. - *

        - * The first {@link #accept(Frame, Callback)} in a message will trigger a dispatch to the - * function specified in the constructor. - *

        - * The completion of the dispatched function call is the sign that the next message is suitable - * for processing from the network. (The connection fillAndParse should remain idle for the - * NEXT message until such time as the dispatched function call has completed) - *

        - *

        - * There are a few use cases we need to handle. - *

        - *

        - * 1. Normal Processing - *

        - *
        - *     Connection Thread | DispatchedMessageSink | Thread 2
        - *     TEXT                accept()
        - *                          - dispatch -           function.read(stream)
        - *     CONT                accept()                stream.read()
        - *     CONT                accept()                stream.read()
        - *     CONT=fin            accept()                stream.read()
        - *                           EOF                   stream.read EOF
        - *     IDLE
        - *                                                 exit method
        - *     RESUME(NEXT MSG)
        - * 
        - *

        - * 2. Early Exit (with no activity) - *

        - *
        - *     Connection Thread | DispatchedMessageSink | Thread 2
        - *     TEXT                accept()
        - *                          - dispatch -           function.read(stream)
        - *     CONT                accept()                exit method (normal return)
        - *     IDLE
        - *     TIMEOUT
        - * 
        - *

        - * 3. Early Exit (due to exception) - *

        - *
        - *     Connection Thread | DispatchedMessageSink | Thread 2
        - *     TEXT                accept()
        - *                          - dispatch -           function.read(stream)
        - *     CONT                accept()                exit method (throwable)
        - *     callback.fail()
        - *     endpoint.onError()
        - *     close(error)
        - * 
        - *

        - * 4. Early Exit (with Custom Threading) - *

        - *
        - *     Connection Thread | DispatchedMessageSink | Thread 2              | Thread 3
        - *     TEXT                accept()
        - *                          - dispatch -           function.read(stream)
        - *                                                 thread.new(stream)      stream.read()
        - *                                                 exit method
        - *     CONT                accept()                                        stream.read()
        - *     CONT                accept()                                        stream.read()
        - *     CONT=fin            accept()                                        stream.read()
        - *                           EOF                                           stream.read EOF
        - *     RESUME(NEXT MSG)
        - * 
        - * - * @param the type of object to give to user function - */ -@SuppressWarnings("Duplicates") -public abstract class DispatchedMessageSink extends AbstractMessageSink -{ - private final Executor executor; - private CompletableFuture dispatchComplete; - private MessageSink typeSink; - - public DispatchedMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - this.executor = session.getContainerImpl().getExecutor(); - Objects.requireNonNull(this.executor, "Executor"); - } - - public abstract MessageSink newSink(Frame frame); - - public void accept(Frame frame, final Callback callback) - { - if (typeSink == null) - { - typeSink = newSink(frame); - // Dispatch to end user function (will likely start with blocking for data/accept) - dispatchComplete = new CompletableFuture<>(); - executor.execute(() -> - { - final T dispatchedType = (T)typeSink; - try - { - methodHandle.invoke(dispatchedType); - dispatchComplete.complete(null); - } - catch (Throwable throwable) - { - dispatchComplete.completeExceptionally(throwable); - } - }); - } - - final Callback frameCallback; - - if (frame.isFin()) - { - CompletableFuture finComplete = new CompletableFuture<>(); - frameCallback = new Callback() - { - @Override - public void failed(Throwable cause) - { - finComplete.completeExceptionally(cause); - } - - @Override - public void succeeded() - { - finComplete.complete(null); - } - }; - CompletableFuture.allOf(dispatchComplete, finComplete).whenComplete( - (aVoid, throwable) -> - { - typeSink = null; - dispatchComplete = null; - if (throwable != null) - callback.failed(throwable); - else - callback.succeeded(); - }); - } - else - { - // Non-fin-frame - frameCallback = callback; - } - - typeSink.accept(frame, frameCallback); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSink.java deleted file mode 100644 index 786885f63fe..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSink.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.InputStream; -import java.lang.invoke.MethodHandle; - -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.MessageSink; - -public class InputStreamMessageSink extends DispatchedMessageSink -{ - public InputStreamMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - } - - @Override - public MessageSink newSink(Frame frame) - { - return new MessageInputStream(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageInputStream.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageInputStream.java deleted file mode 100644 index 98ed8f72197..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageInputStream.java +++ /dev/null @@ -1,227 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.MessageSink; - -/** - * Support class for reading a WebSocket BINARY message via a InputStream. - *

        - * An InputStream that can access a queue of ByteBuffer payloads, along with expected InputStream blocking behavior. - *

        - */ -public class MessageInputStream extends InputStream implements MessageSink -{ - private static final Logger LOG = Log.getLogger(MessageInputStream.class); - private static final CallbackBuffer EOF = new CallbackBuffer(Callback.NOOP, BufferUtil.EMPTY_BUFFER); - private final Deque buffers = new ArrayDeque<>(2); - private final AtomicBoolean closed = new AtomicBoolean(false); - private CallbackBuffer activeFrame; - - @Override - public void accept(Frame frame, Callback callback) - { - if (LOG.isDebugEnabled()) - LOG.debug("accepting {}", frame); - - // If closed, we should just toss incoming payloads into the bit bucket. - if (closed.get()) - { - callback.failed(new IOException("Already Closed")); - return; - } - - if (!frame.hasPayload() && !frame.isFin()) - { - callback.succeeded(); - return; - } - - synchronized (buffers) - { - boolean notify = false; - if (frame.hasPayload()) - { - buffers.offer(new CallbackBuffer(callback, frame.getPayload())); - notify = true; - } - else - { - // We cannot wake up blocking read for a zero length frame. - callback.succeeded(); - } - - if (frame.isFin()) - { - buffers.offer(EOF); - notify = true; - } - - if (notify) - { - // notify other thread - buffers.notify(); - } - } - } - - @Override - public void close() throws IOException - { - if (LOG.isDebugEnabled()) - LOG.debug("close()"); - - if (closed.compareAndSet(false, true)) - { - synchronized (buffers) - { - buffers.offer(EOF); - buffers.notify(); - } - } - super.close(); - } - - public CallbackBuffer getActiveFrame() throws InterruptedIOException - { - if (activeFrame == null) - { - // sync and poll queue - CallbackBuffer result; - synchronized (buffers) - { - try - { - while ((result = buffers.poll()) == null) - { - // TODO: handle read timeout here? - buffers.wait(); - } - } - catch (InterruptedException e) - { - shutdown(); - throw new InterruptedIOException(); - } - } - activeFrame = result; - } - - return activeFrame; - } - - private void shutdown() - { - if (LOG.isDebugEnabled()) - LOG.debug("shutdown()"); - synchronized (buffers) - { - closed.set(true); - Throwable cause = new IOException("Shutdown"); - for (CallbackBuffer buffer : buffers) - { - buffer.callback.failed(cause); - } - // Removed buffers that may have remained in the queue. - buffers.clear(); - } - } - - @Override - public void mark(int readlimit) - { - // Not supported. - } - - @Override - public boolean markSupported() - { - return false; - } - - @Override - public int read() throws IOException - { - byte[] buf = new byte[1]; - while (true) - { - int len = read(buf, 0, 1); - if (len < 0) // EOF - return -1; - if (len > 0) // did read something - return buf[0]; - // reading nothing (len == 0) tries again - } - } - - @Override - public int read(final byte[] b, final int off, final int len) throws IOException - { - if (closed.get()) - { - if (LOG.isDebugEnabled()) - LOG.debug("Stream closed"); - return -1; - } - - CallbackBuffer result = getActiveFrame(); - - if (LOG.isDebugEnabled()) - LOG.debug("result = {}", result); - - if (result == EOF) - { - if (LOG.isDebugEnabled()) - LOG.debug("Read EOF"); - shutdown(); - return -1; - } - - // We have content - int fillLen = Math.min(result.buffer.remaining(), len); - result.buffer.get(b, off, fillLen); - - if (!result.buffer.hasRemaining()) - { - activeFrame = null; - result.callback.succeeded(); - } - - // return number of bytes actually copied into buffer - return fillLen; - } - - @Override - public void reset() throws IOException - { - throw new IOException("reset() not supported"); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageReader.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageReader.java deleted file mode 100644 index 2d00bc19df6..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageReader.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.MessageSink; - -/** - * Support class for reading a (single) WebSocket TEXT message via a Reader. - *

        - * In compliance to the WebSocket spec, this reader always uses the {@link StandardCharsets#UTF_8}. - */ -public class MessageReader extends InputStreamReader implements MessageSink -{ - private final MessageInputStream stream; - - public MessageReader(MessageInputStream stream) - { - super(stream, StandardCharsets.UTF_8); - this.stream = stream; - } - - @Override - public void accept(Frame frame, Callback callback) - { - this.stream.accept(frame, callback); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageWriter.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageWriter.java deleted file mode 100644 index 33916a756c7..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageWriter.java +++ /dev/null @@ -1,226 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.IOException; -import java.io.Writer; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; - -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * Support for writing a single WebSocket TEXT message via a {@link Writer} - *

        - * Note: Per WebSocket spec, all WebSocket TEXT messages must be encoded in UTF-8 - */ -public class MessageWriter extends Writer -{ - private static final Logger LOG = Log.getLogger(MessageWriter.class); - - private final CharsetEncoder utf8Encoder = UTF_8.newEncoder() - .onUnmappableCharacter(CodingErrorAction.REPORT) - .onMalformedInput(CodingErrorAction.REPORT); - - private final FrameHandler.CoreSession coreSession; - private final SharedBlockingCallback blocker; - private long frameCount; - private Frame frame; - private CharBuffer buffer; - private Callback callback; - private boolean closed; - - public MessageWriter(FrameHandler.CoreSession coreSession, int bufferSize) - { - this.coreSession = coreSession; - this.blocker = new SharedBlockingCallback(); - this.buffer = CharBuffer.allocate(bufferSize); - this.frame = new Frame(OpCode.TEXT); - } - - @Override - public void write(char[] chars, int off, int len) throws IOException - { - try - { - send(chars, off, len); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - @Override - public void write(int c) throws IOException - { - try - { - send(new char[]{(char)c}, 0, 1); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - @Override - public void flush() throws IOException - { - try - { - flush(false); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - private void flush(boolean fin) throws IOException - { - synchronized (this) - { - if (closed) - throw new IOException("Stream is closed"); - - closed = fin; - - buffer.flip(); - ByteBuffer payload = utf8Encoder.encode(buffer); - buffer.flip(); - - if (LOG.isDebugEnabled()) - LOG.debug("flush({}): {}", fin, BufferUtil.toDetailString(payload)); - frame.setPayload(payload); - frame.setFin(fin); - - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.sendFrame(frame, b, false); - b.block(); - } - - ++frameCount; - // Any flush after the first will be a CONTINUATION frame. - frame = new Frame(OpCode.CONTINUATION); - } - } - - private void send(char[] chars, int offset, int length) throws IOException - { - synchronized (this) - { - if (closed) - throw new IOException("Stream is closed"); - - CharBuffer source = CharBuffer.wrap(chars, offset, length); - - int remaining = length; - - while (remaining > 0) - { - int read = source.read(buffer); - if (read == -1) - { - return; - } - - remaining -= read; - - if (remaining > 0) - { - // If we could not write everything, it means - // that the buffer was full, so flush it. - flush(false); - } - } - } - } - - @Override - public void close() throws IOException - { - try - { - flush(true); - if (LOG.isDebugEnabled()) - LOG.debug("Stream closed, {} frames sent", frameCount); - // Notify without holding locks. - notifySuccess(); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - public void setCallback(Callback callback) - { - synchronized (this) - { - this.callback = callback; - } - } - - private void notifySuccess() - { - Callback callback; - synchronized (this) - { - callback = this.callback; - } - if (callback != null) - { - callback.succeeded(); - } - } - - private void notifyFailure(Throwable failure) - { - Callback callback; - synchronized (this) - { - callback = this.callback; - } - if (callback != null) - { - callback.failed(failure); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialByteArrayMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialByteArrayMessageSink.java deleted file mode 100644 index 9af9424ac11..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialByteArrayMessageSink.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.nio.ByteBuffer; -import java.util.Objects; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; - -public class PartialByteArrayMessageSink extends AbstractMessageSink -{ - public PartialByteArrayMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - - Objects.requireNonNull(methodHandle, "MethodHandle"); - // byte[] buf, int offset, int length - MethodType onMessageType = MethodType.methodType(Void.TYPE, byte[].class, int.class, int.class, boolean.class); - if (methodHandle.type() != onMessageType) - { - throw InvalidSignatureException.build(onMessageType, methodHandle.type()); - } - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - byte[] buffer; - int offset = 0; - int length = 0; - - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - length = payload.remaining(); - buffer = BufferUtil.toArray(payload); - } - else - { - buffer = new byte[0]; - } - - methodHandle.invoke(buffer, offset, length, frame.isFin()); - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialByteBufferMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialByteBufferMessageSink.java deleted file mode 100644 index 0934aab0dcb..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialByteBufferMessageSink.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; - -public class PartialByteBufferMessageSink extends AbstractMessageSink -{ - public PartialByteBufferMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - ByteBuffer buffer; - - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - // copy buffer here - buffer = ByteBuffer.allocate(payload.remaining()); - BufferUtil.clearToFill(buffer); - BufferUtil.put(payload, buffer); - BufferUtil.flipToFlush(buffer, 0); - } - else - { - buffer = BufferUtil.EMPTY_BUFFER; - } - - methodHandle.invoke(buffer, frame.isFin()); - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialStringMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialStringMessageSink.java deleted file mode 100644 index 569eb32b535..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/PartialStringMessageSink.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.nio.ByteBuffer; -import java.util.Objects; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; - -public class PartialStringMessageSink extends AbstractMessageSink -{ - private static final Logger LOG = Log.getLogger(PartialStringMessageSink.class); - private Utf8StringBuilder utf; - private int size; - - public PartialStringMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - Objects.requireNonNull(methodHandle, "MethodHandle"); - this.size = 0; - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (utf == null) - utf = new Utf8StringBuilder(1024); - - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - - //TODO we should fragment on maxTextMessageBufferSize not limit - //TODO also for PartialBinaryMessageSink - /* - if ((session.getMaxTextMessageBufferSize() > 0) && (size + payload.remaining() > session.getMaxTextMessageBufferSize())) - { - throw new MessageTooLargeException(String.format("Binary message too large: (actual) %,d > (configured max text buffer size) %,d", - size + payload.remaining(), session.getMaxTextMessageBufferSize())); - } - */ - - size += payload.remaining(); - - if (LOG.isDebugEnabled()) - LOG.debug("Raw Payload {}", BufferUtil.toDetailString(payload)); - - // allow for fast fail of BAD utf - utf.append(payload); - } - - if (frame.isFin()) - { - // Using toString to trigger failure on incomplete UTF-8 - methodHandle.invoke(utf.toString(), true); - // reset - size = 0; - utf = null; - } - else - { - methodHandle.invoke(utf.takePartialString(), false); - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSink.java deleted file mode 100644 index 39b0f5eda74..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSink.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.io.Reader; -import java.lang.invoke.MethodHandle; - -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; - -public class ReaderMessageSink extends DispatchedMessageSink -{ - public ReaderMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - } - - @Override - public MessageReader newSink(Frame frame) - { - return new MessageReader(new MessageInputStream()); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/StringMessageSink.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/StringMessageSink.java deleted file mode 100644 index 291c6a5c67d..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/StringMessageSink.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; - -public class StringMessageSink extends AbstractMessageSink -{ - private static final Logger LOG = Log.getLogger(StringMessageSink.class); - private Utf8StringBuilder utf; - private int size; - - public StringMessageSink(JavaxWebSocketSession session, MethodHandle methodHandle) - { - super(session, methodHandle); - this.size = 0; - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - - size += payload.remaining(); - if (session.getMaxTextMessageBufferSize() > 0 && size > session.getMaxTextMessageBufferSize()) - { - throw new MessageTooLargeException(String.format("Binary message too large: (actual) %,d > (configured max text buffer size) %,d", - size, session.getMaxTextMessageBufferSize())); - } - - if (utf == null) - utf = new Utf8StringBuilder(1024); - - if (LOG.isDebugEnabled()) - LOG.debug("Raw Payload {}", BufferUtil.toDetailString(payload)); - - // allow for fast fail of BAD utf (incomplete utf will trigger on messageComplete) - utf.append(payload); - } - - if (frame.isFin()) - { - // notify event - if (utf != null) - methodHandle.invoke(utf.toString()); - else - methodHandle.invoke(""); - - // reset - size = 0; - utf = null; - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/DuplicateAnnotationException.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/DuplicateAnnotationException.java deleted file mode 100644 index 6fb239d4e6d..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/DuplicateAnnotationException.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.util; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; - -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; - -@SuppressWarnings("serial") -public class DuplicateAnnotationException extends InvalidWebSocketException -{ - public static DuplicateAnnotationException build(Class pojo, Class annoClass, Method... methods) - { - // Build big detailed exception to help the developer - StringBuilder err = new StringBuilder(); - err.append("Duplicate @"); - err.append(annoClass.getSimpleName()); - err.append(" declarations in: "); - err.append(pojo.getName()); - - for (Method method : methods) - { - err.append(System.lineSeparator()); - ReflectUtils.append(err, method); - } - - return new DuplicateAnnotationException(err.toString()); - } - - public DuplicateAnnotationException(String message) - { - super(message); - } - - public DuplicateAnnotationException(String message, Throwable cause) - { - super(message, cause); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtils.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtils.java deleted file mode 100644 index d388e1905e1..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtils.java +++ /dev/null @@ -1,562 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.util; - -import java.lang.annotation.Annotation; -import java.lang.invoke.MethodType; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; - -public class ReflectUtils -{ - - private static final Pattern JAVAX_CLASSNAME_PATTERN = Pattern.compile("^javax*\\..*"); - - private static class GenericRef - { - // The base class reference lookup started from - private final Class baseClass; - // The interface that we are interested in - private final Class ifaceClass; - - // The actual class generic interface was found on - Class genericClass; - - // The found genericType - public Type genericType; - private int genericIndex; - - public GenericRef(final Class baseClass, final Class ifaceClass) - { - this.baseClass = baseClass; - this.ifaceClass = ifaceClass; - } - - public boolean needsUnwrap() - { - return (genericClass == null) && (genericType != null) && (genericType instanceof TypeVariable); - } - - public void setGenericFromType(Type type, int index) - { - // debug("setGenericFromType(%s,%d)",toShortName(type),index); - this.genericType = type; - this.genericIndex = index; - if (type instanceof Class) - { - this.genericClass = (Class)type; - } - } - - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - builder.append("GenericRef [baseClass="); - builder.append(baseClass); - builder.append(", ifaceClass="); - builder.append(ifaceClass); - builder.append(", genericType="); - builder.append(genericType); - builder.append(", genericClass="); - builder.append(genericClass); - builder.append("]"); - return builder.toString(); - } - } - - private static StringBuilder appendTypeName(StringBuilder sb, Type type, boolean ellipses) - { - if (type instanceof Class) - { - Class ctype = (Class)type; - if (ctype.isArray()) - { - try - { - int dimensions = 0; - while (ctype.isArray()) - { - dimensions++; - ctype = ctype.getComponentType(); - } - sb.append(ctype.getName()); - for (int i = 0; i < dimensions; i++) - { - if (ellipses) - { - sb.append("..."); - } - else - { - sb.append("[]"); - } - } - return sb; - } - catch (Throwable ignore) - { - // ignore - } - } - - sb.append(ctype.getName()); - } - else - { - sb.append(type.toString()); - } - - return sb; - } - - public static void assertIsAnnotated(Method method, Class annoClass) - { - if (method.getAnnotation(annoClass) == null) - { - StringBuilder err = new StringBuilder(); - err.append("Method does not declare required @"); - err.append(annoClass.getName()); - err.append(" annotation: "); - err.append(method); - - throw new InvalidWebSocketException(err.toString()); - } - } - - public static void assertIsPublicNonStatic(Method method) - { - int mods = method.getModifiers(); - if (!Modifier.isPublic(mods)) - { - StringBuilder err = new StringBuilder(); - err.append("Invalid declaration of "); - err.append(method); - err.append(System.lineSeparator()); - - err.append("Method modifier must be public"); - - throw new InvalidWebSocketException(err.toString()); - } - - if (Modifier.isStatic(mods)) - { - StringBuilder err = new StringBuilder(); - err.append("Invalid declaration of "); - err.append(method); - err.append(System.lineSeparator()); - - err.append("Method modifier must not be static"); - - throw new InvalidWebSocketException(err.toString()); - } - } - - public static void assertIsReturn(Method method, Class type) - { - if (!type.equals(method.getReturnType())) - { - StringBuilder err = new StringBuilder(); - err.append("Invalid declaration of "); - err.append(method); - err.append(System.lineSeparator()); - - err.append("Return type must be ").append(type); - - throw new InvalidWebSocketException(err.toString()); - } - } - - public static Method findMethod(Class pojo, String methodName, Class... params) - { - try - { - return pojo.getMethod(methodName, params); - } - catch (NoSuchMethodException e) - { - return null; - } - } - - public static Method findAnnotatedMethod(Class pojo, Class anno) - { - Method[] methods = findAnnotatedMethods(pojo, anno); - if (methods == null) - { - return null; - } - - if (methods.length > 1) - { - throw DuplicateAnnotationException.build(pojo, anno, methods); - } - - return methods[0]; - } - - public static Method[] findAnnotatedMethods(Class pojo, Class anno) - { - List methods = null; - Class clazz = pojo; - - while ((clazz != null) && Object.class.isAssignableFrom(clazz)) - { - for (Method method : clazz.getDeclaredMethods()) - { - if (method.getAnnotation(anno) != null) - { - if (methods == null) - methods = new ArrayList<>(); - methods.add(method); - } - } - clazz = clazz.getSuperclass(); - } - - if (methods == null) - return null; - int len = methods.size(); - return methods.toArray(new Method[len]); - } - - /** - * Given a Base (concrete) Class, find the interface specified, and return its concrete Generic class declaration. - * - * @param baseClass the base (concrete) class to look in - * @param ifaceClass the interface of interest - * @return the (concrete) generic class that the interface exposes - */ - public static Class findGenericClassFor(Class baseClass, Class ifaceClass) - { - GenericRef ref = new GenericRef(baseClass, ifaceClass); - if (resolveGenericRef(ref, baseClass)) - { - // debug("Generic Found: %s",ref.genericClass); - return ref.genericClass; - } - - // debug("Generic not found: %s",ref); - return null; - } - - private static int findTypeParameterIndex(Class clazz, TypeVariable needVar) - { - // debug("findTypeParameterIndex(%s, [%s])",toShortName(clazz),toShortName(needVar)); - TypeVariable[] params = clazz.getTypeParameters(); - for (int i = 0; i < params.length; i++) - { - if (params[i].getName().equals(needVar.getName())) - { - // debug("Type Parameter found at index: [%d]",i); - return i; - } - } - // debug("Type Parameter NOT found"); - return -1; - } - - public static boolean isDefaultConstructable(Class clazz) - { - int mods = clazz.getModifiers(); - if (Modifier.isAbstract(mods) || !Modifier.isPublic(mods)) - { - // Needs to be public, non-abstract - return false; - } - - Class[] noargs = new Class[0]; - try - { - // Needs to have a no-args constructor - Constructor constructor = clazz.getConstructor(noargs); - // Constructor needs to be public - return Modifier.isPublic(constructor.getModifiers()); - } - catch (NoSuchMethodException | SecurityException e) - { - return false; - } - } - - public static boolean isSameParameters(Class[] actual, Class[] params) - { - if (actual.length != params.length) - { - // skip - return false; - } - - int len = params.length; - for (int i = 0; i < len; i++) - { - if (!actual[i].equals(params[i])) - { - return false; // not valid - } - } - - return true; - } - - private static boolean resolveGenericRef(GenericRef ref, Class clazz, Type type) - { - if (type instanceof Class) - { - if (type == ref.ifaceClass) - { - // is this a straight ref or a TypeVariable? - // debug("Found ref (as class): %s",toShortName(type)); - ref.setGenericFromType(type, 0); - return true; - } - else - { - // Keep digging - return resolveGenericRef(ref, type); - } - } - - if (type instanceof ParameterizedType) - { - ParameterizedType ptype = (ParameterizedType)type; - Type rawType = ptype.getRawType(); - if (rawType == ref.ifaceClass) - { - // debug("Found ref on [%s] as ParameterizedType [%s]",toShortName(clazz),toShortName(ptype)); - // Always get the raw type parameter, let unwrap() solve for what it is - ref.setGenericFromType(ptype.getActualTypeArguments()[0], 0); - return true; - } - else - { - // Keep digging - return resolveGenericRef(ref, rawType); - } - } - return false; - } - - private static boolean resolveGenericRef(GenericRef ref, Type type) - { - if ((type == null) || (type == Object.class)) - { - return false; - } - - if (type instanceof Class) - { - Class clazz = (Class)type; - // prevent spinning off into Serialization and other parts of the - // standard tree that we could care less about - if (JAVAX_CLASSNAME_PATTERN.matcher(clazz.getName()).matches()) - { - return false; - } - - Type[] ifaces = clazz.getGenericInterfaces(); - for (Type iface : ifaces) - { - // debug("resolve %s interface[]: %s",toShortName(clazz),toShortName(iface)); - if (resolveGenericRef(ref, clazz, iface)) - { - if (ref.needsUnwrap()) - { - // debug("## Unwrap class %s::%s",toShortName(clazz),toShortName(iface)); - TypeVariable needVar = (TypeVariable)ref.genericType; - // debug("needs unwrap of type var [%s] - index [%d]",toShortName(needVar),ref.genericIndex); - - // attempt to find typeParameter on class itself - int typeParamIdx = findTypeParameterIndex(clazz, needVar); - // debug("type param index for %s[%s] is [%d]",toShortName(clazz),toShortName(needVar),typeParamIdx); - - if (typeParamIdx >= 0) - { - // found a type parameter, use it - // debug("unwrap from class [%s] - typeParameters[%d]",toShortName(clazz),typeParamIdx); - TypeVariable[] params = clazz.getTypeParameters(); - if (params.length >= typeParamIdx) - { - ref.setGenericFromType(params[typeParamIdx], typeParamIdx); - } - } - else if (iface instanceof ParameterizedType) - { - // use actual args on interface - Type arg = ((ParameterizedType)iface).getActualTypeArguments()[ref.genericIndex]; - ref.setGenericFromType(arg, ref.genericIndex); - } - } - return true; - } - } - - type = clazz.getGenericSuperclass(); - return resolveGenericRef(ref, type); - } - - if (type instanceof ParameterizedType) - { - ParameterizedType ptype = (ParameterizedType)type; - Class rawClass = (Class)ptype.getRawType(); - if (resolveGenericRef(ref, rawClass)) - { - if (ref.needsUnwrap()) - { - // debug("## Unwrap ParameterizedType %s::%s",toShortName(type),toShortName(rawClass)); - TypeVariable needVar = (TypeVariable)ref.genericType; - // debug("needs unwrap of type var [%s] - index [%d]",toShortName(needVar),ref.genericIndex); - int typeParamIdx = findTypeParameterIndex(rawClass, needVar); - // debug("type paramIdx of %s::%s is index [%d]",toShortName(rawClass),toShortName(needVar),typeParamIdx); - - Type arg = ptype.getActualTypeArguments()[typeParamIdx]; - ref.setGenericFromType(arg, typeParamIdx); - return true; - } - } - } - - return false; - } - - public static String toShortName(Type type) - { - if (type == null) - { - return ""; - } - - if (type instanceof Class) - { - String name = ((Class)type).getName(); - return trimClassName(name); - } - - if (type instanceof ParameterizedType) - { - ParameterizedType ptype = (ParameterizedType)type; - StringBuilder str = new StringBuilder(); - str.append(trimClassName(((Class)ptype.getRawType()).getName())); - str.append("<"); - Type[] args = ptype.getActualTypeArguments(); - for (int i = 0; i < args.length; i++) - { - if (i > 0) - { - str.append(","); - } - str.append(args[i]); - } - str.append(">"); - return str.toString(); - } - - return type.toString(); - } - - public static String toString(Class pojo, Method method) - { - StringBuilder str = new StringBuilder(); - - append(str, pojo, method); - - return str.toString(); - } - - public static String trimClassName(String name) - { - int idx = name.lastIndexOf('.'); - name = name.substring(idx + 1); - idx = name.lastIndexOf('$'); - if (idx >= 0) - { - name = name.substring(idx + 1); - } - return name; - } - - public static void append(StringBuilder str, Class pojo, Method method) - { - // method modifiers - int mod = method.getModifiers() & Modifier.methodModifiers(); - if (mod != 0) - { - str.append(Modifier.toString(mod)).append(' '); - } - - // return type - Type retType = method.getGenericReturnType(); - appendTypeName(str, retType, false).append(' '); - - if (pojo != null) - { - // class name - str.append(pojo.getName()); - str.append("#"); - } - - // method name - str.append(method.getName()); - - // method parameters - str.append('('); - Type[] params = method.getGenericParameterTypes(); - for (int j = 0; j < params.length; j++) - { - boolean ellipses = method.isVarArgs() && (j == (params.length - 1)); - appendTypeName(str, params[j], ellipses); - if (j < (params.length - 1)) - { - str.append(", "); - } - } - str.append(')'); - - // TODO: show exceptions? - } - - public static void append(StringBuilder str, Method method) - { - append(str, null, method); - } - - public static void append(StringBuilder str, MethodType methodType) - { - str.append(methodType.returnType().getName()); - str.append("("); - boolean delim = false; - for (Class paramType : methodType.parameterList()) - { - if (delim) - str.append(", "); - str.append(paramType.getName()); - delim = true; - } - str.append(")"); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/TextUtil.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/TextUtil.java deleted file mode 100644 index 1e12267ef2b..00000000000 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/TextUtil.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.util; - -/** - * Collection of utility methods for Text content - */ -public final class TextUtil -{ - /** - * Create a hint of what the text is like. - *

        - * Used by logging and error messages to get a hint of what the text is like. - * - * @param text the text to abbreviate, quote, and generally give you a hint of what the value is. - * @return the abbreviated text - */ - public static String quote(String text) - { - if (text == null) - { - return ""; - } - return '"' + text + '"'; - } - - /** - * Create a hint of what the text is like. - *

        - * Used by logging and error messages to get a hint of what the text is like. - * - * @param text the text to abbreviate, quote, and generally give you a hint of what the value is. - * @return the abbreviated text - */ - public static String hint(String text) - { - if (text == null) - { - return ""; - } - return '"' + maxStringLength(30, text) + '"'; - } - - /** - * Smash a long string to fit within the max string length, by taking the middle section of the string and replacing them with an ellipsis "..." - * - *

        -     * Examples:
        -     * .maxStringLength( 9, "Eatagramovabits") == "Eat...its"
        -     * .maxStringLength(10, "Eatagramovabits") == "Eat...bits"
        -     * .maxStringLength(11, "Eatagramovabits") == "Eata...bits"
        -     * 
        - * - * @param max the maximum size of the string (minimum size supported is 9) - * @param raw the raw string to smash - * @return the ellipsis'd version of the string. - */ - public static String maxStringLength(int max, String raw) - { - int length = raw.length(); - if (length <= max) - { - // already short enough - return raw; - } - - if (max < 9) - { - // minimum supported - return raw.substring(0, max); - } - - StringBuilder ret = new StringBuilder(); - int startLen = (int)Math.round((double)max / (double)3); - ret.append(raw.substring(0, startLen)); - ret.append("..."); - ret.append(raw.substring(length - (max - startLen - 3))); - - return ret.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/Defaults.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/Defaults.java deleted file mode 100644 index e3d7ef1dcea..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/Defaults.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import java.util.concurrent.TimeUnit; - -public final class Defaults -{ - public static final long CONNECT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); - public static final long OPEN_EVENT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); - public static final long CLOSE_EVENT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyFrameHandlerFactory.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyFrameHandlerFactory.java deleted file mode 100644 index 8b55a88df18..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyFrameHandlerFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common; - -import javax.websocket.ClientEndpoint; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; - -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils; - -public class DummyFrameHandlerFactory extends JavaxWebSocketFrameHandlerFactory -{ - public DummyFrameHandlerFactory(JavaxWebSocketContainer container) - { - super(container, InvokerUtils.PARAM_IDENTITY); - } - - @Override - public JavaxWebSocketFrameHandlerMetadata createMetadata(Class endpointClass, EndpointConfig endpointConfig) - { - if (javax.websocket.Endpoint.class.isAssignableFrom(endpointClass)) - { - return createEndpointMetadata((Class)endpointClass, endpointConfig); - } - - if (endpointClass.getAnnotation(ClientEndpoint.class) == null) - { - return null; - } - - JavaxWebSocketFrameHandlerMetadata metadata = new JavaxWebSocketFrameHandlerMetadata(endpointConfig); - return discoverJavaxFrameHandlerMetadata(endpointClass, metadata); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/ExtDecoder.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/ExtDecoder.java deleted file mode 100644 index e6ef0df128e..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/ExtDecoder.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.coders.tests; - -import javax.websocket.Decoder; - -/** - * Testing scenario of an extended Decoder interface - * - * @param the decoder type - */ -public interface ExtDecoder extends Decoder.Text -{ - void setId(String id); -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/Fruit.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/Fruit.java deleted file mode 100644 index e6735590fb1..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/Fruit.java +++ /dev/null @@ -1,25 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.coders.tests; - -public class Fruit -{ - public String name; - public String color; -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitTextEncoder.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitTextEncoder.java deleted file mode 100644 index d4a44f23967..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitTextEncoder.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.coders.tests; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -public class FruitTextEncoder implements Encoder.Text -{ - @Override - public void destroy() - { - } - - @Override - public String encode(Fruit fruit) throws EncodeException - { - return String.format("%s|%s", fruit.name, fruit.color); - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/DummyEndpoint.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/DummyEndpoint.java deleted file mode 100644 index eb86e7f03f1..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/DummyEndpoint.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.endpoints; - -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.Session; - -public class DummyEndpoint extends Endpoint -{ - @Override - public void onOpen(Session session, EndpointConfig config) - { - /* do nothing */ - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/EchoStringEndpoint.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/EchoStringEndpoint.java deleted file mode 100644 index 8bf4caa1b8a..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/EchoStringEndpoint.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.endpoints; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; - -/** - * Legitimate structure for an Endpoint - */ -public class EchoStringEndpoint extends AbstractStringEndpoint -{ - public BlockingQueue messageQueue = new LinkedBlockingDeque<>(); - - @Override - public void onMessage(String message) - { - messageQueue.offer(message); - session.getAsyncRemote().sendText(message); - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/BaseMessageHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/BaseMessageHandler.java deleted file mode 100644 index 5689de61e4a..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/BaseMessageHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import javax.websocket.MessageHandler; - -public class BaseMessageHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(String message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayPartialHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayPartialHandler.java deleted file mode 100644 index 99c07e6c6bf..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayPartialHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import javax.websocket.MessageHandler; - -public class ByteArrayPartialHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(byte[] partialMessage, boolean last) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayWholeHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayWholeHandler.java deleted file mode 100644 index 7ba6da36ec3..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayWholeHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import javax.websocket.MessageHandler; - -public class ByteArrayWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(byte[] message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferPartialHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferPartialHandler.java deleted file mode 100644 index 7b3729db4de..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferPartialHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -public class ByteBufferPartialHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(ByteBuffer partialMessage, boolean last) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferWholeHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferWholeHandler.java deleted file mode 100644 index 3a9a0a15577..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferWholeHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -public class ByteBufferWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(ByteBuffer message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ComboMessageHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ComboMessageHandler.java deleted file mode 100644 index e505a0f4c62..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ComboMessageHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -/** - * A particularly annoying type of MessageHandler. One defining 2 implementations. - */ -public class ComboMessageHandler implements MessageHandler.Whole, MessageHandler.Partial -{ - @Override - public void onMessage(ByteBuffer partialMessage, boolean last) - { - // TODO Auto-generated method stub - } - - @Override - public void onMessage(String message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ExtendedMessageHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ExtendedMessageHandler.java deleted file mode 100644 index 7307fc2648d..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ExtendedMessageHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -public class ExtendedMessageHandler extends BaseMessageHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(ByteBuffer partialMessage, boolean last) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/InputStreamWholeHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/InputStreamWholeHandler.java deleted file mode 100644 index 2818cf8ff86..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/InputStreamWholeHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import java.io.InputStream; -import javax.websocket.MessageHandler; - -public class InputStreamWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(InputStream stream) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/LongMessageHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/LongMessageHandler.java deleted file mode 100644 index 84e55333843..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/LongMessageHandler.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import javax.websocket.MessageHandler; - -public class LongMessageHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(Long message) - { - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ReaderWholeHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ReaderWholeHandler.java deleted file mode 100644 index e32ae8c972b..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ReaderWholeHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import java.io.Reader; -import javax.websocket.MessageHandler; - -public class ReaderWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(Reader reader) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringPartialHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringPartialHandler.java deleted file mode 100644 index a24161ce30a..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringPartialHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import javax.websocket.MessageHandler; - -public class StringPartialHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(String partialMessage, boolean last) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringWholeHandler.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringWholeHandler.java deleted file mode 100644 index c941f7d977a..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringWholeHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.handlers; - -import javax.websocket.MessageHandler; - -public class StringWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(String message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSinkTest.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSinkTest.java deleted file mode 100644 index e5cd46c4e33..00000000000 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSinkTest.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.common.messages; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.util.function.Consumer; - -import org.eclipse.jetty.websocket.javax.common.AbstractSessionTest; - -public abstract class AbstractMessageSinkTest extends AbstractSessionTest -{ - public MethodHandle getAcceptHandle(Consumer copy, Class type) - { - try - { - Class refc = copy.getClass(); - String name = "accept"; - MethodType methodType = MethodType.methodType(void.class, type); - MethodHandle handle = MethodHandles.lookup().findVirtual(refc, name, methodType); - return handle.bindTo(copy); - } - catch (NoSuchMethodException | IllegalAccessException e) - { - throw new RuntimeException("Ooops, we didn't find the Consumer<" + type.getName() + "> MethodHandle", e); - } - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/config/modules/websocket.mod b/jetty-websocket/javax-websocket-server/src/main/config/modules/websocket.mod deleted file mode 100644 index d0136c4ca22..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/config/modules/websocket.mod +++ /dev/null @@ -1,18 +0,0 @@ -DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - -[description] -Enable websockets for deployed web applications - -[depend] -# websocket client needs jetty-client -client -# javax.websocket needs annotations -annotations - -[lib] -lib/websocket/*.jar - -[jpms] -# The implementation needs to access method handles in -# classes that are in the web application classloader. -add-reads: org.eclipse.jetty.websocket.javax.common=ALL-UNNAMED diff --git a/jetty-websocket/javax-websocket-server/src/main/java/module-info.java b/jetty-websocket/javax-websocket-server/src/main/java/module-info.java deleted file mode 100644 index 3c20f2e9d1d..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/module-info.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -import javax.servlet.ServletContainerInitializer; -import javax.websocket.server.ServerEndpointConfig; - -import org.eclipse.jetty.webapp.Configuration; -import org.eclipse.jetty.websocket.javax.server.ContainerDefaultConfigurator; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketConfiguration; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; - -module org.eclipse.jetty.websocket.javax.server -{ - exports org.eclipse.jetty.websocket.javax.server; - - requires jetty.servlet.api; - requires jetty.websocket.api; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.servlet; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.webapp; - requires org.eclipse.jetty.websocket.core; - requires org.eclipse.jetty.websocket.javax.client; - requires org.eclipse.jetty.websocket.javax.common; - requires org.eclipse.jetty.websocket.servlet; - - provides ServletContainerInitializer with JavaxWebSocketServletContainerInitializer; - provides ServerEndpointConfig.Configurator with ContainerDefaultConfigurator; - provides Configuration with JavaxWebSocketConfiguration; -} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketConfiguration.java b/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketConfiguration.java deleted file mode 100644 index 57255fad3b2..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketConfiguration.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server; - -import org.eclipse.jetty.webapp.AbstractConfiguration; -import org.eclipse.jetty.webapp.FragmentConfiguration; -import org.eclipse.jetty.webapp.MetaInfConfiguration; -import org.eclipse.jetty.webapp.WebAppConfiguration; -import org.eclipse.jetty.webapp.WebInfConfiguration; -import org.eclipse.jetty.webapp.WebXmlConfiguration; - -/** - *

        Websocket Configuration

        - *

        This configuration configures the WebAppContext server/system classes to - * be able to see the org.eclipse.jetty.websocket package. - *

        - */ -public class JavaxWebSocketConfiguration extends AbstractConfiguration -{ - public JavaxWebSocketConfiguration() - { - addDependencies(WebXmlConfiguration.class, MetaInfConfiguration.class, WebInfConfiguration.class, FragmentConfiguration.class); - addDependents("org.eclipse.jetty.annotations.AnnotationConfiguration", WebAppConfiguration.class.getName()); - protectAndExpose("org.eclipse.jetty.websocket.servlet."); // For WebSocketUpgradeFilter - protectAndExpose("org.eclipse.jetty.websocket.javax."); // TODO Do we need all classes? - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/AnnotatedServerEndpointConfig.java b/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/AnnotatedServerEndpointConfig.java deleted file mode 100644 index 277fa42daec..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/AnnotatedServerEndpointConfig.java +++ /dev/null @@ -1,253 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.internal; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.websocket.Decoder; -import javax.websocket.DeploymentException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; -import javax.websocket.Extension; -import javax.websocket.server.ServerEndpoint; -import javax.websocket.server.ServerEndpointConfig; - -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; -import org.eclipse.jetty.websocket.javax.server.ContainerDefaultConfigurator; - -public class AnnotatedServerEndpointConfig implements ServerEndpointConfig -{ - private final Class endpointClass; - private final String path; - private final List> decoders; - private final List> encoders; - private final ServerEndpointConfig.Configurator configurator; - private final List subprotocols; - - private Map userProperties; - private List extensions; - - public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class endpointClass, ServerEndpoint anno) throws DeploymentException - { - this(containerScope, endpointClass, anno, null); - } - - public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class endpointClass, ServerEndpoint anno, EndpointConfig baseConfig) - throws DeploymentException - { - ServerEndpointConfig baseServerConfig = null; - - if (baseConfig instanceof ServerEndpointConfig) - { - baseServerConfig = (ServerEndpointConfig)baseConfig; - } - - // Decoders (favor provided config over annotation) - if (baseConfig != null && baseConfig.getDecoders() != null && baseConfig.getDecoders().size() > 0) - { - this.decoders = Collections.unmodifiableList(baseConfig.getDecoders()); - } - else - { - this.decoders = Collections.unmodifiableList(Arrays.asList(anno.decoders())); - } - - // AvailableEncoders (favor provided config over annotation) - if (baseConfig != null && baseConfig.getEncoders() != null && baseConfig.getEncoders().size() > 0) - { - this.encoders = Collections.unmodifiableList(baseConfig.getEncoders()); - } - else - { - this.encoders = Collections.unmodifiableList(Arrays.asList(anno.encoders())); - } - - // Sub Protocols (favor provided config over annotation) - if (baseServerConfig != null && baseServerConfig.getSubprotocols() != null && baseServerConfig.getSubprotocols().size() > 0) - { - this.subprotocols = Collections.unmodifiableList(baseServerConfig.getSubprotocols()); - } - else - { - this.subprotocols = Collections.unmodifiableList(Arrays.asList(anno.subprotocols())); - } - - // Path (favor provided config over annotation) - if (baseServerConfig != null && baseServerConfig.getPath() != null && baseServerConfig.getPath().length() > 0) - { - this.path = baseServerConfig.getPath(); - } - else - { - this.path = anno.value(); - } - - // supplied by init lifecycle - this.extensions = new ArrayList<>(); - // always what is passed in - this.endpointClass = endpointClass; - // UserProperties in annotation - this.userProperties = new HashMap<>(); - if (baseConfig != null && baseConfig.getUserProperties() != null && baseConfig.getUserProperties().size() > 0) - { - userProperties.putAll(baseConfig.getUserProperties()); - } - - ServerEndpointConfig.Configurator rawConfigurator = getConfigurator(baseServerConfig, anno); - - // Make sure all Configurators obtained are decorated - this.configurator = containerScope.getObjectFactory().decorate(rawConfigurator); - } - - private Configurator getConfigurator(ServerEndpointConfig baseServerConfig, ServerEndpoint anno) throws DeploymentException - { - Configurator ret = null; - - // Copy from base config - if (baseServerConfig != null) - { - ret = baseServerConfig.getConfigurator(); - } - - if (anno != null) - { - // Is this using the JSR356 spec/api default? - if (anno.configurator() == ServerEndpointConfig.Configurator.class) - { - // Return the spec default impl if one wasn't provided as part of the base config - if (ret == null) - return new ContainerDefaultConfigurator(); - else - return ret; - } - - // Instantiate the provided configurator - try - { - return anno.configurator().newInstance(); - } - catch (InstantiationException | IllegalAccessException e) - { - StringBuilder err = new StringBuilder(); - err.append("Unable to instantiate ServerEndpoint.configurator() of "); - err.append(anno.configurator().getName()); - err.append(" defined as annotation in "); - err.append(anno.getClass().getName()); - throw new DeploymentException(err.toString(), e); - } - } - - return ret; - } - - @Override - public ServerEndpointConfig.Configurator getConfigurator() - { - return configurator; - } - - @Override - public List> getDecoders() - { - return decoders; - } - - @Override - public List> getEncoders() - { - return encoders; - } - - @Override - public Class getEndpointClass() - { - return endpointClass; - } - - @Override - public List getExtensions() - { - return extensions; - } - - @Override - public String getPath() - { - return path; - } - - @Override - public List getSubprotocols() - { - return subprotocols; - } - - @Override - public Map getUserProperties() - { - return userProperties; - } - - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - AnnotatedServerEndpointConfig that = (AnnotatedServerEndpointConfig)o; - - if (endpointClass != null ? !endpointClass.equals(that.endpointClass) : that.endpointClass != null) - return false; - return path != null ? path.equals(that.path) : that.path == null; - } - - @Override - public int hashCode() - { - int result = endpointClass != null ? endpointClass.hashCode() : 0; - result = 31 * result + (path != null ? path.hashCode() : 0); - return result; - } - - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - builder.append("AnnotatedServerEndpointConfig[endpointClass="); - builder.append(endpointClass); - builder.append(",path="); - builder.append(path); - builder.append(",decoders="); - builder.append(decoders); - builder.append(",encoders="); - builder.append(encoders); - builder.append(",subprotocols="); - builder.append(subprotocols); - builder.append(",extensions="); - builder.append(extensions); - builder.append("]"); - return builder.toString(); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/DelegatedJavaxServletUpgradeRequest.java b/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/DelegatedJavaxServletUpgradeRequest.java deleted file mode 100644 index c6a2eccde05..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/DelegatedJavaxServletUpgradeRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.internal; - -import java.net.URI; -import java.security.Principal; - -import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; -import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; - -public class DelegatedJavaxServletUpgradeRequest implements UpgradeRequest -{ - private final ServletUpgradeRequest servletRequest; - - public DelegatedJavaxServletUpgradeRequest(ServletUpgradeRequest servletRequest) - { - this.servletRequest = servletRequest; - } - - @Override - public Principal getUserPrincipal() - { - return servletRequest.getUserPrincipal(); - } - - @Override - public URI getRequestURI() - { - return this.servletRequest.getRequestURI(); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/ServerEndpointConfigWrapper.java b/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/ServerEndpointConfigWrapper.java deleted file mode 100644 index ec650684ccf..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/ServerEndpointConfigWrapper.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.internal; - -import java.util.List; -import java.util.Map; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Extension; -import javax.websocket.server.ServerEndpointConfig; - -public abstract class ServerEndpointConfigWrapper implements ServerEndpointConfig -{ - private final ServerEndpointConfig delegate; - - public ServerEndpointConfigWrapper(ServerEndpointConfig delegate) - { - this.delegate = delegate; - } - - @Override - public List> getEncoders() - { - return delegate.getEncoders(); - } - - @Override - public List> getDecoders() - { - return delegate.getDecoders(); - } - - @Override - public Map getUserProperties() - { - return delegate.getUserProperties(); - } - - @Override - public Class getEndpointClass() - { - return delegate.getEndpointClass(); - } - - @Override - public String getPath() - { - return delegate.getPath(); - } - - @Override - public List getSubprotocols() - { - return delegate.getSubprotocols(); - } - - @Override - public List getExtensions() - { - return delegate.getExtensions(); - } - - @Override - public Configurator getConfigurator() - { - return delegate.getConfigurator(); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/UndefinedServerEndpointConfig.java b/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/UndefinedServerEndpointConfig.java deleted file mode 100644 index 8fdaf945db5..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/UndefinedServerEndpointConfig.java +++ /dev/null @@ -1,100 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.internal; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.Extension; -import javax.websocket.server.ServerEndpointConfig; - -import org.eclipse.jetty.websocket.javax.server.ContainerDefaultConfigurator; - -public class UndefinedServerEndpointConfig implements ServerEndpointConfig -{ - private final List> decoders; - private final List> encoders; - private final List extensions; - private final List subprotocols; - private final ServerEndpointConfig.Configurator configurator; - private final Class endpointClass; - private Map userProperties; - - public UndefinedServerEndpointConfig(Class endpointClass) - { - this.endpointClass = endpointClass; - this.decoders = new ArrayList<>(); - this.encoders = new ArrayList<>(); - this.subprotocols = new ArrayList<>(); - this.extensions = new ArrayList<>(); - this.userProperties = new HashMap<>(); - this.configurator = new ContainerDefaultConfigurator(); - } - - @Override - public List> getEncoders() - { - return encoders; - } - - @Override - public List> getDecoders() - { - return decoders; - } - - @Override - public Map getUserProperties() - { - return userProperties; - } - - @Override - public Class getEndpointClass() - { - return endpointClass; - } - - @Override - public String getPath() - { - throw new RuntimeException("Using an UndefinedServerEndpointConfig"); - } - - @Override - public List getSubprotocols() - { - return subprotocols; - } - - @Override - public List getExtensions() - { - return extensions; - } - - @Override - public ServerEndpointConfig.Configurator getConfigurator() - { - return configurator; - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/UpgradeResponseAdapter.java b/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/UpgradeResponseAdapter.java deleted file mode 100644 index 28ad2bfed2f..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/UpgradeResponseAdapter.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.internal; - -import java.util.List; - -import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.javax.common.UpgradeResponse; -import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; - -public class UpgradeResponseAdapter implements UpgradeResponse -{ - private final ServletUpgradeResponse servletResponse; - - public UpgradeResponseAdapter(ServletUpgradeResponse servletResponse) - { - this.servletResponse = servletResponse; - } - - @Override - public String getAcceptedSubProtocol() - { - return this.servletResponse.getAcceptedSubProtocol(); - } - - @Override - public List getExtensions() - { - return this.servletResponse.getExtensions(); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer deleted file mode 100644 index 86c5fef3534..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator b/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator deleted file mode 100644 index b925d25755c..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.jetty.websocket.javax.server.ContainerDefaultConfigurator \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration b/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration deleted file mode 100644 index 280be7ed694..00000000000 --- a/jetty-websocket/javax-websocket-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.jetty.websocket.javax.server.JavaxWebSocketConfiguration \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/DummyServerContainer.java b/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/DummyServerContainer.java deleted file mode 100644 index c39c5169bea..00000000000 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/DummyServerContainer.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server; - -import org.eclipse.jetty.websocket.servlet.WebSocketMapping; - -public class DummyServerContainer extends JavaxWebSocketServerContainer -{ - public DummyServerContainer() - { - super(new WebSocketMapping()); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/PathParamTest.java b/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/PathParamTest.java deleted file mode 100644 index 796ee693ca6..00000000000 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/PathParamTest.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server; - -import javax.websocket.DeploymentException; -import javax.websocket.OnMessage; -import javax.websocket.server.PathParam; -import javax.websocket.server.ServerEndpoint; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class PathParamTest -{ - private JavaxWebSocketServerContainer container; - - @BeforeEach - public void startContainer() throws Exception - { - container = new DummyServerContainer(); - container.start(); - } - - @AfterEach - public void stopContainer() throws Exception - { - container.stop(); - } - - @ServerEndpoint("/pathparam/basic/{name}") - public static class BasicPathParamSocket - { - @OnMessage - public void onMessage(String message, @PathParam("name") String name) - { - } - } - - @Test - public void testBasicPathParamSocket() throws DeploymentException - { - container.addEndpoint(BasicPathParamSocket.class); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionConfigurator.java b/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionConfigurator.java deleted file mode 100644 index 3e8850bd06b..00000000000 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionConfigurator.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.examples; - -import javax.servlet.http.HttpSession; -import javax.websocket.HandshakeResponse; -import javax.websocket.server.HandshakeRequest; -import javax.websocket.server.ServerEndpointConfig; - -public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator -{ - @Override - public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) - { - HttpSession httpSession = (HttpSession)request.getHttpSession(); - config.getUserProperties().put(HttpSession.class.getName(), httpSession); - } -} diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedSocket.java b/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedSocket.java deleted file mode 100644 index f09d8f17584..00000000000 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.examples; - -import javax.websocket.OnMessage; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/secured/socket", configurator = MyAuthedConfigurator.class) -public class MyAuthedSocket -{ - @OnMessage - public String onMessage(String msg) - { - // echo the message back to the remote - return msg; - } -} diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/StreamingEchoSocket.java b/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/StreamingEchoSocket.java deleted file mode 100644 index 3a4bf294c8e..00000000000 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/StreamingEchoSocket.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.server.examples; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.util.IO; - -@ServerEndpoint("/echo") -public class StreamingEchoSocket -{ - @OnMessage - public void onMessage(Session session, Reader reader) - { - try (Writer writer = session.getBasicRemote().getSendWriter()) - { - IO.copy(reader, writer); - } - catch (IOException e) - { - e.printStackTrace(); - } - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BadFrame.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BadFrame.java deleted file mode 100644 index 01c97b653da..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BadFrame.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; - -/** - * Allow Fuzzer / Generator to create bad frames for testing frame validation - */ -public class BadFrame extends Frame -{ - public BadFrame(byte opcode) - { - super(OpCode.CONTINUATION); - super.finRsvOp = (byte)((finRsvOp & 0xF0) | (opcode & 0x0F)); - // NOTE: Not setting Frame.Type intentionally - } - - @Override - public boolean isControlFrame() - { - return false; - } - - @Override - public boolean isDataFrame() - { - return false; - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CompletableFutureMethodHandle.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CompletableFutureMethodHandle.java deleted file mode 100644 index b6de20a4d97..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CompletableFutureMethodHandle.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -import java.lang.invoke.MethodHandle; -import java.lang.reflect.Method; -import java.util.concurrent.CompletableFuture; - -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils; -import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; - -public class CompletableFutureMethodHandle -{ - public static MethodHandle of(Class type, CompletableFuture future) - { - Method method = ReflectUtils.findMethod(CompletableFuture.class, "complete", type); - MethodHandle completeHandle = InvokerUtils.mutatedInvoker(CompletableFuture.class, method, new InvokerUtils.Arg(type)); - return completeHandle.bindTo(future); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DummyEndpoint.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DummyEndpoint.java deleted file mode 100644 index f9fdd858049..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DummyEndpoint.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.Session; - -public class DummyEndpoint extends Endpoint -{ - @Override - public void onOpen(Session session, EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java deleted file mode 100644 index 86828f5ac72..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java +++ /dev/null @@ -1,79 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -import java.io.IOException; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import javax.websocket.ClientEndpoint; -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.util.BlockingArrayQueue; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/") -@ClientEndpoint -public class EventSocket -{ - private static final Logger LOG = Log.getLogger(EventSocket.class); - - public Session session; - - public BlockingQueue messageQueue = new BlockingArrayQueue<>(); - public volatile Throwable error = null; - - public CountDownLatch openLatch = new CountDownLatch(1); - public CountDownLatch closeLatch = new CountDownLatch(1); - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - LOG.info("{} onOpen(): {}", toString(), session); - openLatch.countDown(); - } - - @OnMessage - public void onMessage(String message) throws IOException - { - LOG.info("{} onMessage(): {}", toString(), message); - messageQueue.offer(message); - } - - @OnClose - public void onClose(CloseReason reason) - { - LOG.info("{} onClose(): {}", toString(), reason); - closeLatch.countDown(); - } - - @OnError - public void onError(Throwable cause) - { - LOG.info("{} onError(): {}", toString(), cause); - error = cause; - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/MessageType.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/MessageType.java deleted file mode 100644 index 34caeb9aa58..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/MessageType.java +++ /dev/null @@ -1,26 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -public enum MessageType -{ - TEXT, - BINARY, - PONG -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Timeouts.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Timeouts.java deleted file mode 100644 index ebc16611ce4..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Timeouts.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -import java.util.concurrent.TimeUnit; - -public final class Timeouts -{ - public static final long CONNECT_MS = TimeUnit.SECONDS.toMillis(10); - public static final long OPEN_EVENT_MS = TimeUnit.SECONDS.toMillis(10); - public static final long CLOSE_EVENT_MS = TimeUnit.SECONDS.toMillis(10); -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java deleted file mode 100644 index 9e3995ed2b0..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests; - -import java.util.Map; -import java.util.TreeMap; - -import org.eclipse.jetty.http.HttpHeader; - -public class UpgradeUtils -{ - public static String generateUpgradeRequest(CharSequence requestPath, Map headers) - { - StringBuilder upgradeRequest = new StringBuilder(); - upgradeRequest.append("GET "); - upgradeRequest.append(requestPath == null ? "/" : requestPath); - upgradeRequest.append(" HTTP/1.1\r\n"); - headers.entrySet().stream().forEach(e -> - upgradeRequest.append(e.getKey()).append(": ").append(e.getValue()).append("\r\n")); - upgradeRequest.append("\r\n"); - return upgradeRequest.toString(); - } - - public static String generateUpgradeRequest() - { - return generateUpgradeRequest("/", newDefaultUpgradeRequestHeaders()); - } - - public static String generateUpgradeRequest(CharSequence requestPath) - { - return generateUpgradeRequest(requestPath, newDefaultUpgradeRequestHeaders()); - } - - public static Map newDefaultUpgradeRequestHeaders() - { - Map headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - headers.put("Host", "local"); - headers.put("Connection", "Upgrade"); - headers.put("Upgrade", "WebSocket"); - headers.put(HttpHeader.SEC_WEBSOCKET_KEY.asString(), "dGhlIHNhbXBsZSBub25jZQ=="); - headers.put(HttpHeader.ORIGIN.asString(), "ws://local/"); - // headers.put(WSConstants.SEC_WEBSOCKET_PROTOCOL, "echo"); - headers.put(HttpHeader.SEC_WEBSOCKET_VERSION.asString(), "13"); - return headers; - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/StaticText.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/StaticText.java deleted file mode 100644 index dba89bf9d42..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/StaticText.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.framehandlers; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.MessageHandler; - -public class StaticText extends MessageHandler -{ - private final String staticMessage; - - public StaticText(String message) - { - this.staticMessage = message; - } - - @Override - public void onText(String wholeMessage, Callback callback) - { - sendText(staticMessage, callback, false); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/WholeMessageEcho.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/WholeMessageEcho.java deleted file mode 100644 index 0c77a05ef72..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/WholeMessageEcho.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.framehandlers; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.MessageHandler; - -public class WholeMessageEcho extends MessageHandler -{ - @Override - public void onBinary(ByteBuffer wholeMessage, Callback callback) - { - sendBinary(wholeMessage, callback, false); - } - - @Override - public void onText(String wholeMessage, Callback callback) - { - sendText(wholeMessage, callback, false); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEndpointConfigTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEndpointConfigTest.java deleted file mode 100644 index e2d55956205..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEndpointConfigTest.java +++ /dev/null @@ -1,217 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.client; - -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import javax.websocket.ClientEndpoint; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.ContainerProvider; -import javax.websocket.Decoder; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; -import javax.websocket.HandshakeResponse; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; - -import org.eclipse.jetty.websocket.javax.tests.CoreServer; -import org.eclipse.jetty.websocket.javax.tests.coders.DateDecoder; -import org.eclipse.jetty.websocket.javax.tests.coders.TimeEncoder; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class AnnotatedEndpointConfigTest -{ - @ClientEndpoint( - subprotocols = {"chat", "echo-whole"}, - decoders = {DateDecoder.class}, - encoders = {TimeEncoder.class}, - configurator = AnnotatedEndpointConfigurator.class) - public static class AnnotatedEndpointClient - { - public Session session; - public EndpointConfig config; - - @OnOpen - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - this.config = config; - } - - @OnMessage(maxMessageSize = 111222) - public void onText(Date date) - { - /* do nothing - just a test of DateDecoder wiring */ - } - - @OnMessage(maxMessageSize = 333444) - public Date onBinary(ByteBuffer buf) - { - /* do nothing - just a test of TimeEncoder wiring */ - return null; - } - } - - public static class AnnotatedEndpointConfigurator extends ClientEndpointConfig.Configurator - { - @Override - public void afterResponse(HandshakeResponse hr) - { - hr.getHeaders().put("X-Test", Collections.singletonList("Extra")); - super.afterResponse(hr); - } - } - - private static CoreServer server; - private static ClientEndpointConfig ceconfig; - private static EndpointConfig config; - private static Session session; - private static AnnotatedEndpointClient clientEndpoint; - - @BeforeAll - public static void startEnv() throws Exception - { - // Server - server = new CoreServer(new CoreServer.EchoNegotiator()); - - // Start Server - server.start(); - - // Connect client - WebSocketContainer container = ContainerProvider.getWebSocketContainer(); - server.addBean(container); // allow to shutdown with server - clientEndpoint = new AnnotatedEndpointClient(); - - session = container.connectToServer(clientEndpoint, server.getWsUri()); - assertThat("Session", session, notNullValue()); - - config = clientEndpoint.config; - assertThat("EndpointConfig", config, notNullValue()); - assertThat("EndpointConfig", config, instanceOf(ClientEndpointConfig.class)); - - ceconfig = (ClientEndpointConfig)config; - assertThat("EndpointConfig", ceconfig, notNullValue()); - } - - @AfterAll - public static void stopEnv() - { - // Disconnect client - try - { - session.close(); - } - catch (Exception e) - { - e.printStackTrace(System.err); - } - - // Stop server - try - { - server.stop(); - } - catch (Exception e) - { - e.printStackTrace(System.err); - } - } - - @Test - public void testTextMax() throws Exception - { - assertThat("Client Text Max", - clientEndpoint.session.getMaxTextMessageBufferSize(), - is(111222)); - } - - @Test - public void testBinaryMax() throws Exception - { - assertThat("Client Binary Max", - clientEndpoint.session.getMaxBinaryMessageBufferSize(), - is(333444)); - } - - @Test - public void testSubProtocols() throws Exception - { - List subprotocols = ceconfig.getPreferredSubprotocols(); - assertThat("Client Preferred SubProtocols", subprotocols, contains("chat", "echo-whole")); - } - - @Test - public void testDecoders() throws Exception - { - List> decoders = config.getDecoders(); - assertThat("Decoders", decoders, notNullValue()); - - Class expectedClass = DateDecoder.class; - boolean hasExpectedDecoder = false; - for (Class decoder : decoders) - { - if (expectedClass.isAssignableFrom(decoder)) - { - hasExpectedDecoder = true; - } - } - - assertTrue(hasExpectedDecoder, "Client Decoders has " + expectedClass.getName()); - } - - @Test - public void testEncoders() throws Exception - { - List> encoders = config.getEncoders(); - assertThat("AvailableEncoders", encoders, notNullValue()); - - Class expectedClass = TimeEncoder.class; - boolean hasExpectedEncoder = false; - for (Class encoder : encoders) - { - if (expectedClass.isAssignableFrom(encoder)) - { - hasExpectedEncoder = true; - } - } - - assertTrue(hasExpectedEncoder, "Client AvailableEncoders has " + expectedClass.getName()); - } - - @Test - public void testConfigurator() throws Exception - { - ClientEndpointConfig ceconfig = (ClientEndpointConfig)config; - - assertThat("Client Configurator", ceconfig.getConfigurator(), instanceOf(AnnotatedEndpointConfigurator.class)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/WriteTimeoutTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/WriteTimeoutTest.java deleted file mode 100644 index 9aa3634c89f..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/WriteTimeoutTest.java +++ /dev/null @@ -1,124 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.client; - -import java.util.concurrent.TimeUnit; -import javax.websocket.ContainerProvider; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.WebSocketWriteTimeoutException; -import org.eclipse.jetty.websocket.javax.tests.LocalServer; -import org.eclipse.jetty.websocket.javax.tests.WSEndpointTracker; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class WriteTimeoutTest -{ - private static LocalServer server; - - @BeforeAll - public static void startServer() throws Exception - { - server = new LocalServer(); - server.start(); - server.getServerContainer().addEndpoint(LoggingSocket.class); - } - - @AfterAll - public static void stopServer() throws Exception - { - server.stop(); - } - - public static class ClientEndpoint extends WSEndpointTracker implements MessageHandler.Whole - { - @Override - public void onOpen(Session session, EndpointConfig config) - { - super.onOpen(session, config); - session.addMessageHandler(this); - } - - @Override - public void onMessage(String message) - { - super.onWsText(message); - } - } - - @Test - public void testEchoInstance() throws Exception - { - WebSocketContainer container = ContainerProvider.getWebSocketContainer(); - ClientEndpoint clientEndpoint = new ClientEndpoint(); - assertThat(clientEndpoint, Matchers.instanceOf(javax.websocket.Endpoint.class)); - Session session = container.connectToServer(clientEndpoint, server.getWsUri().resolve("/logSocket")); - - session.getAsyncRemote().setSendTimeout(5); - - session.setMaxTextMessageBufferSize(1000000); - String string = "xxxxxxx"; - StringBuilder sb = new StringBuilder(); - while (sb.length() < session.getMaxTextMessageBufferSize() - string.length()) - { - sb.append(string); - } - string = sb.toString(); - - while (session.isOpen()) - { - session.getAsyncRemote().sendText(string); - } - - assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); - assertThat(clientEndpoint.error.get(), instanceOf(WebSocketWriteTimeoutException.class)); - } - - @ServerEndpoint("/logSocket") - public static class LoggingSocket - { - private final Logger LOG = Log.getLogger(LoggingSocket.class); - - @OnMessage - public void onMessage(String msg) - { - LOG.debug("onMessage(): {}", msg); - } - - @OnError - public void onError(Throwable t) - { - LOG.debug("onError(): {}", t); - } - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSocket.java deleted file mode 100644 index 699f3d886fa..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSocket.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.client.samples; - -import javax.websocket.ClientEndpoint; -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.OnError; -import javax.websocket.OnOpen; -import javax.websocket.Session; - -import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; - -@ClientEndpoint -public class CloseReasonSocket extends WSEventTracker -{ - @OnOpen - public void onOpen(Session session) - { - super.onWsOpen(session); - } - - @OnError - public void onError(Throwable cause) - { - super.onWsError(cause); - } - - @OnClose - public void onClose(CloseReason reason) - { - addEvent("onClose(CloseReason)"); - super.onWsClose(reason); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionSocket.java deleted file mode 100644 index 7320791aab2..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionSocket.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.client.samples; - -import javax.websocket.ClientEndpoint; -import javax.websocket.OnClose; -import javax.websocket.OnError; -import javax.websocket.OnOpen; -import javax.websocket.Session; - -import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; - -@ClientEndpoint -public class CloseSessionSocket extends WSEventTracker -{ - @OnOpen - public void onOpen(Session session) - { - super.onWsOpen(session); - } - - @OnError - public void onError(Throwable cause) - { - super.onWsError(cause); - } - - @OnClose - public void onClose(Session session) - { - addEvent("onClose(Session)"); - super.onWsClose(null); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSocket.java deleted file mode 100644 index eea6fdf2fe7..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSocket.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.client.samples; - -import javax.websocket.ClientEndpoint; -import javax.websocket.OnClose; -import javax.websocket.OnError; -import javax.websocket.OnOpen; -import javax.websocket.Session; - -import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; - -@ClientEndpoint -public class CloseSocket extends WSEventTracker -{ - @OnOpen - public void onOpen(Session session) - { - super.onWsOpen(session); - } - - @OnError - public void onError(Throwable cause) - { - super.onWsError(cause); - } - - @OnClose - public void onClose() - { - addEvent("onClose()"); - super.onWsClose(null); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/IntSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/IntSocket.java deleted file mode 100644 index a78e3001855..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/IntSocket.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.client.samples; - -import java.io.IOException; -import javax.websocket.ClientEndpoint; -import javax.websocket.EncodeException; -import javax.websocket.OnMessage; -import javax.websocket.Session; - -import org.eclipse.jetty.websocket.javax.tests.coders.BadDualDecoder; - -@ClientEndpoint(decoders = BadDualDecoder.class) -public class IntSocket -{ - @OnMessage - public void onInt(Session session, int value) - { - try - { - session.getBasicRemote().sendObject(value); - } - catch (IOException | EncodeException e) - { - e.printStackTrace(); - } - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderTextTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderTextTest.java deleted file mode 100644 index e8aae36d6d8..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderTextTest.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.coders; - -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; - -/** - * Test various {@link javax.websocket.Encoder.Text} scenarios - */ -public class EncoderTextTest -{ - @Test - public void testQuotesEncoder_Direct() throws Exception - { - QuotesEncoder encoder = new QuotesEncoder(); - Quotes quotes = QuotesUtil.loadQuote("quotes-ben.txt"); - String result = encoder.encode(quotes); - assertThat("Result", result, containsString("Author: Benjamin Franklin\n")); - assertThat("Result", result, containsString("Quote: We must, ")); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ExtDecoder.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ExtDecoder.java deleted file mode 100644 index 30c05531baf..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ExtDecoder.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.coders; - -import javax.websocket.Decoder; - -/** - * Testing scenario of an extended Decoder interface - * - * @param the decoder type - */ -public interface ExtDecoder extends Decoder.Text -{ - void setId(String id); -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Fruit.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Fruit.java deleted file mode 100644 index b05e431d63f..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Fruit.java +++ /dev/null @@ -1,25 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.coders; - -public class Fruit -{ - public String name; - public String color; -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitTextEncoder.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitTextEncoder.java deleted file mode 100644 index ebf07ea0ded..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitTextEncoder.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.coders; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -public class FruitTextEncoder implements Encoder.Text -{ - @Override - public void destroy() - { - } - - @Override - public String encode(Fruit fruit) throws EncodeException - { - return String.format("%s|%s", fruit.name, fruit.color); - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Quotes.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Quotes.java deleted file mode 100644 index 8f674ee5d1f..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Quotes.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.coders; - -import java.util.ArrayList; -import java.util.List; - -public class Quotes -{ - private String author; - private List quotes = new ArrayList<>(); - - public void addQuote(String quote) - { - quotes.add(quote); - } - - public String getAuthor() - { - return author; - } - - public void setAuthor(String author) - { - this.author = author; - } - - public List getQuotes() - { - return quotes; - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeEncoder.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeEncoder.java deleted file mode 100644 index e482566b249..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeEncoder.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.coders; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -/** - * Encode Time - */ -public class TimeEncoder implements Encoder.Text -{ - private TimeZone GMT = TimeZone.getTimeZone("GMT"); - - @Override - public String encode(Date object) throws EncodeException - { - SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss z"); - format.setTimeZone(GMT); - return format.format(object); - } - - @Override - public void destroy() - { - // TODO: verify destroy called - } - - @Override - public void init(EndpointConfig config) - { - // TODO: verify init called - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/BaseMessageHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/BaseMessageHandler.java deleted file mode 100644 index 5adafbbe64c..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/BaseMessageHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import javax.websocket.MessageHandler; - -public class BaseMessageHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(String message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayPartialHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayPartialHandler.java deleted file mode 100644 index 41bff0c2092..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayPartialHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import javax.websocket.MessageHandler; - -public class ByteArrayPartialHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(byte[] partialMessage, boolean last) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayWholeHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayWholeHandler.java deleted file mode 100644 index 3ddb738bb6e..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayWholeHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import javax.websocket.MessageHandler; - -public class ByteArrayWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(byte[] message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferPartialHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferPartialHandler.java deleted file mode 100644 index c96eebd6756..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferPartialHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -public class ByteBufferPartialHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(ByteBuffer partialMessage, boolean last) - { - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferWholeHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferWholeHandler.java deleted file mode 100644 index d986b476e87..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferWholeHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -public class ByteBufferWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(ByteBuffer message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ComboMessageHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ComboMessageHandler.java deleted file mode 100644 index 68a3c9e53da..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ComboMessageHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -/** - * A particularly annoying type of MessageHandler. One defining 2 implementations. - */ -public class ComboMessageHandler implements MessageHandler.Whole, MessageHandler.Partial -{ - @Override - public void onMessage(ByteBuffer partialMessage, boolean last) - { - // TODO Auto-generated method stub - } - - @Override - public void onMessage(String message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ExtendedMessageHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ExtendedMessageHandler.java deleted file mode 100644 index fe4caf39cd9..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ExtendedMessageHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import java.nio.ByteBuffer; -import javax.websocket.MessageHandler; - -public class ExtendedMessageHandler extends BaseMessageHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(ByteBuffer partialMessage, boolean last) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/InputStreamWholeHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/InputStreamWholeHandler.java deleted file mode 100644 index b719aac63bf..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/InputStreamWholeHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import java.io.InputStream; -import javax.websocket.MessageHandler; - -public class InputStreamWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(InputStream stream) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/LongMessageHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/LongMessageHandler.java deleted file mode 100644 index 961a1ee0ffe..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/LongMessageHandler.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import javax.websocket.MessageHandler; - -public class LongMessageHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(Long message) - { - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ReaderWholeHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ReaderWholeHandler.java deleted file mode 100644 index 7964bd34f86..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ReaderWholeHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import java.io.Reader; -import javax.websocket.MessageHandler; - -public class ReaderWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(Reader reader) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringPartialHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringPartialHandler.java deleted file mode 100644 index 4697cab011c..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringPartialHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import javax.websocket.MessageHandler; - -public class StringPartialHandler implements MessageHandler.Partial -{ - @Override - public void onMessage(String partialMessage, boolean last) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringWholeHandler.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringWholeHandler.java deleted file mode 100644 index 28dadefe6a5..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringWholeHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.handlers; - -import javax.websocket.MessageHandler; - -public class StringWholeHandler implements MessageHandler.Whole -{ - @Override - public void onMessage(String message) - { - // TODO Auto-generated method stub - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/Quotes.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/Quotes.java deleted file mode 100644 index d1c6bf8d329..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/Quotes.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.quotes; - -import java.util.ArrayList; -import java.util.List; - -public class Quotes -{ - private String author; - private List quotes = new ArrayList<>(); - - public void addQuote(String quote) - { - quotes.add(quote); - } - - public String getAuthor() - { - return author; - } - - public void setAuthor(String author) - { - this.author = author; - } - - public List getQuotes() - { - return quotes; - } - - @Override - public String toString() - { - return String.format("Quotes[%s,quotes.size=%d]", author, quotes.size()); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoder.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoder.java deleted file mode 100644 index 4995673365c..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoder.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.quotes; - -import javax.websocket.EncodeException; -import javax.websocket.Encoder; -import javax.websocket.EndpointConfig; - -public class QuotesEncoder implements Encoder.Text -{ - @SuppressWarnings("RedundantThrows") - @Override - public String encode(Quotes q) throws EncodeException - { - StringBuilder buf = new StringBuilder(); - buf.append("Author: ").append(q.getAuthor()).append('\n'); - for (String quote : q.getQuotes()) - { - buf.append("Quote: ").append(quote).append('\n'); - } - return buf.toString(); - } - - @Override - public void destroy() - { - } - - @Override - public void init(EndpointConfig config) - { - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java deleted file mode 100644 index 954c53e7f43..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java +++ /dev/null @@ -1,128 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.websocket.core.CloseStatus; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.tests.Fuzzer; -import org.eclipse.jetty.websocket.javax.tests.UpgradeUtils; -import org.eclipse.jetty.websocket.javax.tests.WSServer; -import org.eclipse.jetty.websocket.javax.tests.coders.DateDecoder; -import org.eclipse.jetty.websocket.javax.tests.coders.TimeEncoder; -import org.eclipse.jetty.websocket.javax.tests.server.configs.EchoSocketConfigurator; -import org.eclipse.jetty.websocket.javax.tests.server.sockets.ConfiguredEchoSocket; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Example of an annotated echo server discovered via annotation scanning. - */ -public class AnnotatedServerEndpointTest -{ - private static WSServer server; - - @BeforeAll - public static void startServer() throws Exception - { - Path testdir = MavenTestingUtils.getTargetTestingPath(AnnotatedServerEndpointTest.class.getName()); - server = new WSServer(testdir, "app"); - server.createWebInf(); - server.copyEndpoint(ConfiguredEchoSocket.class); - server.copyClass(EchoSocketConfigurator.class); - server.copyClass(DateDecoder.class); - server.copyClass(TimeEncoder.class); - - server.start(); - - WebAppContext webapp = server.createWebAppContext(); - server.deployWebapp(webapp); - } - - @AfterAll - public static void stopServer() throws Exception - { - server.stop(); - } - - private void assertResponse(String message, String expectedText) throws Exception - { - Map upgradeRequest = UpgradeUtils.newDefaultUpgradeRequestHeaders(); - upgradeRequest.put(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), "echo"); - - List send = new ArrayList<>(); - send.add(new Frame(OpCode.TEXT).setPayload(message)); - send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - - List expect = new ArrayList<>(); - expect.add(new Frame(OpCode.TEXT).setPayload(expectedText)); - expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - - try (Fuzzer session = server.newNetworkFuzzer("/app/echo", upgradeRequest)) - { - session.sendFrames(send); - session.expect(expect); - } - } - - @Test - public void testConfigurator() throws Exception - { - assertResponse("configurator", EchoSocketConfigurator.class.getName()); - } - - @Test - public void testTextMax() throws Exception - { - assertResponse("text-max", "111,222"); - } - - @Test - public void testBinaryMax() throws Exception - { - assertResponse("binary-max", "333,444"); - } - - @Test - public void testDecoders() throws Exception - { - assertResponse("decoders", DateDecoder.class.getName()); - } - - @Test - public void testEncoders() throws Exception - { - assertResponse("encoders", TimeEncoder.class.getName()); - } - - @Test - public void testSubProtocols() throws Exception - { - assertResponse("subprotocols", "chat, echo, test"); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/EndpointViaConfigTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/EndpointViaConfigTest.java deleted file mode 100644 index 69f27b6c05d..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/EndpointViaConfigTest.java +++ /dev/null @@ -1,163 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server; - -import java.net.URI; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.websocket.DeploymentException; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; -import javax.websocket.server.ServerEndpointConfig; - -import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; -import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; -import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; -import org.eclipse.jetty.websocket.javax.tests.WSServer; -import org.eclipse.jetty.websocket.javax.tests.framehandlers.FrameHandlerTracker; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -/** - * Example of an {@link javax.websocket.Endpoint} extended echo server added programmatically via the - * {@link javax.websocket.server.ServerContainer#addEndpoint(javax.websocket.server.ServerEndpointConfig)} - */ -@ExtendWith(WorkDirExtension.class) -public class EndpointViaConfigTest -{ - private static final Logger LOG = Log.getLogger(EndpointViaConfigTest.class); - - @ServerEndpoint("/echo") - public static class BasicEchoEndpoint extends WSEventTracker implements MessageHandler.Whole - { - @Override - public void onMessage(String msg) - { - super.onWsText(msg); - // reply with echo - session.getAsyncRemote().sendText(msg); - } - - @OnOpen - public void onOpen(Session session, EndpointConfig config) - { - super.onWsOpen(session, config); - this.session.addMessageHandler(this); - } - } - - public static class BasicEchoEndpointConfigContextListener implements ServletContextListener - { - @Override - public void contextDestroyed(ServletContextEvent sce) - { - /* do nothing */ - } - - @Override - public void contextInitialized(ServletContextEvent sce) - { - javax.websocket.server.ServerContainer container = (javax.websocket.server.ServerContainer)sce.getServletContext() - .getAttribute(javax.websocket.server.ServerContainer.class.getName()); - if (container == null) - throw new IllegalStateException("No Websocket ServerContainer in " + sce.getServletContext()); - - // Build up a configuration with a specific path - String path = "/echo"; - ServerEndpointConfig.Builder builder = ServerEndpointConfig.Builder.create(BasicEchoEndpoint.class, path); - try - { - container.addEndpoint(builder.build()); - } - catch (DeploymentException e) - { - throw new RuntimeException("Unable to add endpoint via config file", e); - } - } - } - - public WorkDir testdir; - - @Test - public void testEcho() throws Exception - { - WSServer wsb = new WSServer(testdir.getPath(), "app"); - wsb.copyWebInf("basic-echo-endpoint-config-web.xml"); - // the endpoint (extends javax.websocket.Endpoint) - wsb.copyClass(BasicEchoEndpoint.class); - // the configuration (adds the endpoint) - wsb.copyClass(BasicEchoEndpointConfigContextListener.class); - - try - { - wsb.start(); - URI uri = wsb.getWsUri(); - - WebAppContext webapp = wsb.createWebAppContext(); - wsb.deployWebapp(webapp); - - WebSocketCoreClient client = new WebSocketCoreClient(); - try - { - client.start(); - FrameHandlerTracker clientSocket = new FrameHandlerTracker(); - Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echo")); - // wait for connect - FrameHandler.CoreSession coreSession = clientConnectFuture.get(5, TimeUnit.SECONDS); - try - { - coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload("Hello World"), Callback.NOOP, false); - - String incomingMessage = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS); - assertThat("Expected message", incomingMessage, is("Hello World")); - } - finally - { - coreSession.close(Callback.NOOP); - } - } - finally - { - client.stop(); - LOG.debug("Stopped - " + client); - } - } - finally - { - wsb.stop(); - LOG.debug("Stopped - " + wsb); - } - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeEchoContextListener.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeEchoContextListener.java deleted file mode 100644 index d037cb5f16e..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeEchoContextListener.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.websocket.server.ServerContainer; - -/** - * Configure the Large Text Message Size via the Container - */ -public class LargeEchoContextListener implements ServletContextListener -{ - @Override - public void contextDestroyed(ServletContextEvent sce) - { - /* do nothing */ - } - - @Override - public void contextInitialized(ServletContextEvent sce) - { - ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); - container.setDefaultMaxTextMessageBufferSize(128 * 1024); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PingPongTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PingPongTest.java deleted file mode 100644 index 1b44cdc23f0..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PingPongTest.java +++ /dev/null @@ -1,230 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server; - -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.time.Duration; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.websocket.DeploymentException; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.HandshakeResponse; -import javax.websocket.MessageHandler; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.PongMessage; -import javax.websocket.Session; -import javax.websocket.server.HandshakeRequest; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpoint; -import javax.websocket.server.ServerEndpointConfig; - -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; -import org.eclipse.jetty.websocket.javax.tests.Timeouts; -import org.eclipse.jetty.websocket.javax.tests.WSServer; -import org.eclipse.jetty.websocket.javax.tests.framehandlers.FrameHandlerTracker; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.junit.jupiter.api.Assertions.assertTimeout; - -public class PingPongTest -{ - @ServerEndpoint(value = "/pong-socket", configurator = PongContextListener.Config.class) - public static class PongSocket - { - private static final Logger LOG = Log.getLogger(PongSocket.class); - private String path = "?"; - private Session session; - - @OnOpen - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - this.path = (String)config.getUserProperties().get("path"); - } - - @OnMessage - public void onPong(PongMessage pong) - { - if (LOG.isDebugEnabled()) - LOG.debug("PongSocket.onPong(): PongMessage.appData={}", BufferUtil.toDetailString(pong.getApplicationData())); - byte[] buf = BufferUtil.toArray(pong.getApplicationData()); - String message = new String(buf, StandardCharsets.UTF_8); - this.session.getAsyncRemote().sendText("PongSocket.onPong(PongMessage)[" + path + "]:" + message); - } - } - - public static class PongMessageEndpoint extends Endpoint implements MessageHandler.Whole - { - private String path = "?"; - private Session session; - - @Override - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - this.session.addMessageHandler(this); - this.path = (String)config.getUserProperties().get("path"); - } - - @Override - public void onMessage(PongMessage pong) - { - byte[] buf = BufferUtil.toArray(pong.getApplicationData()); - String message = new String(buf, StandardCharsets.UTF_8); - this.session.getAsyncRemote().sendText("PongMessageEndpoint.onMessage(PongMessage):[" + path + "]:" + message); - } - } - - public static class PongContextListener implements ServletContextListener - { - public static class Config extends ServerEndpointConfig.Configurator - { - @Override - public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) - { - sec.getUserProperties().put("path", sec.getPath()); - super.modifyHandshake(sec, request, response); - } - } - - @Override - public void contextDestroyed(ServletContextEvent sce) - { - /* do nothing */ - } - - @Override - public void contextInitialized(ServletContextEvent sce) - { - ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); - try - { - ServerEndpointConfig.Configurator config = new Config(); - container.addEndpoint(ServerEndpointConfig.Builder.create(PongMessageEndpoint.class, "/pong").configurator(config).build()); - } - catch (DeploymentException e) - { - throw new RuntimeException("Unable to add endpoint directly", e); - } - } - } - - private static WSServer server; - private static WebSocketCoreClient client; - - @BeforeAll - public static void startServer() throws Exception - { - Path testdir = MavenTestingUtils.getTargetTestingPath(PingPongTest.class.getName()); - server = new WSServer(testdir, "app"); - server.copyWebInf("pong-config-web.xml"); - - server.copyClass(PongContextListener.class); - server.copyClass(PongMessageEndpoint.class); - server.copyClass(PongSocket.class); - - server.start(); - - WebAppContext webapp = server.createWebAppContext(); - server.deployWebapp(webapp); - } - - @BeforeAll - public static void startClient() throws Exception - { - client = new WebSocketCoreClient(); - client.start(); - } - - @AfterAll - public static void stopServer() throws Exception - { - server.stop(); - } - - private void assertEcho(String endpointPath, Consumer sendAction, String... expectedMsgs) throws Exception - { - FrameHandlerTracker clientSocket = new FrameHandlerTracker(); - URI toUri = server.getWsUri().resolve(endpointPath); - - // Connect - Future futureSession = client.connect(clientSocket, toUri); - FrameHandler.CoreSession coreSession = futureSession.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); - try - { - // Apply send action - sendAction.accept(coreSession); - - // Validate Responses - for (int i = 0; i < expectedMsgs.length; i++) - { - String pingMsg = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS); - assertThat("Expected message[" + i + "]", pingMsg, containsString(expectedMsgs[i])); - } - } - finally - { - coreSession.close(Callback.NOOP); - } - } - - @Test - public void testPongEndpoint() throws Exception - { - assertTimeout(Duration.ofMillis(6000), () -> - { - assertEcho("/app/pong", (session) -> - { - session.sendFrame(new Frame(OpCode.PONG).setPayload("hello"), Callback.NOOP, false); - }, "PongMessageEndpoint.onMessage(PongMessage):[/pong]:hello"); - }); - } - - @Test - public void testPongSocket() throws Exception - { - assertTimeout(Duration.ofMillis(6000), () -> - { - assertEcho("/app/pong-socket", (session) -> - { - session.sendFrame(new Frame(OpCode.PONG).setPayload("hello"), Callback.NOOP, false); - }, "PongSocket.onPong(PongMessage)[/pong-socket]:hello"); - }); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/TextStreamTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/TextStreamTest.java deleted file mode 100644 index 48f313e4a21..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/TextStreamTest.java +++ /dev/null @@ -1,169 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.CloseStatus; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.tests.DataUtils; -import org.eclipse.jetty.websocket.javax.tests.Fuzzer; -import org.eclipse.jetty.websocket.javax.tests.LocalServer; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -public class TextStreamTest -{ - private static final Logger LOG = Log.getLogger(TextStreamTest.class); - - private static LocalServer server; - private static ServerContainer container; - - @BeforeAll - public static void startServer() throws Exception - { - server = new LocalServer(); - server.start(); - container = server.getServerContainer(); - container.addEndpoint(ServerTextStreamer.class); - } - - @AfterAll - public static void stopServer() throws Exception - { - server.stop(); - } - - @Test - public void testWith1kMessage() throws Exception - { - testEcho(1024); - } - - private byte[] newData(int size) - { - @SuppressWarnings("SpellCheckingInspection") - byte[] pattern = "01234567890abcdefghijlklmopqrstuvwxyz".getBytes(StandardCharsets.UTF_8); - byte[] data = new byte[size]; - for (int i = 0; i < size; i++) - { - data[i] = pattern[i % pattern.length]; - } - return data; - } - - private void testEcho(int size) throws Exception - { - byte[] data = newData(size); - - List send = new ArrayList<>(); - send.add(new Frame(OpCode.TEXT).setPayload(ByteBuffer.wrap(data))); - send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - - ByteBuffer expectedMessage = DataUtils.copyOf(data); - List expect = new ArrayList<>(); - expect.add(new Frame(OpCode.TEXT).setPayload(expectedMessage)); - expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - - try (Fuzzer fuzzer = server.newNetworkFuzzer("/echo")) - { - fuzzer.sendBulk(send); - fuzzer.expect(expect); - } - } - - // TODO These tests incorrectly assumes no frame fragmentation. - // When message fragmentation is implemented in PartialStringMessageSink then update - // this test to check on the server side for no buffers larger than the maxTextMessageBufferSize. - - @Disabled - @Test - public void testAtMaxDefaultMessageBufferSize() throws Exception - { - testEcho(container.getDefaultMaxTextMessageBufferSize()); - } - - @Disabled - @Test - public void testLargerThenMaxDefaultMessageBufferSize() throws Exception - { - int size = container.getDefaultMaxTextMessageBufferSize() + 16; - byte[] data = newData(size); - - List send = new ArrayList<>(); - send.add(new Frame(OpCode.TEXT).setPayload(ByteBuffer.wrap(data))); - send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - - // make copy of raw data (to avoid client masking during send) - byte[] expectedData = new byte[data.length]; - System.arraycopy(data, 0, expectedData, 0, data.length); - - // Frames expected are influenced by container.getDefaultMaxTextMessageBufferSize setting - ByteBuffer frame1 = ByteBuffer.wrap(expectedData, 0, container.getDefaultMaxTextMessageBufferSize()); - ByteBuffer frame2 = ByteBuffer - .wrap(expectedData, container.getDefaultMaxTextMessageBufferSize(), size - container.getDefaultMaxTextMessageBufferSize()); - List expect = new ArrayList<>(); - expect.add(new Frame(OpCode.TEXT).setPayload(frame1).setFin(false)); - expect.add(new Frame(OpCode.CONTINUATION).setPayload(frame2).setFin(true)); - expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - - try (Fuzzer fuzzer = server.newNetworkFuzzer("/echo")) - { - fuzzer.sendBulk(send); - fuzzer.expect(expect); - } - } - - @ServerEndpoint("/echo") - public static class ServerTextStreamer - { - @OnMessage - public void echo(Session session, Reader input) throws IOException - { - char[] buffer = new char[128]; - try (Writer output = session.getBasicRemote().getSendWriter()) - { - long totalRead = 0; - int read; - while ((read = input.read(buffer)) >= 0) - { - totalRead += read; - output.write(buffer, 0, read); - } - - LOG.debug("{} total bytes read/write", totalRead); - } - } - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/configs/EchoSocketConfigurator.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/configs/EchoSocketConfigurator.java deleted file mode 100644 index c942111ceb5..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/configs/EchoSocketConfigurator.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.configs; - -import java.util.Collections; -import javax.websocket.HandshakeResponse; -import javax.websocket.server.HandshakeRequest; -import javax.websocket.server.ServerEndpointConfig; - -public class EchoSocketConfigurator extends ServerEndpointConfig.Configurator -{ - @Override - public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) - { - response.getHeaders().put("X-Test", Collections.singletonList("Extra")); - super.modifyHandshake(sec, request, response); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java deleted file mode 100644 index e85c5849f6c..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import java.nio.ByteBuffer; -import javax.websocket.OnMessage; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/basic") -public class BasicBinaryMessageByteBufferSocket extends TrackingSocket -{ - @OnMessage - public void onBinary(ByteBuffer data) - { - addEvent("onBinary(%s)", data); - dataLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSessionSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSessionSocket.java deleted file mode 100644 index 27034f9324c..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSessionSocket.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/close/reason/session") -public class BasicCloseReasonSessionSocket extends TrackingSocket -{ - @OnClose - public void onClose(CloseReason reason, Session session) - { - addEvent("onClose(%s,%s)", reason, session); - closeLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSocket.java deleted file mode 100644 index 56b6f1a3073..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/close/reason") -public class BasicCloseReasonSocket extends TrackingSocket -{ - @OnClose - public void onClose(CloseReason reason) - { - addEvent("onClose(%s)", reason); - closeLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSessionReasonSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSessionReasonSocket.java deleted file mode 100644 index cc8767536a0..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSessionReasonSocket.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/close/session/reason") -public class BasicCloseSessionReasonSocket extends TrackingSocket -{ - @OnClose - public void onClose(Session session, CloseReason reason) - { - addEvent("onClose(%s,%s)", session, reason); - closeLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSocket.java deleted file mode 100644 index 84bed88c3c1..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnClose; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/close") -public class BasicCloseSocket extends TrackingSocket -{ - @OnClose - public void onClose() - { - addEvent("onClose()"); - closeLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionSocket.java deleted file mode 100644 index 52e17d6b474..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/error/session") -public class BasicErrorSessionSocket extends TrackingSocket -{ - @OnError - public void onError(Session session) - { - addEvent("onError(%s)", session); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionThrowableSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionThrowableSocket.java deleted file mode 100644 index cc682c5c798..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionThrowableSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/error/session/throwable") -public class BasicErrorSessionThrowableSocket extends TrackingSocket -{ - @OnError - public void onError(Session session, Throwable t) - { - addEvent("onError(%s,%s)", session, t); - addError(t); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSocket.java deleted file mode 100644 index 48f44ce26c4..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSocket.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/error") -public class BasicErrorSocket extends TrackingSocket -{ - @OnError - public void onError() - { - addEvent("onError()"); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSessionSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSessionSocket.java deleted file mode 100644 index 968428465f1..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSessionSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/error/throwable/session") -public class BasicErrorThrowableSessionSocket extends TrackingSocket -{ - @OnError - public void onError(Throwable t, Session session) - { - addEvent("onError(%s,%s)", t, session); - addError(t); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSocket.java deleted file mode 100644 index 5e7271b6a7e..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/error/throwable") -public class BasicErrorThrowableSocket extends TrackingSocket -{ - @OnError - public void onError(Throwable t) - { - addEvent("onError(%s)", t); - addError(t); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSessionSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSessionSocket.java deleted file mode 100644 index 64bd5aaec40..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSessionSocket.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/basic") -public class BasicOpenCloseSessionSocket extends TrackingSocket -{ - @OnClose - public void onClose(CloseReason close, Session session) - { - addEvent("onClose(%s, %s)", close, session); - this.closeReason = close; - closeLatch.countDown(); - } - - @OnOpen - public void onOpen(Session session) - { - addEvent("onOpen(%s)", session); - openLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSocket.java deleted file mode 100644 index c72ede1d863..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSocket.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.CloseReason; -import javax.websocket.OnClose; -import javax.websocket.OnOpen; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/basic") -public class BasicOpenCloseSocket extends TrackingSocket -{ - @OnOpen - public void onOpen() - { - openLatch.countDown(); - } - - @OnClose - public void onClose(CloseReason close) - { - this.closeReason = close; - closeLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSessionSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSessionSocket.java deleted file mode 100644 index 27c70fc2f35..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSessionSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/onOpen/session") -public class BasicOpenSessionSocket extends TrackingSocket -{ - @OnOpen - public void onOpen(Session session) - { - openLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSocket.java deleted file mode 100644 index ee4a4f8f806..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSocket.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnOpen; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/onOpen") -public class BasicOpenSocket extends TrackingSocket -{ - @OnOpen - public void onOpen() - { - openLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicPongMessageSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicPongMessageSocket.java deleted file mode 100644 index ad4226e5410..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicPongMessageSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnMessage; -import javax.websocket.PongMessage; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/echo/pong") -public class BasicPongMessageSocket extends TrackingSocket -{ - @OnMessage - public void onPong(PongMessage pong) - { - addEvent("onPong(%s)", pong); - dataLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicTextMessageStringSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicTextMessageStringSocket.java deleted file mode 100644 index 7df2410c7cd..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicTextMessageStringSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnMessage; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/basic") -public class BasicTextMessageStringSocket extends TrackingSocket -{ - @OnMessage - public void onText(String message) - { - addEvent("onText(%s)", message); - dataLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ByteBufferSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ByteBufferSocket.java deleted file mode 100644 index 00a8cc4e787..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ByteBufferSocket.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import java.io.IOException; -import java.nio.ByteBuffer; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/binary/bytebuffer") -public class ByteBufferSocket -{ - private static final Logger LOG = Log.getLogger(ByteBufferSocket.class); - - @OnMessage - public String onByteBuffer(ByteBuffer bbuf) - { - return BufferUtil.toUTF8String(bbuf); - } - - @OnError - public void onError(Session session, Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java deleted file mode 100644 index 1e15bbe4db5..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; -import javax.websocket.Session; - -public class IdleTimeoutOnOpenEndpoint extends Endpoint implements MessageHandler.Whole -{ - private Session session; - - @Override - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - session.addMessageHandler(this); - session.setMaxIdleTimeout(500); - } - - @Override - public void onMessage(String message) - { - // echo message back (this is an indication of timeout failure) - session.getAsyncRemote().sendText(message); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenSocket.java deleted file mode 100644 index 5b9085c3a83..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenSocket.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.websocket.core.WebSocketTimeoutException; - -@ServerEndpoint(value = "/idle-onopen-socket") -public class IdleTimeoutOnOpenSocket -{ - @OnOpen - public void onOpen(Session session) - { - session.setMaxIdleTimeout(500); - } - - @OnMessage - public String onMessage(String msg) - { - return msg; - } - - @OnError - public void onError(Throwable cause) - { - if (!(cause instanceof WebSocketTimeoutException)) - throw new RuntimeException(cause); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidCloseIntSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidCloseIntSocket.java deleted file mode 100644 index 387b9d59257..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidCloseIntSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnClose; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/invalid") -public class InvalidCloseIntSocket extends TrackingSocket -{ - /** - * Invalid Close Method Declaration (parameter type int) - * - * @param statusCode the status code - */ - @OnClose - public void onClose(int statusCode) - { - closeLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorErrorSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorErrorSocket.java deleted file mode 100644 index abcf4bfd143..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorErrorSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/invalid") -public class InvalidErrorErrorSocket extends TrackingSocket -{ - /** - * Invalid Error Method Declaration (parameter type Error) - * - * @param error the error - */ - @OnError - public void onError(Error error) - { - /* no impl */ - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorIntSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorIntSocket.java deleted file mode 100644 index 76653db7754..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorIntSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnError; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/invalid") -public class InvalidErrorIntSocket extends TrackingSocket -{ - /** - * Invalid Error Method Declaration (parameter type int) - * - * @param errorCount the error count - */ - @OnError - public void onError(int errorCount) - { - /* no impl */ - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenCloseReasonSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenCloseReasonSocket.java deleted file mode 100644 index 6260376bec5..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenCloseReasonSocket.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.CloseReason; -import javax.websocket.OnOpen; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/invalid") -public class InvalidOpenCloseReasonSocket extends TrackingSocket -{ - /** - * Invalid Open Method Declaration (parameter type CloseReason) - * - * @param reason the close reason - */ - @OnOpen - public void onOpen(CloseReason reason) - { - openLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenIntSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenIntSocket.java deleted file mode 100644 index 7e561d62778..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenIntSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnOpen; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/invalid") -public class InvalidOpenIntSocket extends TrackingSocket -{ - /** - * Invalid Open Method Declaration (parameter type int) - * - * @param value the value - */ - @OnOpen - public void onOpen(int value) - { - openLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenSessionIntSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenSessionIntSocket.java deleted file mode 100644 index c120d239300..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenSessionIntSocket.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/invalid") -public class InvalidOpenSessionIntSocket extends TrackingSocket -{ - /** - * Invalid Open Method Declaration (parameter of type int) - * - * @param session the sesion - * @param count the count - */ - @OnOpen - public void onOpen(Session session, int count) - { - openLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/StatelessTextMessageStringSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/StatelessTextMessageStringSocket.java deleted file mode 100644 index 9bfb8f3ac77..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/StatelessTextMessageStringSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets; - -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/stateless") -public class StatelessTextMessageStringSocket extends TrackingSocket -{ - @OnMessage - public void onText(Session session, String message) - { - addEvent("onText(%s,%s)", session, message); - dataLatch.countDown(); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/binary/ByteBufferSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/binary/ByteBufferSocket.java deleted file mode 100644 index 09e98e3fe70..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/binary/ByteBufferSocket.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.binary; - -import java.io.IOException; -import java.nio.ByteBuffer; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/binary/bytebuffer") -public class ByteBufferSocket -{ - private static final Logger LOG = Log.getLogger(ByteBufferSocket.class); - - @OnMessage - public String onByteBuffer(ByteBuffer bbuf) - { - return BufferUtil.toUTF8String(bbuf); - } - - @OnError - public void onError(Session session, Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoEndpoint.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoEndpoint.java deleted file mode 100644 index bccc596dd9b..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoEndpoint.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; -import javax.websocket.Session; - -/** - * Example of websocket endpoint based on extending {@link Endpoint} - */ -public class BasicEchoEndpoint extends Endpoint implements MessageHandler.Whole -{ - private Session session; - - @Override - public void onMessage(String msg) - { - // reply with echo - session.getAsyncRemote().sendText(msg); - } - - @Override - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - this.session.addMessageHandler(this); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoSocket.java deleted file mode 100644 index 126606a1c45..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -/** - * Annotated echo socket - */ -@ServerEndpoint("/echo") -public class BasicEchoSocket -{ - @OnMessage - public void echo(Session session, String msg) - { - // reply with echo - session.getAsyncRemote().sendText(msg); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoAsyncTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoAsyncTextSocket.java deleted file mode 100644 index bdb96ad7eaf..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoAsyncTextSocket.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint("/echo/text/async") -public class EchoAsyncTextSocket -{ - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onText(String msg) - { - session.getAsyncRemote().sendText(msg); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnTextSocket.java deleted file mode 100644 index a387721a47a..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnTextSocket.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.OnMessage; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint("/echo/text/return") -public class EchoReturnTextSocket -{ - @OnMessage - public String onText(String msg) - { - return msg; - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java deleted file mode 100644 index 13c7b77c6cb..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint("/echo/text/async/stateless") -public class EchoStatelessAsyncTextSocket -{ - @OnMessage - public void onText(Session session, String msg) - { - session.getAsyncRemote().sendText(msg); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoConfiguredSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoConfiguredSocket.java deleted file mode 100644 index dfc80ada252..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoConfiguredSocket.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -/** - * Annotated echo socket - */ -@ServerEndpoint(value = "/echo/large") -public class LargeEchoConfiguredSocket -{ - private Session session; - - @OnOpen - public void open(Session session) - { - this.session = session; - this.session.setMaxTextMessageBufferSize(128 * 1024); - } - - @OnMessage - public void echo(String msg) - { - // reply with echo - session.getAsyncRemote().sendText(msg); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoDefaultSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoDefaultSocket.java deleted file mode 100644 index f9b6d6a6103..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoDefaultSocket.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; - -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; -import javax.websocket.server.ServerEndpoint; - -/** - * Annotated echo socket (default behavior as defined from {@link WebSocketContainer#setDefaultMaxTextMessageBufferSize(int)}) - */ -@ServerEndpoint(value = "/echo/large") -public class LargeEchoDefaultSocket -{ - @OnMessage - public void echo(Session session, String msg) - { - // reply with echo - session.getAsyncRemote().sendText(msg); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java deleted file mode 100644 index b0abaca0a51..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.idletimeout; - -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; -import javax.websocket.Session; - -public class OnOpenIdleTimeoutEndpoint extends Endpoint implements MessageHandler.Whole -{ - private Session session; - - @Override - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - session.addMessageHandler(this); - session.setMaxIdleTimeout(500); - } - - @Override - public void onMessage(String message) - { - // echo message back (this is an indication of timeout failure) - session.getAsyncRemote().sendText(message); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java deleted file mode 100644 index 44f3fe96cdc..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.idletimeout; - -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -@ServerEndpoint(value = "/idle-onopen-socket") -public class OnOpenIdleTimeoutSocket -{ - @OnOpen - public void onOpen(Session session) - { - session.setMaxIdleTimeout(500); - } - - @OnMessage - public String onMessage(String msg) - { - return msg; - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTrackingSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTrackingSocket.java deleted file mode 100644 index 1b5486cc118..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTrackingSocket.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.partial; - -import java.io.IOException; -import javax.websocket.OnMessage; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.websocket.javax.tests.server.sockets.TrackingSocket; - -@ServerEndpoint("/echo/partial/tracking") -public class PartialTrackingSocket extends TrackingSocket -{ - @OnMessage - public void onPartial(String msg, boolean fin) throws IOException - { - addEvent("onPartial(\"%s\",%b)", msg, fin); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextSocket.java deleted file mode 100644 index 23a4b068b91..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; - -import java.io.IOException; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/primitives/boolean") -public class BooleanTextSocket -{ - private static final Logger LOG = Log.getLogger(BooleanTextSocket.class); - - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onMessage(boolean b) throws IOException - { - String msg = Boolean.toString(b); - session.getAsyncRemote().sendText(msg); - } - - @OnError - public void onError(Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteTextSocket.java deleted file mode 100644 index 17b29b678f4..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; - -import java.io.IOException; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/primitives/byte") -public class ByteTextSocket -{ - private static final Logger LOG = Log.getLogger(ByteTextSocket.class); - - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onMessage(byte b) throws IOException - { - String msg = String.format("0x%02X", b); - session.getAsyncRemote().sendText(msg); - } - - @OnError - public void onError(Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharTextSocket.java deleted file mode 100644 index 3aa9b2ef244..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; - -import java.io.IOException; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/primitives/char") -public class CharTextSocket -{ - private static final Logger LOG = Log.getLogger(CharTextSocket.class); - - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onMessage(char c) throws IOException - { - String msg = Character.toString(c); - session.getAsyncRemote().sendText(msg); - } - - @OnError - public void onError(Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntTextSocket.java deleted file mode 100644 index 80908916767..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; - -import java.io.IOException; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/primitives/integer") -public class IntTextSocket -{ - private static final Logger LOG = Log.getLogger(IntTextSocket.class); - - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onMessage(int i) throws IOException - { - String msg = Integer.toString(i); - session.getAsyncRemote().sendText(msg); - } - - @OnError - public void onError(Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongTextSocket.java deleted file mode 100644 index 437419b1059..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; - -import java.io.IOException; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/primitives/long") -public class LongTextSocket -{ - private static final Logger LOG = Log.getLogger(LongTextSocket.class); - - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onMessage(long l) throws IOException - { - String msg = Long.toString(l); - session.getAsyncRemote().sendText(msg); - } - - @OnError - public void onError(Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortTextSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortTextSocket.java deleted file mode 100644 index 591181d380b..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; - -import java.io.IOException; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/primitives/short") -public class ShortTextSocket -{ - private static final Logger LOG = Log.getLogger(ShortTextSocket.class); - - private Session session; - - @OnOpen - public void onOpen(Session session) - { - this.session = session; - } - - @OnMessage - public void onMessage(short s) throws IOException - { - String msg = Short.toString(s); - session.getAsyncRemote().sendText(msg); - } - - @OnError - public void onError(Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/InputStreamSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/InputStreamSocket.java deleted file mode 100644 index 621b16d7190..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/InputStreamSocket.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.streaming; - -import java.io.IOException; -import java.io.InputStream; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/streaming/inputstream") -public class InputStreamSocket -{ - private static final Logger LOG = Log.getLogger(InputStreamSocket.class); - - @OnMessage - public String onInputStream(InputStream stream) throws IOException - { - return IO.toString(stream, StringUtil.__UTF8); - } - - @OnError - public void onError(Session session, Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderSocket.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderSocket.java deleted file mode 100644 index 7d6588f6ed0..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderSocket.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.javax.tests.server.sockets.streaming; - -import java.io.IOException; -import java.io.Reader; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ServerEndpoint("/echo/streaming/reader") -public class ReaderSocket -{ - private static final Logger LOG = Log.getLogger(ReaderSocket.class); - - @OnMessage - public String onReader(Reader reader) throws IOException - { - return IO.toString(reader); - } - - @OnError - public void onError(Session session, Throwable cause) throws IOException - { - LOG.warn("Error", cause); - session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); - } -} diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties deleted file mode 100644 index d078063b659..00000000000 --- a/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties +++ /dev/null @@ -1,43 +0,0 @@ -# -# -# ======================================================================== -# Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. -# ------------------------------------------------------------------------ -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# and Apache License v2.0 which accompanies this distribution. -# -# The Eclipse Public License is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# The Apache License v2.0 is available at -# http://www.opensource.org/licenses/apache2.0.php -# -# You may elect to redistribute this code under either of these licenses. -# ======================================================================== -# -# -# org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN -# org.eclipse.jetty.util.log.stderr.LONG=true -# org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG -# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG -# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG -# org.eclipse.jetty.client.LEVEL=DEBUG -# org.eclipse.jetty.io.LEVEL=DEBUG -# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO -# org.eclipse.jetty.websocket.LEVEL=DEBUG -# org.eclipse.jetty.websocket.core.internal.WebSocketCoreSessionsion.LEVEL=DEBUG -# org.eclipse.jetty.websocket.jsr356.tests.LEVEL=DEBUG -# org.eclipse.jetty.websocket.LEVEL=INFO -# org.eclipse.jetty.websocket.jsr356.messages.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.client.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.client.jsr356.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.server.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.server.jsr356.LEVEL=DEBUG -### Showing any unintended (ignored) errors from CompletionCallback -# org.eclipse.jetty.websocket.common.CompletionCallback.LEVEL=ALL -### Disabling intentional error out of RFCSocket -org.eclipse.jetty.websocket.tests.server.RFCSocket.LEVEL=OFF diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/keystore b/jetty-websocket/javax-websocket-tests/src/test/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/jetty-websocket/javax-websocket-tests/src/test/resources/keystore and /dev/null differ diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/module-info.java b/jetty-websocket/jetty-websocket-api/src/main/java/module-info.java deleted file mode 100644 index 77689102cb3..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/module-info.java +++ /dev/null @@ -1,25 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -module org.eclipse.jetty.websocket.jetty.api -{ - exports org.eclipse.jetty.websocket.api; - exports org.eclipse.jetty.websocket.api.annotations; - exports org.eclipse.jetty.websocket.api.extensions; - exports org.eclipse.jetty.websocket.api.util; -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java deleted file mode 100644 index 660cdae5a4c..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Exception to terminate the connection because it has received data within a frame payload that was not consistent with the requirements of that frame - * payload. (eg: not UTF-8 in a text frame, or a unexpected data seen by an extension) - * - * @see StatusCode#BAD_PAYLOAD - */ -@SuppressWarnings("serial") -public class BadPayloadException extends CloseException -{ - public BadPayloadException(String message) - { - super(StatusCode.BAD_PAYLOAD, message); - } - - public BadPayloadException(String message, Throwable t) - { - super(StatusCode.BAD_PAYLOAD, message, t); - } - - public BadPayloadException(Throwable t) - { - super(StatusCode.BAD_PAYLOAD, t); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BatchMode.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BatchMode.java deleted file mode 100644 index f3366ffecd1..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/BatchMode.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * The possible batch modes when enqueuing outgoing frames. - */ -public enum BatchMode -{ - /** - * Implementers are free to decide whether to send or not frames - * to the network layer. - */ - AUTO, - - /** - * Implementers must batch frames. - */ - ON, - - /** - * Implementers must send frames to the network layer. - */ - OFF; - - public static BatchMode max(BatchMode one, BatchMode two) - { - // Return the BatchMode that has the higher priority, where AUTO < ON < OFF. - return one.ordinal() < two.ordinal() ? two : one; - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java deleted file mode 100644 index 78a832690e3..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -@SuppressWarnings("serial") -public class CloseException extends WebSocketException -{ - private int statusCode; - - public CloseException(int closeCode, String message) - { - super(message); - this.statusCode = closeCode; - } - - public CloseException(int closeCode, String message, Throwable cause) - { - super(message, cause); - this.statusCode = closeCode; - } - - public CloseException(int closeCode, Throwable cause) - { - super(cause); - this.statusCode = closeCode; - } - - public int getStatusCode() - { - return statusCode; - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java deleted file mode 100644 index 0d6cbc3f8aa..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Indicating that the provided Class is not a valid WebSocket as defined by the API. - *

        - * A valid WebSocket should do one of the following: - *

          - *
        • Implement {@link WebSocketListener}
        • - *
        • Extend {@link WebSocketAdapter}
        • - *
        • Declare the {@link WebSocket @WebSocket} annotation on the type
        • - *
        - */ -@SuppressWarnings("serial") -public class InvalidWebSocketException extends WebSocketException -{ - public InvalidWebSocketException(String message) - { - super(message); - } - - public InvalidWebSocketException(String message, Throwable cause) - { - super(message, cause); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java deleted file mode 100644 index 38a025ca8d9..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Exception when a message is too large for the internal buffers occurs and should trigger a connection close. - * - * @see StatusCode#MESSAGE_TOO_LARGE - */ -@SuppressWarnings("serial") -public class MessageTooLargeException extends CloseException -{ - public MessageTooLargeException(String message) - { - super(StatusCode.MESSAGE_TOO_LARGE, message); - } - - public MessageTooLargeException(String message, Throwable t) - { - super(StatusCode.MESSAGE_TOO_LARGE, message, t); - } - - public MessageTooLargeException(Throwable t) - { - super(StatusCode.MESSAGE_TOO_LARGE, t); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java deleted file mode 100644 index bae86df2a1f..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Exception when a violation of policy occurs and should trigger a connection close. - * - * @see StatusCode#POLICY_VIOLATION - */ -@SuppressWarnings("serial") -public class PolicyViolationException extends CloseException -{ - public PolicyViolationException(String message) - { - super(StatusCode.POLICY_VIOLATION, message); - } - - public PolicyViolationException(String message, Throwable t) - { - super(StatusCode.POLICY_VIOLATION, message, t); - } - - public PolicyViolationException(Throwable t) - { - super(StatusCode.POLICY_VIOLATION, t); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java deleted file mode 100644 index 783680afdd4..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Per spec, a protocol error should result in a Close frame of status code 1002 (PROTOCOL_ERROR) - */ -@SuppressWarnings("serial") -public class ProtocolException extends CloseException -{ - public ProtocolException(String message) - { - super(StatusCode.PROTOCOL, message); - } - - public ProtocolException(String message, Throwable t) - { - super(StatusCode.PROTOCOL, message, t); - } - - public ProtocolException(Throwable t) - { - super(StatusCode.PROTOCOL, t); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java deleted file mode 100644 index ab90ce4aa72..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Connection suspend token - */ -public interface SuspendToken -{ - /** - * Resume a previously suspended connection. - */ - void resume(); -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java deleted file mode 100644 index df2ba5f3fd8..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Behavior for how the WebSocket should operate. - *

        - * This dictated by the RFC 6455 spec in various places, where certain behavior must be performed depending on - * operation as a CLIENT vs a SERVER - */ -public enum WebSocketBehavior -{ - CLIENT, - SERVER -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConstants.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConstants.java deleted file mode 100644 index d4808018e70..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConstants.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -public final class WebSocketConstants -{ - public static final String SEC_WEBSOCKET_EXTENSIONS = "Sec-WebSocket-Extensions"; - public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol"; - public static final String SEC_WEBSOCKET_VERSION = "Sec-WebSocket-Version"; - public static final String SEC_WEBSOCKET_ACCEPT = "Sec-WebSocket-Accept"; - public static final String SEC_WEBSOCKET_ORIGIN = "Sec-WebSocket-Origin"; - public static final String SEC_WEBSOCKET_KEY = "Sec-WebSocket-Key"; - public static final int SPEC_VERSION = 13; -} - diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java deleted file mode 100644 index 554ce6b91ce..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * A recoverable exception within the websocket framework. - */ -@SuppressWarnings("serial") -public class WebSocketException extends RuntimeException -{ - public WebSocketException() - { - super(); - } - - public WebSocketException(String message) - { - super(message); - } - - public WebSocketException(String message, Throwable cause) - { - super(message, cause); - } - - public WebSocketException(Throwable cause) - { - super(cause); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketFrameListener.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketFrameListener.java deleted file mode 100644 index 244d50359e1..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketFrameListener.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * WebSocket Frame Listener interface for incoming WebSocket frames. - */ -public interface WebSocketFrameListener extends WebSocketConnectionListener -{ - /** - * A WebSocket frame has been received. - * - * @param frame the immutable frame received - */ - void onWebSocketFrame(Frame frame); -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java deleted file mode 100644 index 04a0f23acd0..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Basic WebSocket Listener interface for incoming WebSocket message events. - */ -public interface WebSocketListener extends WebSocketConnectionListener -{ - /** - * A WebSocket binary frame has been received. - * - * @param payload the raw payload array received - * @param offset the offset in the payload array where the data starts - * @param len the length of bytes in the payload - */ - void onWebSocketBinary(byte[] payload, int offset, int len); - - /** - * A WebSocket Text frame was received. - * - * @param message the message - */ - void onWebSocketText(String message); -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPingPongListener.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPingPongListener.java deleted file mode 100644 index 505152ee0cf..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPingPongListener.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -import java.nio.ByteBuffer; - -/** - * WebSocket PING/PONG Listener interface for incoming WebSocket PING/PONG frames. - */ -public interface WebSocketPingPongListener extends WebSocketConnectionListener -{ - /** - * A WebSocket PING has been received. - * - * @param payload the ping payload - */ - void onWebSocketPing(ByteBuffer payload); - - /** - * A WebSocket PONG has been received. - * - * @param payload the pong payload - */ - void onWebSocketPong(ByteBuffer payload); -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketSessionListener.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketSessionListener.java deleted file mode 100644 index 0c96a81d332..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketSessionListener.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Interface for Listeners that are interested in knowing about the Session history. - */ -public interface WebSocketSessionListener -{ - default void onWebSocketSessionOpened(Session session) - { - } - - default void onWebSocketSessionClosed(Session session) - { - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketTimeoutException.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketTimeoutException.java deleted file mode 100644 index e261224d0bd..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketTimeoutException.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api; - -/** - * Exception thrown to indicate a connection I/O timeout. - */ -public class WebSocketTimeoutException extends WebSocketException -{ - private static final long serialVersionUID = -6145098200250676673L; - - public WebSocketTimeoutException(String message) - { - super(message); - } - - public WebSocketTimeoutException(String message, Throwable cause) - { - super(message, cause); - } - - public WebSocketTimeoutException(Throwable cause) - { - super(cause); - } -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java deleted file mode 100644 index 906a3e1bbe1..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.api.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.eclipse.jetty.websocket.api.Session; - -/** - * Annotation for tagging methods to receive connection open events. - *

        - * Only 1 acceptable method pattern for this annotation.
        - * Note: {@code methodName} can be any name you want to use. - *

          - *
        1. public void methodName({@link Session} session)
        2. - *
        - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(value = - {ElementType.METHOD}) -public @interface OnWebSocketConnect -{ - /* no config */ -} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/package-info.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/package-info.java deleted file mode 100644 index ffb39d65727..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket API : WebSocket POJO Annotations - */ -package org.eclipse.jetty.websocket.api.annotations; - diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/package-info.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/package-info.java deleted file mode 100644 index ac48e36919c..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket API : WebSocket Extension API - */ -package org.eclipse.jetty.websocket.api.extensions; - diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/package-info.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/package-info.java deleted file mode 100644 index 21a1848737c..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket API - */ -package org.eclipse.jetty.websocket.api; - diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/package-info.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/package-info.java deleted file mode 100644 index ff092082ba2..00000000000 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket API : Utility Classes - */ -package org.eclipse.jetty.websocket.api.util; - diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/module-info.java b/jetty-websocket/jetty-websocket-client/src/main/java/module-info.java deleted file mode 100644 index e414e1fd7b0..00000000000 --- a/jetty-websocket/jetty-websocket-client/src/main/java/module-info.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -module org.eclipse.jetty.websocket.jetty.client -{ - exports org.eclipse.jetty.websocket.client; - - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.websocket.jetty.api; - requires org.eclipse.jetty.websocket.core; - requires org.eclipse.jetty.websocket.jetty.common; -} diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/JettyUpgradeListener.java b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/JettyUpgradeListener.java deleted file mode 100644 index 482101db0c4..00000000000 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/JettyUpgradeListener.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.client; - -import org.eclipse.jetty.client.HttpRequest; -import org.eclipse.jetty.client.HttpResponse; - -public interface JettyUpgradeListener -{ - /** - * Event that triggers before the Handshake request is sent. - * - * @param request the request - */ - default void onHandshakeRequest(HttpRequest request) - { - } - - /** - * Event that triggers after the Handshake response has been received. - * - * @param request the request that was used - * @param response the response that was received - */ - default void onHandshakeResponse(HttpRequest request, HttpResponse response) - { - } -} diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/package-info.java b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/package-info.java deleted file mode 100644 index cf938f42bfe..00000000000 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket API :: Client - */ -package org.eclipse.jetty.websocket.client; - diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/module-info.java b/jetty-websocket/jetty-websocket-common/src/main/java/module-info.java deleted file mode 100644 index 710d1ddfed5..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/module-info.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.common.ExtensionConfigParser; - -module org.eclipse.jetty.websocket.jetty.common -{ - exports org.eclipse.jetty.websocket.common; - exports org.eclipse.jetty.websocket.common.invoke; - exports org.eclipse.jetty.websocket.common.message; - exports org.eclipse.jetty.websocket.common.util; - - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.websocket.core; - requires org.eclipse.jetty.websocket.jetty.api; - - provides ExtensionConfig.Parser with ExtensionConfigParser; -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/AbstractMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/AbstractMessageSink.java deleted file mode 100644 index 199747df1d7..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/AbstractMessageSink.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import java.lang.invoke.MethodHandle; -import java.util.concurrent.Executor; - -public abstract class AbstractMessageSink implements MessageSink -{ - protected final Executor executor; - protected final MethodHandle methodHandle; - - public AbstractMessageSink(Executor executor, MethodHandle methodHandle) - { - this.executor = executor; - this.methodHandle = methodHandle; - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CompletableFutureCallback.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CompletableFutureCallback.java deleted file mode 100644 index 2251e844b52..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CompletableFutureCallback.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import java.util.concurrent.CompletableFuture; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public class CompletableFutureCallback extends CompletableFuture implements Callback -{ - private static final Logger LOG = Log.getLogger(CompletableFutureCallback.class); - - @Override - public void failed(Throwable cause) - { - if (LOG.isDebugEnabled()) - LOG.debug("failed()", cause); - - completeExceptionally(cause); - } - - @Override - public void succeeded() - { - if (LOG.isDebugEnabled()) - LOG.debug("succeeded()"); - - complete(this); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/ExtensionConfigParser.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/ExtensionConfigParser.java deleted file mode 100644 index e3cb79e1b2c..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/ExtensionConfigParser.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import org.eclipse.jetty.websocket.core.ExtensionConfig; - -public class ExtensionConfigParser implements org.eclipse.jetty.websocket.api.extensions.ExtensionConfig.Parser -{ - /** - * Parse a single parameterized name. - * - * @param parameterizedName the parameterized name - * @return the ExtensionConfig - */ - @Override - public JettyExtensionConfig parse(String parameterizedName) - { - return new JettyExtensionConfig(ExtensionConfig.parse(parameterizedName)); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/FunctionCallException.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/FunctionCallException.java deleted file mode 100644 index 41397859ed9..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/FunctionCallException.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.jetty.websocket.core.WebSocketException; - -public class FunctionCallException extends WebSocketException -{ - public FunctionCallException(String message) - { - super(message); - } - - public FunctionCallException(String message, Throwable cause) - { - super(message, cause); - } - - public FunctionCallException(Throwable cause) - { - super(cause); - } - - public Throwable getInvokedCause() - { - Throwable cause = getCause(); - if (cause instanceof InvocationTargetException) - { - return cause.getCause(); - } - return cause; - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/MessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/MessageSink.java deleted file mode 100644 index e24d6441645..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/MessageSink.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.Frame; - -/** - * Sink consumer for messages (used for multiple frames with continuations, - * and also to allow for streaming APIs) - */ -public interface MessageSink -{ - /** - * Consume the frame payload to the message. - * - * @param frame the frame, its payload (and fin state) to append - * @param callback the callback for how the frame was consumed - */ - void accept(Frame frame, Callback callback); -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/invoke/InvalidSignatureException.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/invoke/InvalidSignatureException.java deleted file mode 100644 index dd1fe17884a..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/invoke/InvalidSignatureException.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.invoke; - -import java.lang.annotation.Annotation; -import java.lang.invoke.MethodType; -import java.lang.reflect.Method; - -import org.eclipse.jetty.websocket.api.InvalidWebSocketException; -import org.eclipse.jetty.websocket.common.util.ReflectUtils; - -@SuppressWarnings("serial") -public class InvalidSignatureException extends InvalidWebSocketException -{ - public static InvalidSignatureException build(Class pojo, Class methodAnnotationClass, Method method) - { - StringBuilder err = new StringBuilder(); - err.append("Invalid "); - if (methodAnnotationClass != null) - { - err.append("@"); - err.append(methodAnnotationClass.getSimpleName()); - err.append(' '); - } - if (pojo != null) - { - ReflectUtils.append(err, method); - } - else - { - ReflectUtils.append(err, pojo, method); - } - return new InvalidSignatureException(err.toString()); - } - - public static InvalidSignatureException build(MethodType expectedType, MethodType actualType) - { - StringBuilder err = new StringBuilder(); - err.append("Invalid MethodHandle "); - ReflectUtils.append(err, actualType); - err.append(" - expected "); - ReflectUtils.append(err, expectedType); - - return new InvalidSignatureException(err.toString()); - } - - public InvalidSignatureException(String message) - { - super(message); - } - - public InvalidSignatureException(String message, Throwable cause) - { - super(message, cause); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtils.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtils.java deleted file mode 100644 index f533f5c6ec7..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtils.java +++ /dev/null @@ -1,369 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.invoke; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.websocket.common.util.ReflectUtils; - -public class InvokerUtils -{ - public static class Arg - { - private final Class type; - private boolean required = false; - private String name; - - public Arg(Class type) - { - this.type = type; - } - - public Arg(Class type, String name) - { - this.type = type; - this.name = name; - } - - public String getName() - { - return name; - } - - public boolean matches(Arg other) - { - // If tags exist - if (this.name != null) - { - // They have to match - return (this.name.equals(other.name)); - } - - // Lastly, if types match, use em - return (this.type.isAssignableFrom(other.type)); - } - - public Arg required() - { - this.required = true; - return this; - } - - public Class getType() - { - return type; - } - - public boolean isRequired() - { - return required; - } - } - - public interface ParamIdentifier - { - Arg getParamArg(Method method, Class paramType, int idx); - } - - private static class ParamIdentity implements ParamIdentifier - { - @Override - public Arg getParamArg(Method method, Class paramType, int idx) - { - return new Arg(paramType); - } - } - - public static final ParamIdentifier PARAM_IDENTITY = new ParamIdentity(); - - /** - * Build a MethodHandle that can call the method with the calling args provided. - *

        - * Might need to drop calling args and/or reorder the calling args to fit - * the actual method being called. - *

        - * - * @param targetClass the target class for invocations of the resulting MethodHandle (also known as parameter 0) - * @param method the method to invoke - * @param callingArgs the calling arguments - * @return the MethodHandle for this set of CallingArgs - */ - public static MethodHandle mutatedInvoker(Class targetClass, Method method, Arg... callingArgs) - { - return mutatedInvoker(targetClass, method, PARAM_IDENTITY, callingArgs); - } - - /** - * Create a MethodHandle that performs the following layers - *
          - *
        1. {@link MethodHandles#permuteArguments(MethodHandle, MethodType, int...)} - moving calling Args around - * to fit actual actual method parameter arguments (in proper order), with remaining (unused) calling args afterwords
        2. - *
        3. {@link MethodHandles#dropArguments(MethodHandle, int, Class[])} - to drop the unused calling args
        4. - *
        5. {@link MethodHandle#invoke(Object...)} - to call the specific method
        6. - *
        - * - * @param targetClass the target class for invocations of the resulting MethodHandle (also known as parameter 0) - * @param method the method to invoke - * @param paramIdentifier the mechanism to identify parameters in method - * @param callingArgs the calling arguments - * @return the MethodHandle for this set of CallingArgs - * @throws RuntimeException when unable to fit Calling Args to Parameter Types - */ - public static MethodHandle mutatedInvoker(Class targetClass, Method method, ParamIdentifier paramIdentifier, Arg... callingArgs) - { - return mutatedInvoker(targetClass, true, method, paramIdentifier, callingArgs); - } - - private static MethodHandle mutatedInvoker(Class targetClass, boolean throwOnFailure, Method method, ParamIdentifier paramIdentifier, Arg... callingArgs) - { - Class[] parameterTypes = method.getParameterTypes(); - - // Build up Arg list representing the MethodHandle parameters - // ParamIdentifier is used to find named parameters (like javax.websocket's @PathParam declaration) - boolean hasNamedParamArgs = false; - Arg[] parameterArgs = new Arg[parameterTypes.length + 1]; - parameterArgs[0] = new Arg(targetClass); // first type is always the calling object instance type - for (int i = 0; i < parameterTypes.length; i++) - { - Arg arg = paramIdentifier.getParamArg(method, parameterTypes[i], i); - if (arg.name != null) - { - hasNamedParamArgs = true; - } - parameterArgs[i + 1] = arg; - } - - // Parameter to Calling Argument mapping. - // The size of this array must be the the same as the parameterArgs array (or bigger) - if (callingArgs.length < parameterTypes.length) - { - if (!throwOnFailure) - { - return null; - } - - StringBuilder err = new StringBuilder(); - err.append("Target method "); - ReflectUtils.append(err, targetClass, method); - err.append(" contains too many parameters and cannot be mapped to expected callable args "); - appendTypeList(err, callingArgs); - throw new InvalidSignatureException(err.toString()); - } - - // Establish MethodType for supplied calling args - boolean hasNamedCallingArgs = false; - List> cTypes = new ArrayList<>(); - cTypes.add(targetClass); // targetClass always at index 0 - for (int i = 0; i < callingArgs.length; i++) - { - Arg arg = callingArgs[i]; - if (arg.name != null) - { - hasNamedCallingArgs = true; - } - cTypes.add(arg.getType()); - } - MethodType callingType = MethodType.methodType(method.getReturnType(), cTypes); - - // Create low level MethodHandle - MethodHandles.Lookup lookup = MethodHandles.lookup(); - - try - { - // Low level invoker. - // We intentionally do not use lookup#unreflect() as that will incorrectly preserve - // the calling 'refc' type of where the method is declared, not the targetClass. - // That behavior of #unreflect() results in a MethodType referring to the - // base/abstract/interface where the method is declared, and not the targetClass - MethodType rawType = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); - MethodHandle methodHandle = lookup.findVirtual(targetClass, method.getName(), rawType); - - // If callingType and rawType are the same (and there's no named args), - // then there's no need to reorder / permute / drop args - if (!hasNamedCallingArgs && !hasNamedParamArgs && rawType.equals(callingType)) - { - return methodHandle; - } - - // If we reached this point, then we know that the callingType and rawType don't - // match, so we have to drop and/or permute(reorder) the arguments - - // Mapping will be same size as callingType (to compensate for targetClass at index 0) - int[] reorderMap = new int[callingType.parameterCount()]; - Arrays.fill(reorderMap, -1); - reorderMap[0] = 0; // always references targetClass - - // To track which callingArgs have been used. - // If a callingArg is used, it is used only once. - boolean[] usedCallingArgs = new boolean[callingArgs.length]; - Arrays.fill(usedCallingArgs, false); - - // Iterate through each parameterArg and attempt to find an associated callingArg - for (int pi = 1; pi < parameterArgs.length; pi++) - { - int ref = -1; - - // Find a reference to argument in callArgs - for (int ci = 0; ci < callingArgs.length; ci++) - { - if (!usedCallingArgs[ci] && parameterArgs[pi].matches(callingArgs[ci])) - { - ref = ci + 1; // add 1 to compensate for parameter 0 - usedCallingArgs[ci] = true; - break; - } - } - - // Didn't find an unused callingArg that fits this parameterArg - if (ref < 0) - { - if (!throwOnFailure) - { - return null; - } - - StringBuilder err = new StringBuilder(); - err.append("Invalid mapping of type ["); - err.append(parameterArgs[pi].getType()); - err.append("] in method "); - ReflectUtils.append(err, method); - err.append(" to calling args "); - appendTypeList(err, callingArgs); - - throw new InvalidSignatureException(err.toString()); - } - - reorderMap[pi] = ref; - } - - // Remaining unused callingArgs are to be placed at end of specified reorderMap - for (int ri = parameterArgs.length; ri <= reorderMap.length; ri++) - { - for (int uci = 0; uci < usedCallingArgs.length; uci++) - { - if (usedCallingArgs[uci] == false) - { - if (callingArgs[uci].required) - { - if (!throwOnFailure) - { - return null; - } - - StringBuilder err = new StringBuilder(); - err.append("Missing required argument ["); - err.append(callingArgs[uci].getType().getName()); - err.append("] in method "); - ReflectUtils.append(err, method); - - throw new InvalidSignatureException(err.toString()); - } - - reorderMap[ri] = uci + 1; // compensate for parameter 0 - ri++; - } - } - } - - // Drop excess (not mapped to a method parameter) calling args - int idxDrop = parameterArgs.length; - int dropLength = reorderMap.length - idxDrop; - if (dropLength > 0) - { - List> dropTypes = new ArrayList<>(); - for (int i = 0; i < dropLength; i++) - { - int callingTypeIdx = reorderMap[idxDrop + i]; - dropTypes.add(callingType.parameterType(callingTypeIdx)); - } - methodHandle = MethodHandles.dropArguments(methodHandle, idxDrop, dropTypes); - } - - // Reorder calling args to parameter args - methodHandle = MethodHandles.permuteArguments(methodHandle, callingType, reorderMap); - - // Return method handle - return methodHandle; - } - catch (IllegalAccessException | NoSuchMethodException e) - { - // TODO: throw Invalid Invoker Exception - if (!throwOnFailure) - { - return null; - } - - throw new InvalidSignatureException("Unable to obtain MethodHandle for " + method, e); - } - } - - /** - * Create an optional MethodHandle that performs the following layers. - *
          - *
        1. {@link MethodHandles#permuteArguments(MethodHandle, MethodType, int...)} - moving calling Args around - * to fit actual actual method parameter arguments (in proper order), with remaining (unused) calling args afterwords
        2. - *
        3. {@link MethodHandles#dropArguments(MethodHandle, int, Class[])} - to drop the unused calling args
        4. - *
        5. {@link MethodHandle#invoke(Object...)} - to call the specific method
        6. - *
        - * - * @param targetClass the target class for invocations of the resulting MethodHandle (also known as parameter 0) - * @param method the method to invoke - * @param paramIdentifier the mechanism to identify parameters in method - * @param callingArgs the calling arguments - * @return the MethodHandle for this set of CallingArgs, or null if not possible to create MethodHandle with CallingArgs to provided method - */ - public static MethodHandle optionalMutatedInvoker(Class targetClass, Method method, ParamIdentifier paramIdentifier, Arg... callingArgs) - { - return mutatedInvoker(targetClass, false, method, paramIdentifier, callingArgs); - } - - private static void appendTypeList(StringBuilder str, Arg[] args) - { - str.append("("); - boolean comma = false; - for (Arg arg : args) - { - if (comma) - str.append(", "); - str.append(arg.getType().getName()); - comma = true; - } - str.append(")"); - } - - private static void appendTypeList(StringBuilder str, Class[] types) - { - str.append("("); - boolean comma = false; - for (Class type : types) - { - if (comma) - str.append(", "); - str.append(type.getName()); - comma = true; - } - str.append(")"); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ByteArrayMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ByteArrayMessageSink.java deleted file mode 100644 index dc5b48a50f7..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ByteArrayMessageSink.java +++ /dev/null @@ -1,105 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.ByteArrayOutputStream; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.nio.ByteBuffer; -import java.util.Objects; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.common.AbstractMessageSink; -import org.eclipse.jetty.websocket.common.invoke.InvalidSignatureException; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; - -public class ByteArrayMessageSink extends AbstractMessageSink -{ - private static final byte[] EMPTY_BUFFER = new byte[0]; - private static final int BUFFER_SIZE = 65535; - private final Session session; - private ByteArrayOutputStream out; - private int size; - - public ByteArrayMessageSink(Executor executor, MethodHandle methodHandle, Session session) - { - super(executor, methodHandle); - this.session = session; - - Objects.requireNonNull(methodHandle, "MethodHandle"); - // byte[] buf, int offset, int length - MethodType onMessageType = MethodType.methodType(Void.TYPE, byte[].class, int.class, int.class); - if (methodHandle.type() != onMessageType) - { - throw InvalidSignatureException.build(onMessageType, methodHandle.type()); - } - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - size = size + payload.remaining(); - long maxMessageSize = session.getMaxBinaryMessageSize(); - if (maxMessageSize > 0 && size > maxMessageSize) - throw new MessageTooLargeException("Message size [" + size + "] exceeds maximum size [" + maxMessageSize + "]"); - - if (out == null) - out = new ByteArrayOutputStream(BUFFER_SIZE); - - BufferUtil.writeTo(payload, out); - } - - if (frame.isFin()) - { - if (out != null) - { - byte[] buf = out.toByteArray(); - methodHandle.invoke(buf, 0, buf.length); - } - else - methodHandle.invoke(EMPTY_BUFFER, 0, 0); - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - finally - { - if (frame.isFin()) - { - // reset - out = null; - size = 0; - } - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ByteBufferMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ByteBufferMessageSink.java deleted file mode 100644 index d40d7ea1e0a..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ByteBufferMessageSink.java +++ /dev/null @@ -1,102 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.ByteArrayOutputStream; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.nio.ByteBuffer; -import java.util.Objects; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.common.AbstractMessageSink; -import org.eclipse.jetty.websocket.common.invoke.InvalidSignatureException; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; - -public class ByteBufferMessageSink extends AbstractMessageSink -{ - private static final int BUFFER_SIZE = 65535; - private final Session session; - private ByteArrayOutputStream out; - private int size; - - public ByteBufferMessageSink(Executor executor, MethodHandle methodHandle, Session session) - { - super(executor, methodHandle); - this.session = session; - - // Validate onMessageMethod - Objects.requireNonNull(methodHandle, "MethodHandle"); - MethodType onMessageType = MethodType.methodType(Void.TYPE, ByteBuffer.class); - if (methodHandle.type() != onMessageType) - { - throw InvalidSignatureException.build(onMessageType, methodHandle.type()); - } - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - size = size + payload.remaining(); - long maxMessageSize = session.getMaxBinaryMessageSize(); - if (maxMessageSize > 0 && size > maxMessageSize) - throw new MessageTooLargeException("Message size [" + size + "] exceeds maximum size [" + maxMessageSize + "]"); - - if (out == null) - out = new ByteArrayOutputStream(BUFFER_SIZE); - - BufferUtil.writeTo(payload, out); - payload.position(payload.limit()); // consume buffer - } - - if (frame.isFin()) - { - if (out != null) - methodHandle.invoke(ByteBuffer.wrap(out.toByteArray())); - else - methodHandle.invoke(BufferUtil.EMPTY_BUFFER); - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - finally - { - if (frame.isFin()) - { - // reset - out = null; - size = 0; - } - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/CallbackBuffer.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/CallbackBuffer.java deleted file mode 100644 index 620c660a4cd..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/CallbackBuffer.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; - -public class CallbackBuffer -{ - public ByteBuffer buffer; - public Callback callback; - - public CallbackBuffer(Callback callback, ByteBuffer buffer) - { - this.callback = callback; - this.buffer = buffer; - } - - @Override - public String toString() - { - return String.format("CallbackBuffer[%s,%s]", BufferUtil.toDetailString(buffer), callback.getClass().getSimpleName()); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/InputStreamMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/InputStreamMessageSink.java deleted file mode 100644 index e84c289f2d0..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/InputStreamMessageSink.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.InputStream; -import java.lang.invoke.MethodHandle; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.websocket.common.MessageSink; -import org.eclipse.jetty.websocket.core.Frame; - -public class InputStreamMessageSink extends DispatchedMessageSink -{ - public InputStreamMessageSink(Executor executor, MethodHandle methodHandle) - { - super(executor, methodHandle); - } - - @Override - public MessageSink newSink(Frame frame) - { - return new MessageInputStream(); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java deleted file mode 100644 index 8f1ee6bea29..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java +++ /dev/null @@ -1,227 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.nio.ByteBuffer; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.common.MessageSink; -import org.eclipse.jetty.websocket.core.Frame; - -/** - * Support class for reading a WebSocket BINARY message via a InputStream. - *

        - * An InputStream that can access a queue of ByteBuffer payloads, along with expected InputStream blocking behavior. - *

        - */ -public class MessageInputStream extends InputStream implements MessageSink -{ - private static final Logger LOG = Log.getLogger(MessageInputStream.class); - private static final CallbackBuffer EOF = new CallbackBuffer(Callback.NOOP, ByteBuffer.allocate(0).asReadOnlyBuffer()); - private final Deque buffers = new ArrayDeque<>(2); - private final AtomicBoolean closed = new AtomicBoolean(false); - private CallbackBuffer activeFrame; - - @Override - public void accept(Frame frame, Callback callback) - { - if (LOG.isDebugEnabled()) - LOG.debug("accepting {}", frame); - - // If closed, we should just toss incoming payloads into the bit bucket. - if (closed.get()) - { - callback.failed(new IOException("Already Closed")); - return; - } - - if (!frame.hasPayload() && !frame.isFin()) - { - callback.succeeded(); - return; - } - - synchronized (buffers) - { - boolean notify = false; - if (frame.hasPayload()) - { - buffers.offer(new CallbackBuffer(callback, frame.getPayload())); - notify = true; - } - else - { - // We cannot wake up blocking read for a zero length frame. - callback.succeeded(); - } - - if (frame.isFin()) - { - buffers.offer(EOF); - notify = true; - } - - if (notify) - { - // notify other thread - buffers.notify(); - } - } - } - - @Override - public void close() throws IOException - { - if (LOG.isDebugEnabled()) - LOG.debug("close()"); - - if (closed.compareAndSet(false, true)) - { - synchronized (buffers) - { - buffers.offer(EOF); - buffers.notify(); - } - } - super.close(); - } - - public CallbackBuffer getActiveFrame() throws InterruptedIOException - { - if (activeFrame == null) - { - // sync and poll queue - CallbackBuffer result; - synchronized (buffers) - { - try - { - while ((result = buffers.poll()) == null) - { - // TODO: handle read timeout here? - buffers.wait(); - } - } - catch (InterruptedException e) - { - shutdown(); - throw new InterruptedIOException(); - } - } - activeFrame = result; - } - - return activeFrame; - } - - private void shutdown() - { - if (LOG.isDebugEnabled()) - LOG.debug("shutdown()"); - synchronized (buffers) - { - closed.set(true); - Throwable cause = new IOException("Shutdown"); - for (CallbackBuffer buffer : buffers) - { - buffer.callback.failed(cause); - } - // Removed buffers that may have remained in the queue. - buffers.clear(); - } - } - - @Override - public void mark(int readlimit) - { - // Not supported. - } - - @Override - public boolean markSupported() - { - return false; - } - - @Override - public int read() throws IOException - { - byte[] buf = new byte[1]; - while (true) - { - int len = read(buf, 0, 1); - if (len < 0) // EOF - return -1; - if (len > 0) // did read something - return buf[0]; - // reading nothing (len == 0) tries again - } - } - - @Override - public int read(final byte[] b, final int off, final int len) throws IOException - { - if (closed.get()) - { - if (LOG.isDebugEnabled()) - LOG.debug("Stream closed"); - return -1; - } - - CallbackBuffer result = getActiveFrame(); - - if (LOG.isDebugEnabled()) - LOG.debug("result = {}", result); - - if (result == EOF) - { - if (LOG.isDebugEnabled()) - LOG.debug("Read EOF"); - shutdown(); - return -1; - } - - // We have content - int fillLen = Math.min(result.buffer.remaining(), len); - result.buffer.get(b, off, fillLen); - - if (!result.buffer.hasRemaining()) - { - activeFrame = null; - result.callback.succeeded(); - } - - // return number of bytes actually copied into buffer - return fillLen; - } - - @Override - public void reset() throws IOException - { - throw new IOException("reset() not supported"); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java deleted file mode 100644 index 0275496e9db..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java +++ /dev/null @@ -1,218 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; - -/** - * Support for writing a single WebSocket BINARY message via a {@link OutputStream} - */ -public class MessageOutputStream extends OutputStream -{ - private static final Logger LOG = Log.getLogger(MessageOutputStream.class); - - private final FrameHandler.CoreSession coreSession; - private final ByteBufferPool bufferPool; - private final SharedBlockingCallback blocker; - private long frameCount; - private long bytesSent; - private Frame frame; - private ByteBuffer buffer; // Kept in fill mode - private Callback callback; - private boolean closed; - - public MessageOutputStream(FrameHandler.CoreSession coreSession, int bufferSize, ByteBufferPool bufferPool) - { - this.coreSession = coreSession; - this.bufferPool = bufferPool; - this.blocker = new SharedBlockingCallback(); - this.buffer = bufferPool.acquire(bufferSize, true); - BufferUtil.flipToFill(buffer); - this.frame = new Frame(OpCode.BINARY); - } - - @Override - public void write(byte[] bytes, int off, int len) throws IOException - { - try - { - send(bytes, off, len); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - @Override - public void write(int b) throws IOException - { - try - { - send(new byte[]{(byte)b}, 0, 1); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - @Override - public void flush() throws IOException - { - try - { - flush(false); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - private void flush(boolean fin) throws IOException - { - synchronized (this) - { - if (closed) - throw new IOException("Stream is closed"); - - closed = fin; - - BufferUtil.flipToFlush(buffer, 0); - frame.setPayload(buffer); - frame.setFin(fin); - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.sendFrame(frame, b, false); - b.block(); - assert buffer.remaining() == 0; - } - finally - { - BufferUtil.clearToFill(buffer); - } - - ++frameCount; - // Any flush after the first will be a CONTINUATION frame. - frame = new Frame(OpCode.CONTINUATION); - } - } - - private void send(byte[] bytes, final int offset, final int length) throws IOException - { - synchronized (this) - { - if (closed) - throw new IOException("Stream is closed"); - - int remaining = length; - int off = offset; - int space = buffer.remaining(); - while (remaining > 0) - { - // There may be no space available, we want - // to handle correctly when space == 0. - int size = Math.min(space, remaining); - buffer.put(bytes, off, size); - off += size; - remaining -= size; - space = buffer.remaining(); - if (space == 0) - { - flush(false); - space = buffer.remaining(); - } - } - bytesSent += length; - } - } - - @Override - public void close() throws IOException - { - try - { - flush(true); - bufferPool.release(buffer); - if (LOG.isDebugEnabled()) - LOG.debug("Stream closed, {} frames ({} bytes) sent", frameCount, bytesSent); - // Notify without holding locks. - notifySuccess(); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - public void setCallback(Callback callback) - { - synchronized (this) - { - this.callback = callback; - } - } - - private void notifySuccess() - { - Callback callback; - synchronized (this) - { - callback = this.callback; - } - if (callback != null) - { - callback.succeeded(); - } - } - - private void notifyFailure(Throwable failure) - { - Callback callback; - synchronized (this) - { - callback = this.callback; - } - if (callback != null) - { - callback.failed(failure); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageReader.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageReader.java deleted file mode 100644 index 81322fd218c..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageReader.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.common.MessageSink; -import org.eclipse.jetty.websocket.core.Frame; - -/** - * Support class for reading a (single) WebSocket TEXT message via a Reader. - *

        - * In compliance to the WebSocket spec, this reader always uses the {@link StandardCharsets#UTF_8}. - */ -public class MessageReader extends InputStreamReader implements MessageSink -{ - private final MessageInputStream stream; - - public MessageReader(MessageInputStream stream) - { - super(stream, StandardCharsets.UTF_8); - this.stream = stream; - } - - @Override - public void accept(Frame frame, Callback callback) - { - this.stream.accept(frame, callback); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageWriter.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageWriter.java deleted file mode 100644 index 534a7194039..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageWriter.java +++ /dev/null @@ -1,226 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.IOException; -import java.io.Writer; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; - -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * Support for writing a single WebSocket TEXT message via a {@link Writer} - *

        - * Note: Per WebSocket spec, all WebSocket TEXT messages must be encoded in UTF-8 - */ -public class MessageWriter extends Writer -{ - private static final Logger LOG = Log.getLogger(MessageWriter.class); - - private final CharsetEncoder utf8Encoder = UTF_8.newEncoder() - .onUnmappableCharacter(CodingErrorAction.REPORT) - .onMalformedInput(CodingErrorAction.REPORT); - - private final FrameHandler.CoreSession coreSession; - private final SharedBlockingCallback blocker; - private long frameCount; - private Frame frame; - private CharBuffer buffer; - private Callback callback; - private boolean closed; - - public MessageWriter(FrameHandler.CoreSession coreSession, int bufferSize) - { - this.coreSession = coreSession; - this.blocker = new SharedBlockingCallback(); - this.buffer = CharBuffer.allocate(bufferSize); - this.frame = new Frame(OpCode.TEXT); - } - - @Override - public void write(char[] chars, int off, int len) throws IOException - { - try - { - send(chars, off, len); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - @Override - public void write(int c) throws IOException - { - try - { - send(new char[]{(char)c}, 0, 1); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - @Override - public void flush() throws IOException - { - try - { - flush(false); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - private void flush(boolean fin) throws IOException - { - synchronized (this) - { - if (closed) - throw new IOException("Stream is closed"); - - closed = fin; - - buffer.flip(); - ByteBuffer payload = utf8Encoder.encode(buffer); - buffer.flip(); - - if (LOG.isDebugEnabled()) - LOG.debug("flush({}): {}", fin, BufferUtil.toDetailString(payload)); - frame.setPayload(payload); - frame.setFin(fin); - - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.sendFrame(frame, b, false); - b.block(); - } - - ++frameCount; - // Any flush after the first will be a CONTINUATION frame. - frame = new Frame(OpCode.CONTINUATION); - } - } - - private void send(char[] chars, int offset, int length) throws IOException - { - synchronized (this) - { - if (closed) - throw new IOException("Stream is closed"); - - CharBuffer source = CharBuffer.wrap(chars, offset, length); - - int remaining = length; - - while (remaining > 0) - { - int read = source.read(buffer); - if (read == -1) - { - return; - } - - remaining -= read; - - if (remaining > 0) - { - // If we could not write everything, it means - // that the buffer was full, so flush it. - flush(false); - } - } - } - } - - @Override - public void close() throws IOException - { - try - { - flush(true); - if (LOG.isDebugEnabled()) - LOG.debug("Stream closed, {} frames sent", frameCount); - // Notify without holding locks. - notifySuccess(); - } - catch (Throwable x) - { - // Notify without holding locks. - notifyFailure(x); - throw x; - } - } - - public void setCallback(Callback callback) - { - synchronized (this) - { - this.callback = callback; - } - } - - private void notifySuccess() - { - Callback callback; - synchronized (this) - { - callback = this.callback; - } - if (callback != null) - { - callback.succeeded(); - } - } - - private void notifyFailure(Throwable failure) - { - Callback callback; - synchronized (this) - { - callback = this.callback; - } - if (callback != null) - { - callback.failed(failure); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/PartialBinaryMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/PartialBinaryMessageSink.java deleted file mode 100644 index 2077fd2f88c..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/PartialBinaryMessageSink.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.lang.invoke.MethodHandle; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.common.AbstractMessageSink; -import org.eclipse.jetty.websocket.core.Frame; - -public class PartialBinaryMessageSink extends AbstractMessageSink -{ - public PartialBinaryMessageSink(Executor executor, MethodHandle methodHandle) - { - super(executor, methodHandle); - } - - @Override - public void accept(Frame frame, Callback callback) - { - try - { - methodHandle.invoke(frame.getPayload(), frame.isFin()); - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/PartialTextMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/PartialTextMessageSink.java deleted file mode 100644 index 3581795fc4b..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/PartialTextMessageSink.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.lang.invoke.MethodHandle; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.websocket.common.AbstractMessageSink; -import org.eclipse.jetty.websocket.core.Frame; - -public class PartialTextMessageSink extends AbstractMessageSink -{ - private final Utf8StringBuilder utf8Partial; - - public PartialTextMessageSink(Executor executor, MethodHandle methodHandle) - { - super(executor, methodHandle); - this.utf8Partial = new Utf8StringBuilder(); - } - - @Override - public void accept(Frame frame, Callback callback) - { - utf8Partial.append(frame.getPayload()); - String partialText = utf8Partial.takePartialString(); - try - { - methodHandle.invoke(partialText, frame.isFin()); - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - finally - { - if (frame.isFin()) - utf8Partial.reset(); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ReaderMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ReaderMessageSink.java deleted file mode 100644 index 1cfda8afdab..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/ReaderMessageSink.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.io.Reader; -import java.lang.invoke.MethodHandle; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.websocket.core.Frame; - -public class ReaderMessageSink extends DispatchedMessageSink -{ - public ReaderMessageSink(Executor executor, MethodHandle methodHandle) - { - super(executor, methodHandle); - } - - @Override - public MessageReader newSink(Frame frame) - { - return new MessageReader(new MessageInputStream()); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/StringMessageSink.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/StringMessageSink.java deleted file mode 100644 index 8d2780bd5d2..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/StringMessageSink.java +++ /dev/null @@ -1,105 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.message; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.nio.ByteBuffer; -import java.util.Objects; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.common.AbstractMessageSink; -import org.eclipse.jetty.websocket.common.invoke.InvalidSignatureException; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; - -public class StringMessageSink extends AbstractMessageSink -{ - private static final Logger LOG = Log.getLogger(StringMessageSink.class); - private final Session session; - private Utf8StringBuilder utf; - private int size = 0; - - public StringMessageSink(Executor executor, MethodHandle methodHandle, Session session) - { - super(executor, methodHandle); - this.session = session; - - // Validate onMessageMethod - Objects.requireNonNull(methodHandle, "MethodHandle"); - MethodType onMessageType = MethodType.methodType(Void.TYPE, String.class); - if (methodHandle.type() != onMessageType) - { - throw InvalidSignatureException.build(onMessageType, methodHandle.type()); - } - - this.size = 0; - } - - @SuppressWarnings("Duplicates") - @Override - public void accept(Frame frame, Callback callback) - { - try - { - if (frame.hasPayload()) - { - ByteBuffer payload = frame.getPayload(); - size = size + payload.remaining(); - long maxMessageSize = session.getMaxTextMessageSize(); - if (maxMessageSize > 0 && size > maxMessageSize) - throw new MessageTooLargeException("Message size [" + size + "] exceeds maximum size [" + maxMessageSize + "]"); - - if (utf == null) - utf = new Utf8StringBuilder(1024); - - if (LOG.isDebugEnabled()) - LOG.debug("Raw Payload {}", BufferUtil.toDetailString(payload)); - - // allow for fast fail of BAD utf (incomplete utf will trigger on messageComplete) - utf.append(payload); - } - - if (frame.isFin()) - { - // notify event - if (utf != null) - methodHandle.invoke(utf.toString()); - else - methodHandle.invoke(""); - - // reset - size = 0; - utf = null; - } - - callback.succeeded(); - } - catch (Throwable t) - { - callback.failed(t); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/package-info.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/package-info.java deleted file mode 100644 index 6bc70b11411..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket Common : Message Handling - */ -package org.eclipse.jetty.websocket.common.message; - diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/package-info.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/package-info.java deleted file mode 100644 index 24fadec1315..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/package-info.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -/** - * Jetty WebSocket Common : Implementation [Internal Use Only] - *

        - * A core set of internal implementation classes for the Jetty WebSocket API. - *

        - *

        - * Note: do not reference or use classes present in this package space in your code.
        - * Restrict your usage to the Jetty WebSocket API classes, the Jetty WebSocket Client API, - * or the Jetty WebSocket Servlet API. - *

        - */ -package org.eclipse.jetty.websocket.common; - diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/Utf8CharBuffer.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/Utf8CharBuffer.java deleted file mode 100644 index f4d6e7c7a30..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/Utf8CharBuffer.java +++ /dev/null @@ -1,117 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.util; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Utf8Appendable; - -/** - * A CharBuffer wrapped with the Utf8Appendable logic. - */ -public class Utf8CharBuffer extends Utf8Appendable -{ - /** - * Convenience method to wrap a ByteBuffer with a {@link Utf8CharBuffer} - * - * @param buffer the buffer to wrap - * @return the Utf8ByteBuffer for the provided ByteBuffer - */ - public static Utf8CharBuffer wrap(ByteBuffer buffer) - { - return new Utf8CharBuffer(buffer.asCharBuffer()); - } - - private final CharBuffer buffer; - - private Utf8CharBuffer(CharBuffer buffer) - { - super(buffer); - this.buffer = buffer; - } - - public void append(char[] cbuf, int offset, int size) - { - append(BufferUtil.toDirectBuffer(new String(cbuf, offset, size), StandardCharsets.UTF_8)); - } - - public void append(int c) - { - buffer.append((char)c); - } - - public void clear() - { - buffer.position(0); - buffer.limit(buffer.capacity()); - } - - public ByteBuffer getByteBuffer() - { - // remember settings - int limit = buffer.limit(); - int position = buffer.position(); - - // flip to flush - buffer.limit(buffer.position()); - buffer.position(0); - - // get byte buffer - ByteBuffer bb = StandardCharsets.UTF_8.encode(buffer); - - // restor settings - buffer.limit(limit); - buffer.position(position); - - return bb; - } - - @Override - public int length() - { - return buffer.capacity(); - } - - @Override - public String getPartialString() - { - throw new UnsupportedOperationException("Cannot get Partial String from Utf8CharBuffer"); - } - - public int remaining() - { - return buffer.remaining(); - } - - @Override - public String toString() - { - StringBuilder str = new StringBuilder(); - str.append("Utf8CharBuffer@").append(hashCode()); - str.append("[p=").append(buffer.position()); - str.append(",l=").append(buffer.limit()); - str.append(",c=").append(buffer.capacity()); - str.append(",r=").append(buffer.remaining()); - str.append("]"); - return str.toString(); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.common.reflect.ArgIdentifier b/jetty-websocket/jetty-websocket-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.common.reflect.ArgIdentifier deleted file mode 100644 index 815310b16b6..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.common.reflect.ArgIdentifier +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.jetty.websocket.common.reflect.NameArgIdentifier diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageWriterTest.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageWriterTest.java deleted file mode 100644 index 8db970f469a..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageWriterTest.java +++ /dev/null @@ -1,102 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import java.util.Arrays; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.common.message.MessageWriter; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class MessageWriterTest -{ - private static final Logger LOG = Log.getLogger(MessageWriterTest.class); - private static final int OUTPUT_BUFFER_SIZE = 4096; - - public TestableLeakTrackingBufferPool bufferPool = new TestableLeakTrackingBufferPool("Test"); - - @AfterEach - public void afterEach() - { - bufferPool.assertNoLeaks(); - } - - private OutgoingMessageCapture remoteSocket; - - @BeforeEach - public void setupSession() - { - remoteSocket = new OutgoingMessageCapture(); - } - - @Test - public void testMultipleWrites() throws Exception - { - try (MessageWriter stream = new MessageWriter(remoteSocket, OUTPUT_BUFFER_SIZE)) - { - stream.write("Hello"); - stream.write(" "); - stream.write("World"); - } - - assertThat("Socket.messageQueue.size", remoteSocket.textMessages.size(), is(1)); - String msg = remoteSocket.textMessages.poll(); - assertThat("Message", msg, is("Hello World")); - } - - @Test - public void testSingleWrite() throws Exception - { - try (MessageWriter stream = new MessageWriter(remoteSocket, OUTPUT_BUFFER_SIZE)) - { - stream.append("Hello World"); - } - - assertThat("Socket.messageQueue.size", remoteSocket.textMessages.size(), is(1)); - String msg = remoteSocket.textMessages.poll(); - assertThat("Message", msg, is("Hello World")); - } - - @Test - public void testWriteLarge_RequiringMultipleBuffers() throws Exception - { - int size = (int)(OUTPUT_BUFFER_SIZE * 2.5); - char[] buf = new char[size]; - if (LOG.isDebugEnabled()) - LOG.debug("Buffer size: {}", size); - Arrays.fill(buf, 'x'); - buf[size - 1] = 'o'; // mark last entry for debugging - - try (MessageWriter stream = new MessageWriter(remoteSocket, OUTPUT_BUFFER_SIZE)) - { - stream.write(buf); - } - - assertThat("Socket.messageQueue.size", remoteSocket.textMessages.size(), is(1)); - String msg = remoteSocket.textMessages.poll(); - String expected = new String(buf); - assertThat("Message", msg, is(expected)); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/OutgoingMessageCapture.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/OutgoingMessageCapture.java deleted file mode 100644 index 5955296793f..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/OutgoingMessageCapture.java +++ /dev/null @@ -1,324 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; - -import org.eclipse.jetty.toolchain.test.Hex; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.RemoteEndpoint; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.SuspendToken; -import org.eclipse.jetty.websocket.api.UpgradeRequest; -import org.eclipse.jetty.websocket.api.UpgradeResponse; -import org.eclipse.jetty.websocket.api.WebSocketBehavior; -import org.eclipse.jetty.websocket.common.message.ByteBufferMessageSink; -import org.eclipse.jetty.websocket.common.message.StringMessageSink; -import org.eclipse.jetty.websocket.core.CloseStatus; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.OpCode; - -public class OutgoingMessageCapture extends FrameHandler.CoreSession.Empty implements FrameHandler.CoreSession -{ - private static final Logger LOG = Log.getLogger(OutgoingMessageCapture.class); - - public BlockingQueue textMessages = new LinkedBlockingDeque<>(); - public BlockingQueue binaryMessages = new LinkedBlockingDeque<>(); - public BlockingQueue events = new LinkedBlockingDeque<>(); - - private final MethodHandle wholeTextHandle; - private final MethodHandle wholeBinaryHandle; - private MessageSink messageSink; - private long maxMessageSize = 2 * 1024 * 1024; - - public OutgoingMessageCapture() - { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - try - { - MethodHandle text = lookup.findVirtual(this.getClass(), "onWholeText", MethodType.methodType(Void.TYPE, String.class)); - this.wholeTextHandle = text.bindTo(this); - - MethodHandle binary = lookup.findVirtual(this.getClass(), "onWholeBinary", MethodType.methodType(Void.TYPE, ByteBuffer.class)); - this.wholeBinaryHandle = binary.bindTo(this); - } - catch (NoSuchMethodException | IllegalAccessException e) - { - throw new IllegalStateException("Unable to setup OutgoingMessageCapture", e); - } - } - - @Override - public void sendFrame(Frame frame, Callback callback, boolean batch) - { - switch (frame.getOpCode()) - { - case OpCode.CLOSE: - { - CloseStatus closeStatus = new CloseStatus(frame.getPayload()); - String event = String.format("CLOSE:%s:%s", CloseStatus.codeString(closeStatus.getCode()), closeStatus.getReason()); - LOG.debug(event); - events.offer(event); - } - break; - case OpCode.PING: - { - String event = String.format("PING:%s", dataHint(frame.getPayload())); - LOG.debug(event); - events.offer(event); - } - break; - case OpCode.PONG: - { - String event = String.format("PONG:%s", dataHint(frame.getPayload())); - LOG.debug(event); - events.offer(event); - } - break; - case OpCode.TEXT: - { - String event = String.format("TEXT:fin=%b:len=%d", frame.isFin(), frame.getPayloadLength()); - LOG.debug(event); - events.offer(event); - messageSink = new StringMessageSink(null, wholeTextHandle, getFakeSession()); - } - break; - case OpCode.BINARY: - { - String event = String.format("BINARY:fin=%b:len=%d", frame.isFin(), frame.getPayloadLength()); - LOG.debug(event); - events.offer(event); - messageSink = new ByteBufferMessageSink(null, wholeBinaryHandle, getFakeSession()); - } - break; - case OpCode.CONTINUATION: - { - String event = String.format("CONTINUATION:fin=%b:len=%d", frame.isFin(), frame.getPayloadLength()); - LOG.debug(event); - events.offer(event); - } - break; - } - - if (OpCode.isDataFrame(frame.getOpCode())) - { - messageSink.accept(frame, callback); - if (frame.isFin()) - { - messageSink = null; - } - } - else - { - callback.succeeded(); - } - } - - @SuppressWarnings("unused") - public void onWholeText(String msg) - { - this.textMessages.offer(msg); - } - - @SuppressWarnings("unused") - public void onWholeBinary(ByteBuffer buf) - { - ByteBuffer copy = null; - if (buf != null) - { - copy = ByteBuffer.allocate(buf.remaining()); - copy.put(buf); - copy.flip(); - } - this.binaryMessages.offer(copy); - } - - private String dataHint(ByteBuffer payload) - { - if (payload == null) - return ""; - - StringBuilder hint = new StringBuilder(); - hint.append('['); - ByteBuffer sliced = payload.slice(); - if (sliced.remaining() > 20) - { - sliced.limit(20); - hint.append(Hex.asHex(sliced)); - hint.append("..."); - } - else - { - hint.append(Hex.asHex(sliced)); - } - hint.append(']'); - return hint.toString(); - } - - private Session getFakeSession() - { - return new Session() - { - @Override - public void close() - { - } - - @Override - public void close(org.eclipse.jetty.websocket.api.CloseStatus closeStatus) - { - } - - @Override - public void close(int statusCode, String reason) - { - } - - @Override - public void disconnect() - { - } - - @Override - public SocketAddress getLocalAddress() - { - return null; - } - - @Override - public String getProtocolVersion() - { - return null; - } - - @Override - public RemoteEndpoint getRemote() - { - return null; - } - - @Override - public SocketAddress getRemoteAddress() - { - return null; - } - - @Override - public UpgradeRequest getUpgradeRequest() - { - return null; - } - - @Override - public UpgradeResponse getUpgradeResponse() - { - return null; - } - - @Override - public boolean isOpen() - { - return false; - } - - @Override - public boolean isSecure() - { - return false; - } - - @Override - public SuspendToken suspend() - { - return null; - } - - @Override - public WebSocketBehavior getBehavior() - { - return null; - } - - @Override - public Duration getIdleTimeout() - { - return null; - } - - @Override - public int getInputBufferSize() - { - return 0; - } - - @Override - public int getOutputBufferSize() - { - return 0; - } - - @Override - public long getMaxBinaryMessageSize() - { - return maxMessageSize; - } - - @Override - public long getMaxTextMessageSize() - { - return maxMessageSize; - } - - @Override - public void setIdleTimeout(Duration duration) - { - } - - @Override - public void setInputBufferSize(int size) - { - } - - @Override - public void setOutputBufferSize(int size) - { - } - - @Override - public void setMaxBinaryMessageSize(long size) - { - } - - @Override - public void setMaxTextMessageSize(long size) - { - } - }; - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java deleted file mode 100644 index fca79b30149..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.adapters; - -import java.io.IOException; - -import org.eclipse.jetty.websocket.api.WebSocketAdapter; - -/** - * Example EchoSocket using Adapter. - */ -public class AdapterEchoSocket extends WebSocketAdapter -{ - @Override - public void onWebSocketText(String message) - { - if (isConnected()) - { - try - { - System.out.printf("Echoing back message [%s]%n", message); - // echo the message back - getRemote().sendString(message); - } - catch (IOException e) - { - e.printStackTrace(System.err); - } - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java deleted file mode 100644 index 5e18dafbc14..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.adapters; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Example EchoSocket using Annotations. - */ -@WebSocket(maxTextMessageSize = 64 * 1024) -public class AnnotatedEchoSocket -{ - @OnWebSocketMessage - public void onText(Session session, String message) - { - if (session.isOpen()) - { - System.out.printf("Echoing back message [%s]%n", message); - // echo the message back - session.getRemote().sendString(message, null); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedBinaryArraySocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedBinaryArraySocket.java deleted file mode 100644 index 5e8aec6aee9..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedBinaryArraySocket.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; - -@WebSocket -public class AnnotatedBinaryArraySocket -{ - public EventQueue events = new EventQueue(); - - @OnWebSocketMessage - public void onBinary(byte payload[], int offset, int length) - { - events.add("onBinary([%d],%d,%d)", payload.length, offset, length); - } - - @OnWebSocketClose - public void onClose(int statusCode, String reason) - { - events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); - } - - @OnWebSocketConnect - public void onConnect(Session sess) - { - events.add("onConnect(%s)", sess); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedBinaryStreamSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedBinaryStreamSocket.java deleted file mode 100644 index b665a781fb3..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedBinaryStreamSocket.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import java.io.InputStream; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.notNullValue; - -@WebSocket -public class AnnotatedBinaryStreamSocket -{ - public EventQueue events = new EventQueue(); - - @OnWebSocketMessage - public void onBinary(InputStream stream) - { - assertThat("InputStream", stream, notNullValue()); - events.add("onBinary(%s)", stream); - } - - @OnWebSocketClose - public void onClose(int statusCode, String reason) - { - events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); - } - - @OnWebSocketConnect - public void onConnect(Session sess) - { - events.add("onConnect(%s)", sess); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedTextSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedTextSocket.java deleted file mode 100644 index 71d62146a9b..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedTextSocket.java +++ /dev/null @@ -1,58 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; - -@WebSocket -public class AnnotatedTextSocket -{ - public EventQueue events = new EventQueue(); - - @OnWebSocketClose - public void onClose(int statusCode, String reason) - { - events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); - } - - @OnWebSocketConnect - public void onConnect(Session sess) - { - events.add("onConnect(%s)", sess); - } - - @OnWebSocketError - public void onError(Throwable cause) - { - events.add("onError(%s: %s)", cause.getClass().getSimpleName(), cause.getMessage()); - } - - @OnWebSocketMessage - public void onText(String message) - { - events.add("onText(%s)", TextUtil.quote(message)); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedTextStreamSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedTextStreamSocket.java deleted file mode 100644 index 917d894a765..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/AnnotatedTextStreamSocket.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import java.io.Reader; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; - -@WebSocket -public class AnnotatedTextStreamSocket -{ - public EventQueue events = new EventQueue(); - - @OnWebSocketClose - public void onClose(int statusCode, String reason) - { - events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); - } - - @OnWebSocketConnect - public void onConnect(Session sess) - { - events.add("onConnect(%s)", sess); - } - - @OnWebSocketMessage - public void onText(Reader reader) - { - events.add("onText(%s)", reader); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadBinarySignatureSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadBinarySignatureSocket.java deleted file mode 100644 index eb7b46a468f..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadBinarySignatureSocket.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Invalid Socket: Annotate a message interest on a method with a return type. - */ -@WebSocket -public class BadBinarySignatureSocket -{ - /** - * Declaring a non-void return type - * - * @param session the session - * @param buf the buffer - * @param offset the offset - * @param len the length - * @return the response boolean - */ - @OnWebSocketMessage - public boolean onBinary(Session session, byte buf[], int offset, int len) - { - return false; - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadDuplicateBinarySocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadDuplicateBinarySocket.java deleted file mode 100644 index 17edc4975b4..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadDuplicateBinarySocket.java +++ /dev/null @@ -1,55 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import java.io.InputStream; - -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Invalid Socket: Annotate 2 methods with interest in Binary Messages. - */ -@WebSocket -public class BadDuplicateBinarySocket -{ - /** - * First method - * - * @param payload the payload - * @param offset the offset - * @param len the len - */ - @OnWebSocketMessage - public void binMe(byte[] payload, int offset, int len) - { - /* ignore */ - } - - /** - * Second method (also binary) - * - * @param stream the input stream - */ - @OnWebSocketMessage - public void streamMe(InputStream stream) - { - /* ignore */ - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadDuplicateFrameSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadDuplicateFrameSocket.java deleted file mode 100644 index e7fdc674f20..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadDuplicateFrameSocket.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.core.Frame; - -@WebSocket -public class BadDuplicateFrameSocket -{ - /** - * The get a frame - * - * @param frame the frame - */ - @OnWebSocketFrame - public void frameMe(Frame frame) - { - /* ignore */ - } - - /** - * This is a duplicate frame type (should throw an exception attempting to use) - * - * @param frame the frame - */ - @OnWebSocketFrame - public void watchMe(Frame frame) - { - /* ignore */ - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadTextSignatureSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadTextSignatureSocket.java deleted file mode 100644 index 44a00291fdf..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/BadTextSignatureSocket.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Invalid Socket: Annotate a message interest on a static method - */ -@WebSocket -public class BadTextSignatureSocket -{ - /** - * Declaring a static method - * - * @param session the session - * @param text the text message - */ - @OnWebSocketMessage - public static void onText(Session session, String text) - { - /* do nothing */ - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/FrameSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/FrameSocket.java deleted file mode 100644 index e2babb5620b..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/FrameSocket.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Frame; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -@WebSocket -public class FrameSocket -{ - /** - * A frame - * - * @param frame the frame - */ - @OnWebSocketFrame - public void frameMe(Frame frame) - { - /* ignore */ - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyEchoBinarySocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyEchoBinarySocket.java deleted file mode 100644 index d50071bf790..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyEchoBinarySocket.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Test of constructing a new WebSocket based on a base class - */ -@WebSocket -public class MyEchoBinarySocket extends MyEchoSocket -{ - @OnWebSocketMessage - public void echoBin(byte buf[], int offset, int length) - { - try - { - getRemote().sendBytes(ByteBuffer.wrap(buf, offset, length)); - } - catch (IOException e) - { - e.printStackTrace(); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyEchoSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyEchoSocket.java deleted file mode 100644 index b7e20b9a3ec..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyEchoSocket.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import java.io.IOException; - -import org.eclipse.jetty.websocket.api.RemoteEndpoint; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * The most common websocket implementation. - *

        - * This version tracks the connection per socket instance and will - */ -@WebSocket -public class MyEchoSocket -{ - private Session session; - private RemoteEndpoint remote; - - public RemoteEndpoint getRemote() - { - return remote; - } - - @OnWebSocketClose - public void onClose(int statusCode, String reason) - { - this.session = null; - } - - @OnWebSocketConnect - public void onConnect(Session session) - { - this.session = session; - this.remote = session.getRemote(); - } - - @OnWebSocketMessage - public void onText(String message) - { - if (session == null) - { - // no connection, do nothing. - // this is possible due to async behavior - return; - } - - try - { - remote.sendString(message); - } - catch (IOException e) - { - e.printStackTrace(); - } - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyStatelessEchoSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyStatelessEchoSocket.java deleted file mode 100644 index 1866d07de62..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/MyStatelessEchoSocket.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Example of a stateless websocket implementation. - *

        - * Useful for websockets that only reply to incoming requests. - *

        - * Note: that for this style of websocket to be viable on the server side be sure that you only create 1 instance of this socket, as more instances would be - * wasteful of resources and memory. - */ -@WebSocket -public class MyStatelessEchoSocket -{ - @OnWebSocketMessage - public void onText(Session session, String text) - { - session.getRemote().sendString(text, null); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/NoopSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/NoopSocket.java deleted file mode 100644 index 37e8e53477e..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/NoopSocket.java +++ /dev/null @@ -1,30 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * The most basic websocket declaration. - */ -@WebSocket -public class NoopSocket -{ - /* intentionally do nothing */ -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/NotASocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/NotASocket.java deleted file mode 100644 index 20932d0975a..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/annotated/NotASocket.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.annotated; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; - -/** - * (Test Case) - *

        - * Intentionally not specifying the @WebSocket annotation here - */ -public class NotASocket -{ - @OnWebSocketConnect - public void onConnect(Session session) - { - /* do nothing */ - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerBasicSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerBasicSocket.java deleted file mode 100644 index 7448da837e0..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerBasicSocket.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.listeners; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketListener; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; -import org.eclipse.jetty.websocket.core.CloseStatus; - -public class ListenerBasicSocket implements WebSocketListener -{ - public EventQueue events = new EventQueue(); - - @Override - public void onWebSocketBinary(byte[] payload, int offset, int len) - { - events.add("onWebSocketBinary([%d], %d, %d)", payload.length, offset, len); - } - - @Override - public void onWebSocketClose(int statusCode, String reason) - { - events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); - } - - @Override - public void onWebSocketConnect(Session session) - { - events.add("onWebSocketConnect(%s)", session); - } - - @Override - public void onWebSocketError(Throwable cause) - { - events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); - } - - @Override - public void onWebSocketText(String message) - { - events.add("onWebSocketText(%s)", TextUtil.quote(message)); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerFrameSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerFrameSocket.java deleted file mode 100644 index 638c35cb58b..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerFrameSocket.java +++ /dev/null @@ -1,55 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.listeners; - -import org.eclipse.jetty.websocket.api.Frame; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketFrameListener; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; -import org.eclipse.jetty.websocket.core.CloseStatus; - -public class ListenerFrameSocket implements WebSocketFrameListener -{ - public EventQueue events = new EventQueue(); - - @Override - public void onWebSocketClose(int statusCode, String reason) - { - events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); - } - - @Override - public void onWebSocketConnect(Session session) - { - events.add("onWebSocketConnect(%s)", session); - } - - @Override - public void onWebSocketError(Throwable cause) - { - events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); - } - - @Override - public void onWebSocketFrame(Frame frame) - { - events.add("onWebSocketFrame(%s)", frame.toString()); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerPartialSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerPartialSocket.java deleted file mode 100644 index ea3137fcc20..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerPartialSocket.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.listeners; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketPartialListener; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; -import org.eclipse.jetty.websocket.core.CloseStatus; - -public class ListenerPartialSocket implements WebSocketPartialListener -{ - public EventQueue events = new EventQueue(); - - @Override - public void onWebSocketClose(int statusCode, String reason) - { - events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); - } - - @Override - public void onWebSocketConnect(Session session) - { - events.add("onWebSocketConnect(%s)", session); - } - - @Override - public void onWebSocketError(Throwable cause) - { - events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); - } - - @Override - public void onWebSocketPartialText(String payload, boolean fin) - { - events.add("onWebSocketPartialText(%s, %b)", TextUtil.quote(payload), fin); - } - - @Override - public void onWebSocketPartialBinary(ByteBuffer payload, boolean fin) - { - events.add("onWebSocketPartialBinary(%s, %b)", BufferUtil.toDetailString(payload), fin); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerPingPongSocket.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerPingPongSocket.java deleted file mode 100644 index a5f1039a50e..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/listeners/ListenerPingPongSocket.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.endpoints.listeners; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketPingPongListener; -import org.eclipse.jetty.websocket.common.EventQueue; -import org.eclipse.jetty.websocket.common.util.TextUtil; -import org.eclipse.jetty.websocket.core.CloseStatus; - -public class ListenerPingPongSocket implements WebSocketPingPongListener -{ - public EventQueue events = new EventQueue(); - - @Override - public void onWebSocketClose(int statusCode, String reason) - { - events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); - } - - @Override - public void onWebSocketConnect(Session session) - { - events.add("onWebSocketConnect(%s)", session); - } - - @Override - public void onWebSocketError(Throwable cause) - { - events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); - } - - @Override - public void onWebSocketPing(ByteBuffer payload) - { - events.add("onWebSocketPing(%s)", BufferUtil.toDetailString(payload)); - } - - @Override - public void onWebSocketPong(ByteBuffer payload) - { - events.add("onWebSocketPong(%s)", BufferUtil.toDetailString(payload)); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java deleted file mode 100644 index ff776d71200..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java +++ /dev/null @@ -1,223 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.handshake; - -import java.net.HttpCookie; -import java.net.URI; -import java.security.Principal; -import java.util.List; -import java.util.Map; - -import org.eclipse.jetty.websocket.api.UpgradeRequest; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; - -public class DummyUpgradeRequest implements UpgradeRequest -{ - @Override - public void addExtensions(ExtensionConfig... configs) - { - - } - - @Override - public void addExtensions(String... configs) - { - - } - - @Override - public List getCookies() - { - return null; - } - - @Override - public List getExtensions() - { - return null; - } - - @Override - public String getHeader(String name) - { - return null; - } - - @Override - public int getHeaderInt(String name) - { - return 0; - } - - @Override - public Map> getHeaders() - { - return null; - } - - @Override - public List getHeaders(String name) - { - return null; - } - - @Override - public String getHost() - { - return null; - } - - @Override - public String getHttpVersion() - { - return null; - } - - @Override - public String getMethod() - { - return null; - } - - @Override - public String getOrigin() - { - return null; - } - - @Override - public Map> getParameterMap() - { - return null; - } - - @Override - public String getProtocolVersion() - { - return null; - } - - @Override - public String getQueryString() - { - return null; - } - - @Override - public URI getRequestURI() - { - return null; - } - - @Override - public Object getSession() - { - return null; - } - - @Override - public List getSubProtocols() - { - return null; - } - - @Override - public Principal getUserPrincipal() - { - return null; - } - - @Override - public boolean hasSubProtocol(String test) - { - return false; - } - - @Override - public boolean isSecure() - { - return false; - } - - @Override - public void setCookies(List cookies) - { - - } - - @Override - public void setExtensions(List configs) - { - - } - - @Override - public void setHeader(String name, List values) - { - - } - - @Override - public void setHeader(String name, String value) - { - - } - - @Override - public void setHeaders(Map> headers) - { - - } - - @Override - public void setHttpVersion(String httpVersion) - { - - } - - @Override - public void setMethod(String method) - { - - } - - @Override - public void setRequestURI(URI uri) - { - - } - - @Override - public void setSession(Object session) - { - - } - - @Override - public void setSubProtocols(List protocols) - { - - } - - @Override - public void setSubProtocols(String... protocols) - { - - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeResponse.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeResponse.java deleted file mode 100644 index d1929e4aac8..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeResponse.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.handshake; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.jetty.websocket.api.UpgradeResponse; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; - -public class DummyUpgradeResponse implements UpgradeResponse -{ - @Override - public void addHeader(String name, String value) - { - - } - - @Override - public String getAcceptedSubProtocol() - { - return null; - } - - @Override - public List getExtensions() - { - return null; - } - - @Override - public String getHeader(String name) - { - return null; - } - - @Override - public Set getHeaderNames() - { - return null; - } - - @Override - public Map> getHeaders() - { - return null; - } - - @Override - public List getHeaders(String name) - { - return null; - } - - @Override - public int getStatusCode() - { - return 0; - } - - @Override - public void sendForbidden(String message) throws IOException - { - - } - - @Override - public void setAcceptedSubProtocol(String protocol) - { - - } - - @Override - public void setExtensions(List extensions) - { - - } - - @Override - public void setHeader(String name, String value) - { - - } - - @Override - public void setStatusCode(int statusCode) - { - - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/util/Utf8CharBufferTest.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/util/Utf8CharBufferTest.java deleted file mode 100644 index 742086dcdd9..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/util/Utf8CharBufferTest.java +++ /dev/null @@ -1,125 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.util; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - -import org.eclipse.jetty.util.BufferUtil; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class Utf8CharBufferTest -{ - private static String asString(ByteBuffer buffer) - { - return BufferUtil.toUTF8String(buffer); - } - - private static byte[] asUTF(String str) - { - return str.getBytes(StandardCharsets.UTF_8); - } - - @Test - public void testAppendGetAppendGet() - { - ByteBuffer buf = ByteBuffer.allocate(128); - Utf8CharBuffer utf = Utf8CharBuffer.wrap(buf); - - byte[] hellobytes = asUTF("Hello "); - byte[] worldbytes = asUTF("World!"); - - utf.append(hellobytes, 0, hellobytes.length); - ByteBuffer hellobuf = utf.getByteBuffer(); - utf.append(worldbytes, 0, worldbytes.length); - ByteBuffer worldbuf = utf.getByteBuffer(); - - assertThat("Hello buffer", asString(hellobuf), is("Hello ")); - assertThat("World buffer", asString(worldbuf), is("Hello World!")); - } - - @Test - public void testAppendGetClearAppendGet() - { - int bufsize = 128; - ByteBuffer buf = ByteBuffer.allocate(bufsize); - Utf8CharBuffer utf = Utf8CharBuffer.wrap(buf); - - int expectedSize = bufsize / 2; - assertThat("Remaining (initial)", utf.remaining(), is(expectedSize)); - - byte[] hellobytes = asUTF("Hello World"); - - utf.append(hellobytes, 0, hellobytes.length); - ByteBuffer hellobuf = utf.getByteBuffer(); - - assertThat("Remaining (after append)", utf.remaining(), is(expectedSize - hellobytes.length)); - assertThat("Hello buffer", asString(hellobuf), is("Hello World")); - - utf.clear(); - - assertThat("Remaining (after clear)", utf.remaining(), is(expectedSize)); - - byte[] whatnowbytes = asUTF("What Now?"); - utf.append(whatnowbytes, 0, whatnowbytes.length); - ByteBuffer whatnowbuf = utf.getByteBuffer(); - - assertThat("Remaining (after 2nd append)", utf.remaining(), is(expectedSize - whatnowbytes.length)); - assertThat("What buffer", asString(whatnowbuf), is("What Now?")); - } - - @Test - public void testAppendUnicodeGetBuffer() - { - ByteBuffer buf = ByteBuffer.allocate(64); - Utf8CharBuffer utf = Utf8CharBuffer.wrap(buf); - - byte[] bb = asUTF("Hello A\u00ea\u00f1\u00fcC"); - utf.append(bb, 0, bb.length); - - ByteBuffer actual = utf.getByteBuffer(); - assertThat("Buffer length should be retained", actual.remaining(), is(bb.length)); - assertThat("Message", asString(actual), is("Hello A\u00ea\u00f1\u00fcC")); - } - - @Test - public void testSimpleGetBuffer() - { - int bufsize = 64; - ByteBuffer buf = ByteBuffer.allocate(bufsize); - Utf8CharBuffer utf = Utf8CharBuffer.wrap(buf); - - int expectedSize = bufsize / 2; - assertThat("Remaining (initial)", utf.remaining(), is(expectedSize)); - - byte[] bb = asUTF("Hello World"); - utf.append(bb, 0, bb.length); - - expectedSize -= bb.length; - assertThat("Remaining (after append)", utf.remaining(), is(expectedSize)); - - ByteBuffer actual = utf.getByteBuffer(); - assertThat("Buffer length", actual.remaining(), is(bb.length)); - - assertThat("Message", asString(actual), is("Hello World")); - } -} diff --git a/jetty-websocket/jetty-websocket-common/src/test/resources/jetty-logging.properties b/jetty-websocket/jetty-websocket-common/src/test/resources/jetty-logging.properties deleted file mode 100644 index af83047e755..00000000000 --- a/jetty-websocket/jetty-websocket-common/src/test/resources/jetty-logging.properties +++ /dev/null @@ -1,18 +0,0 @@ -# -# ======================================================================== -# Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. -# ------------------------------------------------------------------------ -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# and Apache License v2.0 which accompanies this distribution. -# -# The Eclipse Public License is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# The Apache License v2.0 is available at -# http://www.opensource.org/licenses/apache2.0.php -# -# You may elect to redistribute this code under either of these licenses. -# ======================================================================== -# -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog \ No newline at end of file diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/module-info.java b/jetty-websocket/jetty-websocket-server/src/main/java/module-info.java deleted file mode 100644 index 689f680ecea..00000000000 --- a/jetty-websocket/jetty-websocket-server/src/main/java/module-info.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -import javax.servlet.ServletContainerInitializer; - -import org.eclipse.jetty.webapp.Configuration; -import org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration; -import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; - -module org.eclipse.jetty.websocket.jetty.server -{ - exports org.eclipse.jetty.websocket.server; - - requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.servlet; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.webapp; - requires org.eclipse.jetty.websocket.core; - requires org.eclipse.jetty.websocket.jetty.api; - requires org.eclipse.jetty.websocket.jetty.common; - requires org.eclipse.jetty.websocket.servlet; - - // Only required if using JMX. - requires static org.eclipse.jetty.jmx; - - provides ServletContainerInitializer with JettyWebSocketServletContainerInitializer; - provides Configuration with JettyWebSocketConfiguration; -} diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketCreator.java b/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketCreator.java deleted file mode 100644 index 67bed07017d..00000000000 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketCreator.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.server; - -/** - * Abstract WebSocket creator interface. - *

        - * Should you desire filtering of the WebSocket object creation due to criteria such as origin or sub-protocol, then you will be required to implement a custom - * WebSocketCreator implementation. - *

        - */ -public interface JettyWebSocketCreator -{ - /** - * Create a websocket from the incoming request. - * - * @param req the request details - * @param resp the response details - * @return a websocket object to use, or null if no websocket should be created from this request. - */ - Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp); -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/AnnoMaxMessageEndpoint.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/AnnoMaxMessageEndpoint.java deleted file mode 100644 index ed981ff7f9c..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/AnnoMaxMessageEndpoint.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests; - -import java.io.IOException; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -@SuppressWarnings("unused") -@WebSocket(maxTextMessageSize = 100 * 1024) -public class AnnoMaxMessageEndpoint -{ - @OnWebSocketMessage - public void onMessage(Session session, String msg) throws IOException - { - session.getRemote().sendString(msg); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConnectMessageEndpoint.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConnectMessageEndpoint.java deleted file mode 100644 index d9ff09a4645..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConnectMessageEndpoint.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests; - -import java.io.IOException; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -@SuppressWarnings("unused") -@WebSocket -public class ConnectMessageEndpoint -{ - @OnWebSocketConnect - public void onConnect(Session session) throws IOException - { - session.getRemote().sendString("Greeting from onConnect"); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoCreator.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoCreator.java deleted file mode 100644 index 61be8ec2617..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoCreator.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests; - -import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; -import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; -import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; - -public class EchoCreator implements JettyWebSocketCreator -{ - @Override - public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) - { - if (req.hasSubProtocol("echo")) - { - resp.setAcceptedSubProtocol("echo"); - } - - return new EchoSocket(); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoSocket.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoSocket.java deleted file mode 100644 index eac981f385b..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoSocket.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.websocket.api.WriteCallback; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -@SuppressWarnings("unused") -@WebSocket -public class EchoSocket extends EventSocket -{ - @Override - public void onMessage(String message) throws IOException - { - super.onMessage(message); - session.getRemote().sendString(message); - } - - @Override - public void onMessage(byte[] buf, int offset, int len) - { - super.onMessage(buf, offset, len); - session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len), WriteCallback.NOOP); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/GetAuthHeaderEndpoint.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/GetAuthHeaderEndpoint.java deleted file mode 100644 index 8e6130841cf..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/GetAuthHeaderEndpoint.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests; - -import java.io.IOException; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -@SuppressWarnings("unused") -@WebSocket -public class GetAuthHeaderEndpoint -{ - @OnWebSocketConnect - public void onConnect(Session session) throws IOException - { - String authHeaderName = "Authorization"; - String authHeaderValue = session.getUpgradeRequest().getHeader(authHeaderName); - session.getRemote().sendString("Header[" + authHeaderName + "]=" + authHeaderValue); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SimpleStatusServlet.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SimpleStatusServlet.java deleted file mode 100644 index 300439a10d4..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SimpleStatusServlet.java +++ /dev/null @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class SimpleStatusServlet extends HttpServlet -{ - private final int statusCode; - - public SimpleStatusServlet(int statusCode) - { - this.statusCode = statusCode; - } - - @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - resp.setStatus(this.statusCode); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java deleted file mode 100644 index c287614a809..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.examples; - -import java.time.Duration; -import javax.servlet.annotation.WebServlet; - -import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; -import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; - -@SuppressWarnings("serial") -@WebServlet(name = "MyAdvanced Echo WebSocket Servlet", urlPatterns = {"/advecho"}) -public class MyAdvancedEchoServlet extends JettyWebSocketServlet -{ - @Override - public void configure(JettyWebSocketServletFactory factory) - { - // set a 10 second timeout - factory.setIdleTimeout(Duration.ofSeconds(10)); - - // set a custom WebSocket creator - factory.setCreator(new MyAdvancedEchoCreator()); - } -} \ No newline at end of file diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedServlet.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedServlet.java deleted file mode 100644 index bd3304d8446..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedServlet.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.examples; - -import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; -import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; - -@SuppressWarnings("serial") -public class MyAuthedServlet extends JettyWebSocketServlet -{ - @Override - public void configure(JettyWebSocketServletFactory factory) - { - factory.setCreator(new MyAuthedCreator()); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyBinaryEchoSocket.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyBinaryEchoSocket.java deleted file mode 100644 index 14978f84fe9..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyBinaryEchoSocket.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.examples; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Echo BINARY messages - */ -@WebSocket -public class MyBinaryEchoSocket -{ - @OnWebSocketMessage - public void onWebSocketText(Session session, byte buf[], int offset, int len) - { - // Echo message back, asynchronously - session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len), null); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java deleted file mode 100644 index 85875302869..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.examples; - -import java.time.Duration; -import javax.servlet.annotation.WebServlet; - -import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; -import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; - -@SuppressWarnings("serial") -@WebServlet(name = "MyEcho WebSocket Servlet", urlPatterns = {"/echo"}) -public class MyEchoServlet extends JettyWebSocketServlet -{ - @Override - public void configure(JettyWebSocketServletFactory factory) - { - // set a 10 second timeout - factory.setIdleTimeout(Duration.ofSeconds(10)); - - // register MyEchoSocket as the WebSocket to create on Upgrade - factory.register(MyEchoSocket.class); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoSocket.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoSocket.java deleted file mode 100644 index 23abd9967fd..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.examples; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; -import org.eclipse.jetty.websocket.api.annotations.WebSocket; - -/** - * Example WebSocket, simple echo - */ -@WebSocket -public class MyEchoSocket -{ - @OnWebSocketMessage - public void onWebSocketText(Session session, String message) - { - // Echo message back, asynchronously - session.getRemote().sendString(message, null); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastCloseEndpoint.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastCloseEndpoint.java deleted file mode 100644 index d9d45573502..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastCloseEndpoint.java +++ /dev/null @@ -1,35 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.server; - -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.StatusCode; - -/** - * On Connect, close socket - */ -public class FastCloseEndpoint extends AbstractCloseEndpoint -{ - @Override - public void onWebSocketConnect(Session sess) - { - LOG.debug("onWebSocketConnect({})", sess); - sess.close(StatusCode.NORMAL, "FastCloseServer"); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastFailEndpoint.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastFailEndpoint.java deleted file mode 100644 index aa2990fc0c8..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastFailEndpoint.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.server; - -import org.eclipse.jetty.websocket.api.Session; - -/** - * On Connect, throw unhandled exception - */ -public class FastFailEndpoint extends AbstractCloseEndpoint -{ - @Override - public void onWebSocketConnect(Session sess) - { - LOG.debug("onWebSocketConnect({})", sess); - // Test failure due to unhandled exception - // this should trigger a fast-fail closure during open/connect - throw new RuntimeException("Intentional FastFail"); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/FutureWriteCallback.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/FutureWriteCallback.java deleted file mode 100644 index 9b37c301651..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/FutureWriteCallback.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.tests.util; - -import java.util.concurrent.Future; - -import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.WriteCallback; - -/** - * Allows events to a {@link WriteCallback} to drive a {@link Future} for the user. - */ -public class FutureWriteCallback extends FutureCallback implements WriteCallback -{ - private static final Logger LOG = Log.getLogger(FutureWriteCallback.class); - - @Override - public void writeFailed(Throwable cause) - { - if (LOG.isDebugEnabled()) - LOG.debug(".writeFailed", cause); - failed(cause); - } - - @Override - public void writeSuccess() - { - if (LOG.isDebugEnabled()) - LOG.debug(".writeSuccess"); - succeeded(); - } -} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties deleted file mode 100644 index 8806e105177..00000000000 --- a/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties +++ /dev/null @@ -1,44 +0,0 @@ -# -# -# ======================================================================== -# Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. -# ------------------------------------------------------------------------ -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# and Apache License v2.0 which accompanies this distribution. -# -# The Eclipse Public License is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# The Apache License v2.0 is available at -# http://www.opensource.org/licenses/apache2.0.php -# -# You may elect to redistribute this code under either of these licenses. -# ======================================================================== -# -# -# org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN -# org.eclipse.jetty.websocket.tests.LEVEL=DEBUG -# org.eclipse.jetty.util.log.stderr.LONG=true -# org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG -# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG -# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG -# org.eclipse.jetty.client.LEVEL=DEBUG -# org.eclipse.jetty.io.LEVEL=DEBUG -# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO -# org.eclipse.jetty.websocket.LEVEL=DEBUG -# org.eclipse.jetty.websocket.core.internal.WebSocketCoreSessionsion.LEVEL=DEBUG -# org.eclipse.jetty.websocket.jsr356.tests.LEVEL=DEBUG -# org.eclipse.jetty.websocket.LEVEL=INFO -# org.eclipse.jetty.websocket.jsr356.messages.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.client.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.client.jsr356.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.server.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.server.jsr356.LEVEL=DEBUG -### Showing any unintended (ignored) errors from CompletionCallback -# org.eclipse.jetty.websocket.common.CompletionCallback.LEVEL=ALL -### Disabling intentional error out of RFCSocket -org.eclipse.jetty.websocket.tests.server.RFCSocket.LEVEL=OFF diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index e4c5bbe5837..b2952f150a8 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -16,17 +16,18 @@ websocket-core websocket-servlet + websocket-util - jetty-websocket-api - jetty-websocket-common - jetty-websocket-client - jetty-websocket-server - jetty-websocket-tests + websocket-jetty-api + websocket-jetty-common + websocket-jetty-client + websocket-jetty-server + websocket-jetty-tests - javax-websocket-common - javax-websocket-client - javax-websocket-server - javax-websocket-tests + websocket-javax-common + websocket-javax-client + websocket-javax-server + websocket-javax-tests diff --git a/jetty-websocket/websocket-core/pom.xml b/jetty-websocket/websocket-core/pom.xml index 1e3067f593b..2e976948002 100644 --- a/jetty-websocket/websocket-core/pom.xml +++ b/jetty-websocket/websocket-core/pom.xml @@ -30,6 +30,10 @@ jetty-http ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty jetty-xml @@ -40,15 +44,18 @@ org.eclipse.jetty jetty-client ${project.version} - provided org.eclipse.jetty jetty-server ${project.version} - provided + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper @@ -71,7 +78,7 @@ - org.eclipse.jetty.websocket:jetty-websocket-api + org.eclipse.jetty.websocket:websocket-jetty-api javax.websocket @@ -141,7 +148,7 @@ - org.eclipse.jetty.websocket.core.autobahn.AutobahnWebSocketServer + org.eclipse.jetty.websocket.core.autobahn.CoreAutobahnServer diff --git a/jetty-websocket/websocket-core/src/main/config/modules/websocket.mod b/jetty-websocket/websocket-core/src/main/config/modules/websocket.mod new file mode 100644 index 00000000000..da53af6d2e2 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/config/modules/websocket.mod @@ -0,0 +1,11 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Enable both jetty and javax websocket modules for deployed web applications. + +[tags] +websocket + +[depend] +websocket-jetty +websocket-javax diff --git a/jetty-websocket/websocket-core/src/main/java/module-info.java b/jetty-websocket/websocket-core/src/main/java/module-info.java index b8d16f3d4ff..c2fa64dda77 100644 --- a/jetty-websocket/websocket-core/src/main/java/module-info.java +++ b/jetty-websocket/websocket-core/src/main/java/module-info.java @@ -1,43 +1,39 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.websocket.core.Extension; import org.eclipse.jetty.websocket.core.internal.FragmentExtension; import org.eclipse.jetty.websocket.core.internal.IdentityExtension; +import org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension; import org.eclipse.jetty.websocket.core.internal.ValidationExtension; -import org.eclipse.jetty.websocket.core.internal.compress.DeflateFrameExtension; -import org.eclipse.jetty.websocket.core.internal.compress.PerMessageDeflateExtension; -import org.eclipse.jetty.websocket.core.internal.compress.XWebkitDeflateFrameExtension; module org.eclipse.jetty.websocket.core { exports org.eclipse.jetty.websocket.core; exports org.eclipse.jetty.websocket.core.client; exports org.eclipse.jetty.websocket.core.server; + exports org.eclipse.jetty.websocket.core.exception; exports org.eclipse.jetty.websocket.core.internal to org.eclipse.jetty.util; - exports org.eclipse.jetty.websocket.core.internal.compress to org.eclipse.jetty.util; requires jetty.servlet.api; - requires org.eclipse.jetty.client; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.util; + requires transitive org.eclipse.jetty.client; + requires transitive org.eclipse.jetty.server; + requires org.slf4j; // Only required if using XmlHttpClientProvider. requires static org.eclipse.jetty.xml; @@ -45,10 +41,8 @@ module org.eclipse.jetty.websocket.core uses Extension; provides Extension with - DeflateFrameExtension, FragmentExtension, IdentityExtension, PerMessageDeflateExtension, - ValidationExtension, - XWebkitDeflateFrameExtension; + ValidationExtension; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java index 6f50cc5d4fb..c4806edbc30 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -24,25 +24,24 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.compression.DeflaterPool; import org.eclipse.jetty.util.compression.InflaterPool; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject("Abstract Extension") -public abstract class AbstractExtension implements Extension +public class AbstractExtension implements Extension { private final Logger log; private ByteBufferPool bufferPool; private ExtensionConfig config; private OutgoingFrames nextOutgoing; private IncomingFrames nextIncoming; - private WebSocketCoreSession coreSession; + private Configuration configuration; private DeflaterPool deflaterPool; private InflaterPool inflaterPool; public AbstractExtension() { - log = Log.getLogger(this.getClass()); + log = LoggerFactory.getLogger(this.getClass()); } @Override @@ -54,6 +53,18 @@ public abstract class AbstractExtension implements Extension this.inflaterPool = components.getInflaterPool(); } + @Override + public void onFrame(Frame frame, Callback callback) + { + nextIncomingFrame(frame, callback); + } + + @Override + public void sendFrame(Frame frame, Callback callback, boolean batch) + { + nextOutgoingFrame(frame, callback, batch); + } + public ByteBufferPool getBufferPool() { return bufferPool; @@ -157,14 +168,14 @@ public abstract class AbstractExtension implements Extension } @Override - public void setWebSocketCoreSession(WebSocketCoreSession coreSession) + public void setCoreSession(CoreSession coreSession) { - this.coreSession = coreSession; + this.configuration = coreSession; } - protected WebSocketCoreSession getWebSocketCoreSession() + protected Configuration getConfiguration() { - return coreSession; + return configuration; } @Override diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/BadPayloadException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/BadPayloadException.java deleted file mode 100644 index d0cfdae380b..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/BadPayloadException.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -/** - * Exception to terminate the connection because it has received data within a frame payload that was not consistent with the requirements of that frame - * payload. (eg: not UTF-8 in a text frame, or a unexpected data seen by an extension) - * - * @see RFC6455 : Section 7.4.1 - */ -@SuppressWarnings("serial") -public class BadPayloadException extends CloseException -{ - public BadPayloadException(String message) - { - super(CloseStatus.BAD_PAYLOAD, message); - } - - public BadPayloadException(String message, Throwable t) - { - super(CloseStatus.BAD_PAYLOAD, message, t); - } - - public BadPayloadException(Throwable t) - { - super(CloseStatus.BAD_PAYLOAD, t); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Behavior.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Behavior.java index 7906828d3d1..dfe8e6d8de5 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Behavior.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Behavior.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseException.java deleted file mode 100644 index a28f7a5fb08..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseException.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -@SuppressWarnings("serial") -public class CloseException extends WebSocketException -{ - private int statusCode; - - public CloseException(int closeCode, String message) - { - super(message); - this.statusCode = closeCode; - } - - public CloseException(int closeCode, String message, Throwable cause) - { - super(message, cause); - this.statusCode = closeCode; - } - - public CloseException(int closeCode, Throwable cause) - { - super(cause); - this.statusCode = closeCode; - } - - public int getStatusCode() - { - return statusCode; - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java index e3661992a2a..cdbed64f7a6 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -25,6 +25,9 @@ import java.util.Arrays; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Utf8Appendable; import org.eclipse.jetty.util.Utf8StringBuilder; +import org.eclipse.jetty.websocket.core.exception.BadPayloadException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.internal.NullAppendable; /** * Representation of a WebSocket Close (status code & reason) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Configuration.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Configuration.java new file mode 100644 index 00000000000..ffc2d8d9225 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Configuration.java @@ -0,0 +1,210 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core; + +import java.time.Duration; + +public interface Configuration +{ + /** + * Get the Idle Timeout + * + * @return the idle timeout + */ + Duration getIdleTimeout(); + + /** + * Get the Write Timeout + * + * @return the write timeout + */ + Duration getWriteTimeout(); + + /** + * Set the Idle Timeout. + * + * @param timeout the timeout duration (timeout <= 0 implies an infinite timeout) + */ + void setIdleTimeout(Duration timeout); + + /** + * Set the Write Timeout. + * + * @param timeout the timeout duration (timeout <= 0 implies an infinite timeout) + */ + void setWriteTimeout(Duration timeout); + + boolean isAutoFragment(); + + void setAutoFragment(boolean autoFragment); + + long getMaxFrameSize(); + + void setMaxFrameSize(long maxFrameSize); + + int getOutputBufferSize(); + + void setOutputBufferSize(int outputBufferSize); + + int getInputBufferSize(); + + void setInputBufferSize(int inputBufferSize); + + long getMaxBinaryMessageSize(); + + void setMaxBinaryMessageSize(long maxSize); + + long getMaxTextMessageSize(); + + void setMaxTextMessageSize(long maxSize); + + interface Customizer + { + void customize(Configuration configurable); + } + + class ConfigurationCustomizer implements Configuration, Customizer + { + private Duration idleTimeout; + private Duration writeTimeout; + private Boolean autoFragment; + private Long maxFrameSize; + private Integer outputBufferSize; + private Integer inputBufferSize; + private Long maxBinaryMessageSize; + private Long maxTextMessageSize; + + @Override + public Duration getIdleTimeout() + { + return idleTimeout == null ? WebSocketConstants.DEFAULT_IDLE_TIMEOUT : idleTimeout; + } + + @Override + public Duration getWriteTimeout() + { + return writeTimeout == null ? WebSocketConstants.DEFAULT_WRITE_TIMEOUT : writeTimeout; + } + + @Override + public void setIdleTimeout(Duration timeout) + { + this.idleTimeout = timeout; + } + + @Override + public void setWriteTimeout(Duration timeout) + { + this.writeTimeout = timeout; + } + + @Override + public boolean isAutoFragment() + { + return autoFragment == null ? WebSocketConstants.DEFAULT_AUTO_FRAGMENT : autoFragment; + } + + @Override + public void setAutoFragment(boolean autoFragment) + { + this.autoFragment = autoFragment; + } + + @Override + public long getMaxFrameSize() + { + return maxFrameSize == null ? WebSocketConstants.DEFAULT_MAX_FRAME_SIZE : maxFrameSize; + } + + @Override + public void setMaxFrameSize(long maxFrameSize) + { + this.maxFrameSize = maxFrameSize; + } + + @Override + public int getOutputBufferSize() + { + return outputBufferSize == null ? WebSocketConstants.DEFAULT_OUTPUT_BUFFER_SIZE : outputBufferSize; + } + + @Override + public void setOutputBufferSize(int outputBufferSize) + { + this.outputBufferSize = outputBufferSize; + } + + @Override + public int getInputBufferSize() + { + return inputBufferSize == null ? WebSocketConstants.DEFAULT_INPUT_BUFFER_SIZE : inputBufferSize; + } + + @Override + public void setInputBufferSize(int inputBufferSize) + { + this.inputBufferSize = inputBufferSize; + } + + @Override + public long getMaxBinaryMessageSize() + { + return maxBinaryMessageSize == null ? WebSocketConstants.DEFAULT_MAX_BINARY_MESSAGE_SIZE : maxBinaryMessageSize; + } + + @Override + public void setMaxBinaryMessageSize(long maxBinaryMessageSize) + { + this.maxBinaryMessageSize = maxBinaryMessageSize; + } + + @Override + public long getMaxTextMessageSize() + { + return maxTextMessageSize == null ? WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE : maxTextMessageSize; + } + + @Override + public void setMaxTextMessageSize(long maxTextMessageSize) + { + this.maxTextMessageSize = maxTextMessageSize; + } + + @Override + public void customize(Configuration configurable) + { + if (idleTimeout != null) + configurable.setIdleTimeout(idleTimeout); + if (writeTimeout != null) + configurable.setWriteTimeout(writeTimeout); + if (autoFragment != null) + configurable.setAutoFragment(autoFragment); + if (maxFrameSize != null) + configurable.setMaxFrameSize(maxFrameSize); + if (inputBufferSize != null) + configurable.setInputBufferSize(inputBufferSize); + if (outputBufferSize != null) + configurable.setOutputBufferSize(outputBufferSize); + if (maxBinaryMessageSize != null) + configurable.setMaxBinaryMessageSize(maxBinaryMessageSize); + if (maxTextMessageSize != null) + configurable.setMaxTextMessageSize(maxTextMessageSize); + } + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CoreSession.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CoreSession.java new file mode 100644 index 00000000000..8f298677a6d --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CoreSession.java @@ -0,0 +1,282 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.URI; +import java.util.List; +import java.util.Map; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.util.Callback; + +/** + * Represents the outgoing Frames. + */ +public interface CoreSession extends OutgoingFrames, Configuration +{ + /** + * The negotiated WebSocket Sub-Protocol for this session. + * + * @return the negotiated WebSocket Sub-Protocol for this session. + */ + String getNegotiatedSubProtocol(); + + /** + * The negotiated WebSocket Extension Configurations for this session. + * + * @return the list of Negotiated Extension Configurations for this session. + */ + List getNegotiatedExtensions(); + + /** + * The parameter map (from URI Query) for the active session. + * + * @return the immutable map of parameters + */ + Map> getParameterMap(); + + /** + * The active {@code Sec-WebSocket-Version} (protocol version) in use. + * + * @return the protocol version in use. + */ + String getProtocolVersion(); + + /** + * The active connection's Request URI. + * This is the URI of the upgrade request and is typically http: or https: rather than + * the ws: or wss: scheme. + * + * @return the absolute URI (including Query string) + */ + URI getRequestURI(); + + /** + * The active connection's Secure status indicator. + * + * @return true if connection is secure (similar in role to {@code HttpServletRequest.isSecure()}) + */ + boolean isSecure(); + + /** + * @return Client or Server behaviour + */ + Behavior getBehavior(); + + /** + * TODO + * @return + */ + WebSocketComponents getWebSocketComponents(); + + /** + * @return The shared ByteBufferPool + */ + ByteBufferPool getByteBufferPool(); + + /** + * The Local Socket Address for the connection + *

        + * Do not assume that this will return a {@link InetSocketAddress} in all cases. + * Use of various proxies, and even UnixSockets can result a SocketAddress being returned + * without supporting {@link InetSocketAddress} + *

        + * + * @return the SocketAddress for the local connection, or null if not supported by Session + */ + SocketAddress getLocalAddress(); + + /** + * The Remote Socket Address for the connection + *

        + * Do not assume that this will return a {@link InetSocketAddress} in all cases. + * Use of various proxies, and even UnixSockets can result a SocketAddress being returned + * without supporting {@link InetSocketAddress} + *

        + * + * @return the SocketAddress for the remote connection, or null if not supported by Session + */ + SocketAddress getRemoteAddress(); + + /** + * @return True if the websocket is open outbound + */ + boolean isOutputOpen(); + + /** + * If using BatchMode.ON or BatchMode.AUTO, trigger a flush of enqueued / batched frames. + * + * @param callback the callback to track close frame sent (or failed) + */ + void flush(Callback callback); + + /** + * Initiate close handshake, no payload (no declared status code or reason phrase) + * + * @param callback the callback to track close frame sent (or failed) + */ + void close(Callback callback); + + /** + * Initiate close handshake with provide status code and optional reason phrase. + * + * @param statusCode the status code (should be a valid status code that can be sent) + * @param reason optional reason phrase (will be truncated automatically by implementation to fit within limits of protocol) + * @param callback the callback to track close frame sent (or failed) + */ + void close(int statusCode, String reason, Callback callback); + + /** + * Issue a harsh abort of the underlying connection. + *

        + * This will terminate the connection, without sending a websocket close frame. + * No WebSocket Protocol close handshake will be performed. + *

        + *

        + * Once called, any read/write activity on the websocket from this point will be indeterminate. + * This can result in the {@link FrameHandler#onError(Throwable, Callback)} event being called indicating any issue that arises. + *

        + *

        + * Once the underlying connection has been determined to be closed, the {@link FrameHandler#onClosed(CloseStatus, Callback)} event will be called. + *

        + */ + void abort(); + + /** + * Manage flow control by indicating demand for handling Frames. A call to + * {@link FrameHandler#onFrame(Frame, Callback)} will only be made if a + * corresponding demand has been signaled. It is an error to call this method + * if {@link FrameHandler#isDemanding()} returns false. + * + * @param n The number of frames that can be handled (in sequential calls to + * {@link FrameHandler#onFrame(Frame, Callback)}). May not be negative. + */ + void demand(long n); + + class Empty extends ConfigurationCustomizer implements CoreSession + { + @Override + public String getNegotiatedSubProtocol() + { + return null; + } + + @Override + public List getNegotiatedExtensions() + { + return null; + } + + @Override + public Map> getParameterMap() + { + return null; + } + + @Override + public String getProtocolVersion() + { + return null; + } + + @Override + public URI getRequestURI() + { + return null; + } + + @Override + public boolean isSecure() + { + return false; + } + + @Override + public void abort() + { + } + + @Override + public Behavior getBehavior() + { + return null; + } + + @Override + public WebSocketComponents getWebSocketComponents() + { + return null; + } + + @Override + public ByteBufferPool getByteBufferPool() + { + return null; + } + + @Override + public SocketAddress getLocalAddress() + { + return null; + } + + @Override + public SocketAddress getRemoteAddress() + { + return null; + } + + @Override + public boolean isOutputOpen() + { + return false; + } + + @Override + public void flush(Callback callback) + { + callback.succeeded(); + } + + @Override + public void close(Callback callback) + { + callback.succeeded(); + } + + @Override + public void close(int statusCode, String reason, Callback callback) + { + callback.succeeded(); + } + + @Override + public void demand(long n) + { + } + + @Override + public void sendFrame(Frame frame, Callback callback, boolean batch) + { + callback.succeeded(); + } + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Extension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Extension.java index 0fd66060372..9e67ffa51c5 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Extension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Extension.java @@ -1,25 +1,23 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; -import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; - /** * Interface for WebSocket Extensions. *

        @@ -88,7 +86,8 @@ public interface Extension extends IncomingFrames, OutgoingFrames void setNextOutgoingFrames(OutgoingFrames nextOutgoing); /** - * Set the {@link WebSocketCoreSession} for this Extension + * Set the {@link CoreSession} for this Extension. + * @param coreSession */ - void setWebSocketCoreSession(WebSocketCoreSession coreSession); + void setCoreSession(CoreSession coreSession); } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java index cabb98c8f85..28be0a3e4f6 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -26,9 +26,11 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.jetty.http.QuotedCSV; import org.eclipse.jetty.util.ArrayTrie; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; /** @@ -161,16 +163,24 @@ public class ExtensionConfig public ExtensionConfig(String parameterizedName) { ParamParser paramParser = new ParamParser(parameterizedName); - List keys = paramParser.parse(); + paramParser.parse(); + this.name = paramParser.getName(); + this.parameters = paramParser.getParams(); + } - if (keys.size() > 1) - throw new IllegalStateException("parameterizedName contains multiple ExtensionConfigs: " + parameterizedName); - if (keys.isEmpty()) - throw new IllegalStateException("parameterizedName contains no ExtensionConfigs: " + parameterizedName); + public boolean isInternalExtension() + { + return name.startsWith("@"); + } - this.name = keys.get(0); - this.parameters = new HashMap<>(); - this.parameters.putAll(paramParser.params.get(this.name)); + public List> getInternalParameters() + { + return parameters.entrySet().stream().filter(entry -> entry.getKey().startsWith("@")).collect(Collectors.toList()); + } + + public void removeInternalParameters() + { + parameters.entrySet().removeIf(entry -> entry.getKey().startsWith("@")); } public String getName() @@ -216,6 +226,27 @@ public class ExtensionConfig return str.toString(); } + public final String getParameterizedNameWithoutInternalParams() + { + StringBuilder str = new StringBuilder(); + str.append(name); + for (String param : parameters.keySet()) + { + if (param.startsWith("@")) + continue; + + str.append(';'); + str.append(param); + String value = parameters.get(param); + if (value != null) + { + str.append('='); + quoteIfNeeded(str, value); + } + } + return str.toString(); + } + public static void quoteIfNeeded(StringBuilder buf, String str) { if (str == null) @@ -282,17 +313,29 @@ public class ExtensionConfig private static class ParamParser extends QuotedCSV { - Map> params; + private final String parameterizedName; + private String name; + private Map params = new HashMap<>(); - public ParamParser(String rawParams) + public ParamParser(String parameterizedName) { - super(false, rawParams); + super(false); + this.parameterizedName = parameterizedName; + } + + public String getName() + { + return name; + } + + public Map getParams() + { + return params; } @Override protected void parsedParam(StringBuffer buffer, int valueLength, int paramNameIdx, int paramValueIdx) { - String extName = buffer.substring(0, valueLength); String paramName = ""; String paramValue = null; @@ -306,9 +349,7 @@ public class ExtensionConfig paramName = buffer.substring(paramNameIdx); } - Map paramMap = getParamMap(extName); - paramMap.put(paramName, paramValue); - + params.put(paramName, paramValue); super.parsedParam(buffer, valueLength, paramNameIdx, paramValueIdx); } @@ -316,35 +357,17 @@ public class ExtensionConfig protected void parsedValue(StringBuffer buffer) { String extName = buffer.toString(); - getParamMap(extName); + if (name != null) + throw new IllegalArgumentException("parameterizedName contains multiple ExtensionConfigs: " + parameterizedName); + name = extName; super.parsedValue(buffer); } - private Map getParamMap(String extName) + public void parse() { - if (params == null) - { - params = new HashMap<>(); - } - - Map paramMap = params.get(extName); - if (paramMap == null) - { - paramMap = new HashMap<>(); - params.put(extName, paramMap); - } - return paramMap; - } - - public List parse() - { - Iterator iter = iterator(); - while (iter.hasNext()) - { - iter.next(); - } - - return new ArrayList<>(params.keySet()); + addValue(parameterizedName); + if (StringUtil.isEmpty(name)) + throw new IllegalArgumentException("parameterizedName contains no ExtensionConfigs: " + parameterizedName); } } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Frame.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Frame.java index 3aea6897147..5c44d9c4e77 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Frame.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/Frame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -221,6 +221,13 @@ public class Frame return payload; } + /** + * Get the payload of the frame as a UTF-8 string. + *

        Should only be used in testing, does not validate the + * UTF-8 and a non fin frame can contain partial UTF-8 characters.

        + * + * @return the payload as a UTF-8 string. + */ public String getPayloadAsUTF8() { if (payload == null) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java index 16fd5bcc3a1..2e16bee68a2 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java @@ -1,31 +1,23 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.URI; -import java.time.Duration; -import java.util.List; -import java.util.Map; - -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.core.server.Negotiation; @@ -129,443 +121,4 @@ public interface FrameHandler extends IncomingFrames { return false; } - - interface Configuration - { - - /** - * Get the Idle Timeout - * - * @return the idle timeout - */ - Duration getIdleTimeout(); - - /** - * Get the Write Timeout - * - * @return the write timeout - */ - Duration getWriteTimeout(); - - /** - * Set the Idle Timeout. - * - * @param timeout the timeout duration (timeout <= 0 implies an infinite timeout) - */ - void setIdleTimeout(Duration timeout); - - /** - * Set the Write Timeout. - * - * @param timeout the timeout duration (timeout <= 0 implies an infinite timeout) - */ - void setWriteTimeout(Duration timeout); - - boolean isAutoFragment(); - - void setAutoFragment(boolean autoFragment); - - long getMaxFrameSize(); - - void setMaxFrameSize(long maxFrameSize); - - int getOutputBufferSize(); - - void setOutputBufferSize(int outputBufferSize); - - int getInputBufferSize(); - - void setInputBufferSize(int inputBufferSize); - - long getMaxBinaryMessageSize(); - - void setMaxBinaryMessageSize(long maxSize); - - long getMaxTextMessageSize(); - - void setMaxTextMessageSize(long maxSize); - } - - /** - * Represents the outgoing Frames. - */ - interface CoreSession extends OutgoingFrames, Configuration - { - /** - * The negotiated WebSocket Sub-Protocol for this session. - * - * @return the negotiated WebSocket Sub-Protocol for this session. - */ - String getNegotiatedSubProtocol(); - - /** - * The negotiated WebSocket Extension Configurations for this session. - * - * @return the list of Negotiated Extension Configurations for this session. - */ - List getNegotiatedExtensions(); - - /** - * The parameter map (from URI Query) for the active session. - * - * @return the immutable map of parameters - */ - Map> getParameterMap(); - - /** - * The active {@code Sec-WebSocket-Version} (protocol version) in use. - * - * @return the protocol version in use. - */ - String getProtocolVersion(); - - /** - * The active connection's Request URI. - * This is the URI of the upgrade request and is typically http: or https: rather than - * the ws: or wss: scheme. - * - * @return the absolute URI (including Query string) - */ - URI getRequestURI(); - - /** - * The active connection's Secure status indicator. - * - * @return true if connection is secure (similar in role to {@code HttpServletRequest.isSecure()}) - */ - boolean isSecure(); - - /** - * @return Client or Server behaviour - */ - Behavior getBehavior(); - - /** - * @return The shared ByteBufferPool - */ - ByteBufferPool getByteBufferPool(); - - /** - * The Local Socket Address for the connection - *

        - * Do not assume that this will return a {@link InetSocketAddress} in all cases. - * Use of various proxies, and even UnixSockets can result a SocketAddress being returned - * without supporting {@link InetSocketAddress} - *

        - * - * @return the SocketAddress for the local connection, or null if not supported by Session - */ - SocketAddress getLocalAddress(); - - /** - * The Remote Socket Address for the connection - *

        - * Do not assume that this will return a {@link InetSocketAddress} in all cases. - * Use of various proxies, and even UnixSockets can result a SocketAddress being returned - * without supporting {@link InetSocketAddress} - *

        - * - * @return the SocketAddress for the remote connection, or null if not supported by Session - */ - SocketAddress getRemoteAddress(); - - /** - * @return True if the websocket is open outbound - */ - boolean isOutputOpen(); - - /** - * If using BatchMode.ON or BatchMode.AUTO, trigger a flush of enqueued / batched frames. - * - * @param callback the callback to track close frame sent (or failed) - */ - void flush(Callback callback); - - /** - * Initiate close handshake, no payload (no declared status code or reason phrase) - * - * @param callback the callback to track close frame sent (or failed) - */ - void close(Callback callback); - - /** - * Initiate close handshake with provide status code and optional reason phrase. - * - * @param statusCode the status code (should be a valid status code that can be sent) - * @param reason optional reason phrase (will be truncated automatically by implementation to fit within limits of protocol) - * @param callback the callback to track close frame sent (or failed) - */ - void close(int statusCode, String reason, Callback callback); - - /** - * Issue a harsh abort of the underlying connection. - *

        - * This will terminate the connection, without sending a websocket close frame. - * No WebSocket Protocol close handshake will be performed. - *

        - *

        - * Once called, any read/write activity on the websocket from this point will be indeterminate. - * This can result in the {@link #onError(Throwable, Callback)} event being called indicating any issue that arises. - *

        - *

        - * Once the underlying connection has been determined to be closed, the {@link #onClosed(CloseStatus, Callback)} event will be called. - *

        - */ - void abort(); - - /** - * Manage flow control by indicating demand for handling Frames. A call to - * {@link FrameHandler#onFrame(Frame, Callback)} will only be made if a - * corresponding demand has been signaled. It is an error to call this method - * if {@link FrameHandler#isDemanding()} returns false. - * - * @param n The number of frames that can be handled (in sequential calls to - * {@link FrameHandler#onFrame(Frame, Callback)}). May not be negative. - */ - void demand(long n); - - class Empty extends ConfigurationCustomizer implements CoreSession - { - @Override - public String getNegotiatedSubProtocol() - { - return null; - } - - @Override - public List getNegotiatedExtensions() - { - return null; - } - - @Override - public Map> getParameterMap() - { - return null; - } - - @Override - public String getProtocolVersion() - { - return null; - } - - @Override - public URI getRequestURI() - { - return null; - } - - @Override - public boolean isSecure() - { - return false; - } - - @Override - public void abort() - { - } - - @Override - public Behavior getBehavior() - { - return null; - } - - @Override - public ByteBufferPool getByteBufferPool() - { - return null; - } - - @Override - public SocketAddress getLocalAddress() - { - return null; - } - - @Override - public SocketAddress getRemoteAddress() - { - return null; - } - - @Override - public boolean isOutputOpen() - { - return false; - } - - @Override - public void flush(Callback callback) - { - } - - @Override - public void close(Callback callback) - { - } - - @Override - public void close(int statusCode, String reason, Callback callback) - { - } - - @Override - public void demand(long n) - { - } - - @Override - public void sendFrame(Frame frame, Callback callback, boolean batch) - { - } - } - } - - interface Customizer - { - void customize(Configuration configurable); - } - - class ConfigurationHolder implements Configuration - { - protected Duration idleTimeout; - protected Duration writeTimeout; - protected Boolean autoFragment; - protected Long maxFrameSize; - protected Integer outputBufferSize; - protected Integer inputBufferSize; - protected Long maxBinaryMessageSize; - protected Long maxTextMessageSize; - - @Override - public Duration getIdleTimeout() - { - return idleTimeout == null ? WebSocketConstants.DEFAULT_IDLE_TIMEOUT : idleTimeout; - } - - @Override - public Duration getWriteTimeout() - { - return writeTimeout == null ? WebSocketConstants.DEFAULT_WRITE_TIMEOUT : writeTimeout; - } - - @Override - public void setIdleTimeout(Duration timeout) - { - this.idleTimeout = timeout; - } - - @Override - public void setWriteTimeout(Duration timeout) - { - this.writeTimeout = timeout; - } - - @Override - public boolean isAutoFragment() - { - return autoFragment == null ? WebSocketConstants.DEFAULT_AUTO_FRAGMENT : autoFragment; - } - - @Override - public void setAutoFragment(boolean autoFragment) - { - this.autoFragment = autoFragment; - } - - @Override - public long getMaxFrameSize() - { - return maxFrameSize == null ? WebSocketConstants.DEFAULT_MAX_FRAME_SIZE : maxFrameSize; - } - - @Override - public void setMaxFrameSize(long maxFrameSize) - { - this.maxFrameSize = maxFrameSize; - } - - @Override - public int getOutputBufferSize() - { - return outputBufferSize == null ? WebSocketConstants.DEFAULT_OUTPUT_BUFFER_SIZE : outputBufferSize; - } - - @Override - public void setOutputBufferSize(int outputBufferSize) - { - this.outputBufferSize = outputBufferSize; - } - - @Override - public int getInputBufferSize() - { - return inputBufferSize == null ? WebSocketConstants.DEFAULT_INPUT_BUFFER_SIZE : inputBufferSize; - } - - @Override - public void setInputBufferSize(int inputBufferSize) - { - this.inputBufferSize = inputBufferSize; - } - - @Override - public long getMaxBinaryMessageSize() - { - return maxBinaryMessageSize == null ? WebSocketConstants.DEFAULT_MAX_BINARY_MESSAGE_SIZE : maxBinaryMessageSize; - } - - @Override - public void setMaxBinaryMessageSize(long maxBinaryMessageSize) - { - this.maxBinaryMessageSize = maxBinaryMessageSize; - } - - @Override - public long getMaxTextMessageSize() - { - return maxTextMessageSize == null ? WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE : maxTextMessageSize; - } - - @Override - public void setMaxTextMessageSize(long maxTextMessageSize) - { - this.maxTextMessageSize = maxTextMessageSize; - } - } - - class ConfigurationCustomizer extends ConfigurationHolder implements Customizer - { - @Override - public void customize(Configuration configurable) - { - if (idleTimeout != null) - configurable.setIdleTimeout(idleTimeout); - if (writeTimeout != null) - configurable.setWriteTimeout(idleTimeout); - if (autoFragment != null) - configurable.setAutoFragment(autoFragment); - if (maxFrameSize != null) - configurable.setMaxFrameSize(maxFrameSize); - if (inputBufferSize != null) - configurable.setInputBufferSize(inputBufferSize); - if (outputBufferSize != null) - configurable.setOutputBufferSize(outputBufferSize); - if (maxBinaryMessageSize != null) - configurable.setMaxBinaryMessageSize(maxBinaryMessageSize); - if (maxTextMessageSize != null) - configurable.setMaxTextMessageSize(maxTextMessageSize); - } - - public static ConfigurationCustomizer from(ConfigurationCustomizer parent, ConfigurationCustomizer child) - { - ConfigurationCustomizer customizer = new ConfigurationCustomizer(); - parent.customize(customizer); - child.customize(customizer); - return customizer; - } - } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/IncomingFrames.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/IncomingFrames.java index 6902e6f7f36..f63f4314b5d 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/IncomingFrames.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/IncomingFrames.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageHandler.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageHandler.java index 86d962b5f2e..4a2620ddf4d 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageHandler.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -27,15 +27,17 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingNestedCallback; import org.eclipse.jetty.util.Utf8Appendable; import org.eclipse.jetty.util.Utf8StringBuilder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.exception.BadPayloadException; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A utility implementation of FrameHandler that defragments * text frames into a String message before calling {@link #onText(String, Callback)}. * Flow control is by default automatic, but an implementation * may extend {@link #isDemanding()} to return true and then explicityly control - * demand with calls to {@link org.eclipse.jetty.websocket.core.FrameHandler.CoreSession#demand(long)} + * demand with calls to {@link CoreSession#demand(long)} */ public class MessageHandler implements FrameHandler { @@ -85,7 +87,7 @@ public class MessageHandler implements FrameHandler }; } - protected static final Logger LOG = Log.getLogger(MessageHandler.class); + protected static final Logger LOG = LoggerFactory.getLogger(MessageHandler.class); private CoreSession coreSession; private Utf8StringBuilder textMessageBuffer; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageTooLargeException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageTooLargeException.java deleted file mode 100644 index b6e8ff47f48..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/MessageTooLargeException.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -/** - * Exception when a message is too large for the internal buffers occurs and should trigger a connection close. - * - * @see RFC6455 : Section 7.4.1 - */ -@SuppressWarnings("serial") -public class MessageTooLargeException extends CloseException -{ - public MessageTooLargeException(String message) - { - super(CloseStatus.MESSAGE_TOO_LARGE, message); - } - - public MessageTooLargeException(String message, Throwable t) - { - super(CloseStatus.MESSAGE_TOO_LARGE, message, t); - } - - public MessageTooLargeException(Throwable t) - { - super(CloseStatus.MESSAGE_TOO_LARGE, t); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/NullAppendable.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/NullAppendable.java deleted file mode 100644 index 6dde40e4d7a..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/NullAppendable.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -import org.eclipse.jetty.util.Utf8Appendable; - -public class NullAppendable extends Utf8Appendable -{ - public NullAppendable() - { - super(new Appendable() - { - @Override - public Appendable append(CharSequence csq) - { - return null; - } - - @Override - public Appendable append(CharSequence csq, int start, int end) - { - return null; - } - - @Override - public Appendable append(char c) - { - return null; - } - }); - } - - @Override - public int length() - { - return 0; - } - - @Override - public String getPartialString() - { - return null; - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OpCode.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OpCode.java index 19f298b6d00..bef19ec377d 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OpCode.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OpCode.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OutgoingFrames.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OutgoingFrames.java index a435a3c3c8b..06ef6aec7d6 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OutgoingFrames.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/OutgoingFrames.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ProtocolException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ProtocolException.java deleted file mode 100644 index 9aa97fa98d0..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ProtocolException.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -/** - * Per spec, a protocol error should result in a Close frame of status code 1002 (PROTOCOL_ERROR) - * - * @see RFC6455 : Section 7.4.1 - */ -@SuppressWarnings("serial") -public class ProtocolException extends CloseException -{ - public ProtocolException(String message) - { - super(CloseStatus.PROTOCOL, message); - } - - public ProtocolException(String message, Throwable t) - { - super(CloseStatus.PROTOCOL, message, t); - } - - public ProtocolException(Throwable t) - { - super(CloseStatus.PROTOCOL, t); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketComponents.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketComponents.java index 60c451d6554..1f5d593f7fd 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketComponents.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketComponents.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -99,4 +99,4 @@ public class WebSocketComponents { return deflaterPool; } -} \ No newline at end of file +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketConstants.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketConstants.java index a669683d55a..d29d3c35304 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketConstants.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketConstants.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketException.java deleted file mode 100644 index 2da71d2f94d..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketException.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -/** - * A recoverable exception within the websocket framework. - */ -@SuppressWarnings("serial") -public class WebSocketException extends RuntimeException -{ - public WebSocketException() - { - super(); - } - - public WebSocketException(String message) - { - super(message); - } - - public WebSocketException(String message, Throwable cause) - { - super(message, cause); - } - - public WebSocketException(Throwable cause) - { - super(cause); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketExtensionRegistry.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketExtensionRegistry.java index 0e71b730ed3..a6b55884f68 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketExtensionRegistry.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketExtensionRegistry.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -26,23 +26,17 @@ import java.util.Set; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; public class WebSocketExtensionRegistry implements Iterable> { - private Map> availableExtensions; + private Map> availableExtensions = new HashMap<>(); public WebSocketExtensionRegistry() { - // Load extensions from container loader - ServiceLoader extensionLoader = ServiceLoader.load(Extension.class, this.getClass().getClassLoader()); - availableExtensions = new HashMap<>(); - for (Extension ext : extensionLoader) - { - if (ext != null) - { - availableExtensions.put(ext.getName(), ext.getClass()); - } - } + // Load extensions from container loader. + TypeUtil.serviceStream(ServiceLoader.load(Extension.class, this.getClass().getClassLoader())) + .forEach(ext -> availableExtensions.put(ext.getName(), ext.getClass())); } public Map> getAvailableExtensions() diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketTimeoutException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketTimeoutException.java deleted file mode 100644 index 8dcfab5b104..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketTimeoutException.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -/** - * Exception thrown to indicate a connection I/O timeout. - */ -public class WebSocketTimeoutException extends WebSocketException -{ - private static final long serialVersionUID = -6145098200250676673L; - - public WebSocketTimeoutException(String message) - { - super(message); - } - - public WebSocketTimeoutException(String message, Throwable cause) - { - super(message, cause); - } - - public WebSocketTimeoutException(Throwable cause) - { - super(cause); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketWriteTimeoutException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketWriteTimeoutException.java deleted file mode 100644 index 2dabed13133..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/WebSocketWriteTimeoutException.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core; - -public class WebSocketWriteTimeoutException extends WebSocketTimeoutException -{ - public WebSocketWriteTimeoutException(String message) - { - super(message); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java index 139e355df63..c37918952fe 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java @@ -1,31 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.client; +import java.io.IOException; import java.net.URI; import java.util.ArrayList; -import java.util.Base64; +import java.util.Arrays; +import java.util.Iterator; import java.util.List; -import java.util.Locale; +import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.ThreadLocalRandom; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -33,41 +33,36 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpConversation; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; -import org.eclipse.jetty.client.http.HttpConnectionUpgrader; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.core.Behavior; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.UpgradeException; import org.eclipse.jetty.websocket.core.WebSocketConstants; -import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.UpgradeException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; import org.eclipse.jetty.websocket.core.internal.Negotiated; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; -import org.eclipse.jetty.websocket.core.internal.WebSocketCore; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public abstract class ClientUpgradeRequest extends HttpRequest implements Response.CompleteListener, HttpConnectionUpgrader +public abstract class ClientUpgradeRequest extends HttpRequest implements Response.CompleteListener, HttpUpgrader.Factory { public static ClientUpgradeRequest from(WebSocketCoreClient webSocketClient, URI requestURI, FrameHandler frameHandler) { @@ -81,12 +76,13 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon }; } - private static final Logger LOG = Log.getLogger(ClientUpgradeRequest.class); - protected final CompletableFuture futureCoreSession; + private static final Logger LOG = LoggerFactory.getLogger(ClientUpgradeRequest.class); + protected final CompletableFuture futureCoreSession; private final WebSocketCoreClient wsClient; private FrameHandler frameHandler; - private FrameHandler.ConfigurationCustomizer customizer = new FrameHandler.ConfigurationCustomizer(); + private Configuration.ConfigurationCustomizer customizer = new Configuration.ConfigurationCustomizer(); private List upgradeListeners = new ArrayList<>(); + private List requestedExtensions = new ArrayList<>(); public ClientUpgradeRequest(WebSocketCoreClient webSocketClient, URI requestURI) { @@ -103,8 +99,8 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon throw new IllegalArgumentException("WebSocket URI must include a scheme"); } - String scheme = requestURI.getScheme().toLowerCase(Locale.ENGLISH); - if (("ws".equals(scheme) == false) && ("wss".equals(scheme) == false)) + String scheme = requestURI.getScheme(); + if (!HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme)) { throw new IllegalArgumentException("WebSocket URI scheme only supports [ws] and [wss], not [" + scheme + "]"); } @@ -116,13 +112,9 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon this.wsClient = webSocketClient; this.futureCoreSession = new CompletableFuture<>(); - method(HttpMethod.GET); - version(HttpVersion.HTTP_1_1); - - getConversation().setAttribute(HttpConnectionUpgrader.class.getName(), this); } - public void setConfiguration(FrameHandler.ConfigurationCustomizer config) + public void setConfiguration(Configuration.ConfigurationCustomizer config) { config.customize(customizer); } @@ -134,46 +126,30 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon public void addExtensions(ExtensionConfig... configs) { - HttpFields headers = getHeaders(); - for (ExtensionConfig config : configs) - { - headers.add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, config.getParameterizedName()); - } + requestedExtensions.addAll(Arrays.asList(configs)); } public void addExtensions(String... configs) { - HttpFields headers = getHeaders(); for (String config : configs) { - headers.add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, ExtensionConfig.parse(config).getParameterizedName()); + requestedExtensions.add(ExtensionConfig.parse(config)); } } public List getExtensions() { - List extensions = getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, true) - .stream() - .map(ExtensionConfig::parse) - .collect(Collectors.toList()); - - return extensions; + return requestedExtensions; } public void setExtensions(List configs) { - HttpFields headers = getHeaders(); - headers.remove(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); - for (ExtensionConfig config : configs) - { - headers.add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, config.getParameterizedName()); - } + requestedExtensions = configs; } public List getSubProtocols() { - List subProtocols = getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, true); - return subProtocols; + return getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, true); } public void setSubProtocols(String... protocols) @@ -210,11 +186,10 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon throw new IllegalArgumentException("FrameHandler could not be created", t); } - initWebSocketHeaders(); super.send(listener); } - public CompletableFuture sendAsync() + public CompletableFuture sendAsync() { send(this); return futureCoreSession; @@ -247,19 +222,18 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon } Throwable failure = result.getFailure(); - boolean wrapFailure = !((failure instanceof java.net.SocketException) || - (failure instanceof java.io.InterruptedIOException) || - (failure instanceof UpgradeException)); + boolean wrapFailure = !(failure instanceof IOException) && !(failure instanceof UpgradeException); if (wrapFailure) failure = new UpgradeException(requestURI, responseStatusCode, responseLine, failure); handleException(failure); + return; } if (responseStatusCode != HttpStatus.SWITCHING_PROTOCOLS_101) { // Failed to upgrade (other reason) - handleException( - new UpgradeException(requestURI, responseStatusCode, "Failed to upgrade to websocket: Unexpected HTTP Response Status Code: " + responseLine)); + handleException(new UpgradeException(requestURI, responseStatusCode, + "Failed to upgrade to websocket: Unexpected HTTP Response Status Code: " + responseLine)); } } @@ -279,20 +253,70 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon } } - @SuppressWarnings("Duplicates") @Override - public void upgrade(HttpResponse response, HttpConnectionOverHTTP httpConnection) + public HttpUpgrader newHttpUpgrader(HttpVersion version) { - if (!this.getHeaders().get(HttpHeader.UPGRADE).equalsIgnoreCase("websocket")) - throw new HttpResponseException("Not a WebSocket Upgrade", response); + if (version == HttpVersion.HTTP_1_1) + return new HttpUpgraderOverHTTP(this); + else if (version == HttpVersion.HTTP_2) + return new HttpUpgraderOverHTTP2(this); + else + throw new UnsupportedOperationException("Unsupported HTTP version for upgrade: " + version); + } - // Check the Accept hash - String reqKey = this.getHeaders().get(HttpHeader.SEC_WEBSOCKET_KEY); - String expectedHash = WebSocketCore.hashKey(reqKey); - String respHash = response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_ACCEPT); - if (expectedHash.equalsIgnoreCase(respHash) == false) - throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash (was:" + respHash + ", expected:" + expectedHash + ")", response); + /** + * Allow for overridden customization of endpoint (such as special transport level properties: e.g. TCP keepAlive) + */ + protected void customize(EndPoint endPoint) + { + } + public abstract FrameHandler getFrameHandler(); + + void requestComplete() + { + // Add extensions header filtering out internal extensions and internal parameters. + String extensionString = requestedExtensions.stream() + .filter(ec -> !ec.getName().startsWith("@")) + .map(ExtensionConfig::getParameterizedNameWithoutInternalParams) + .collect(Collectors.joining(",")); + + if (!StringUtil.isEmpty(extensionString)) + getHeaders().add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, extensionString); + + // Notify the listener which may change the headers directly. + notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); + + // Check if extensions were set in the headers from the upgrade listener. + String extsAfterListener = String.join(",", getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, true)); + if (!extensionString.equals(extsAfterListener)) + { + // If extensions were set in both the ClientUpgradeRequest and UpgradeListener throw ISE. + if (!requestedExtensions.isEmpty()) + abort(new IllegalStateException("Extensions set in both the ClientUpgradeRequest and UpgradeListener")); + + // Otherwise reparse the new set of requested extensions. + requestedExtensions = ExtensionConfig.parseList(extsAfterListener); + } + } + + private void notifyUpgradeListeners(Consumer action) + { + for (UpgradeListener listener : upgradeListeners) + { + try + { + action.accept(listener); + } + catch (Throwable t) + { + LOG.info("Exception while invoking listener " + listener, t); + } + } + } + + public void upgrade(HttpResponse response, EndPoint endPoint) + { // Parse the Negotiated Extensions List negotiatedExtensions = new ArrayList<>(); HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); @@ -312,25 +336,61 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon } } + // Get list of negotiated extensions with internal extensions in the correct order. + List negotiatedWithInternal = new ArrayList<>(requestedExtensions); + for (Iterator iterator = negotiatedWithInternal.iterator(); iterator.hasNext();) + { + ExtensionConfig extConfig = iterator.next(); + + // Always keep internal extensions. + if (extConfig.isInternalExtension()) + continue; + + // If it was not negotiated by the server remove. + long negExtsCount = negotiatedExtensions.stream().filter(ec -> extConfig.getName().equals(ec.getName())).count(); + if (negExtsCount < 1) + { + iterator.remove(); + continue; + } + + // Remove if we have duplicates. + long duplicateCount = negotiatedWithInternal.stream().filter(ec -> extConfig.getName().equals(ec.getName())).count(); + if (duplicateCount > 1) + iterator.remove(); + } + // Verify the Negotiated Extensions - List offeredExtensions = getExtensions(); for (ExtensionConfig config : negotiatedExtensions) { if (config.getName().startsWith("@")) continue; - long numMatch = offeredExtensions.stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (numMatch < 1) + boolean wasRequested = false; + for (ExtensionConfig requestedConfig : requestedExtensions) + { + if (config.getName().equalsIgnoreCase(requestedConfig.getName())) + { + for (Map.Entry entry : requestedConfig.getInternalParameters()) + { + config.setParameter(entry.getKey(), entry.getValue()); + } + + wasRequested = true; + break; + } + } + if (!wasRequested) throw new WebSocketException("Upgrade failed: Sec-WebSocket-Extensions contained extension not requested"); - numMatch = negotiatedExtensions.stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (numMatch > 1) + long numExtsWithSameName = negotiatedExtensions.stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (numExtsWithSameName > 1) throw new WebSocketException("Upgrade failed: Sec-WebSocket-Extensions contained more than one extension of the same name"); } // Negotiate the extension stack ExtensionStack extensionStack = new ExtensionStack(wsClient.getWebSocketComponents(), Behavior.CLIENT); - extensionStack.negotiate(offeredExtensions, negotiatedExtensions); + extensionStack.negotiate(requestedExtensions, negotiatedWithInternal); // Get the negotiated subprotocol String negotiatedSubProtocol = null; @@ -341,7 +401,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon if (values != null) { if (values.length > 1) - throw new WebSocketException("Upgrade failed: Too many WebSocket subprotocol's in response: " + values); + throw new WebSocketException("Upgrade failed: Too many WebSocket subprotocol's in response: " + Arrays.toString(values)); else if (values.length == 1) negotiatedSubProtocol = values[0]; } @@ -355,8 +415,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon throw new WebSocketException("Upgrade failed: subprotocol [" + negotiatedSubProtocol + "] not found in offered subprotocols " + offeredSubProtocols); // We can upgrade - EndPoint endp = httpConnection.getEndPoint(); - customize(endp); + customize(endPoint); Request request = response.getRequest(); Negotiated negotiated = new Negotiated( @@ -366,25 +425,19 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon extensionStack, WebSocketConstants.SPEC_VERSION_STRING); - WebSocketCoreSession coreSession = newWebSocketCoreSession(frameHandler, negotiated); + WebSocketCoreSession coreSession = new WebSocketCoreSession(frameHandler, Behavior.CLIENT, negotiated, wsClient.getWebSocketComponents()); customizer.customize(coreSession); HttpClient httpClient = wsClient.getHttpClient(); - WebSocketConnection wsConnection = newWebSocketConnection(endp, httpClient.getExecutor(), httpClient.getScheduler(), httpClient.getByteBufferPool(), coreSession); - - for (Connection.Listener listener : wsClient.getBeans(Connection.Listener.class)) - { - wsConnection.addListener(listener); - } - + WebSocketConnection wsConnection = new WebSocketConnection(endPoint, httpClient.getExecutor(), httpClient.getScheduler(), httpClient.getByteBufferPool(), coreSession); + wsClient.getEventListeners().forEach(wsConnection::addEventListener); coreSession.setWebSocketConnection(wsConnection); - notifyUpgradeListeners((listener) -> listener.onHandshakeResponse(this, response)); // Now swap out the connection try { - endp.upgrade(wsConnection); + endPoint.upgrade(wsConnection); futureCoreSession.complete(coreSession); } catch (Throwable t) @@ -392,79 +445,4 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon futureCoreSession.completeExceptionally(t); } } - - /** - * Allow for overridden customization of endpoint (such as special transport level properties: e.g. TCP keepAlive) - * - * @see Issue #1811 - Customization of WebSocket Connections via WebSocketPolicy - */ - protected void customize(EndPoint endp) - { - } - - protected WebSocketConnection newWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) - { - return new WebSocketConnection(endp, executor, scheduler, byteBufferPool, coreSession); - } - - protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) - { - return new WebSocketCoreSession(handler, Behavior.CLIENT, negotiated); - } - - public abstract FrameHandler getFrameHandler(); - - private final String genRandomKey() - { - byte[] bytes = new byte[16]; - ThreadLocalRandom.current().nextBytes(bytes); - return Base64.getEncoder().encodeToString(bytes); - } - - private void initWebSocketHeaders() - { - method(HttpMethod.GET); - version(HttpVersion.HTTP_1_1); - - // The Upgrade Headers - setHeaderIfNotPresent(HttpHeader.UPGRADE, "websocket"); - setHeaderIfNotPresent(HttpHeader.CONNECTION, "Upgrade"); - - // The WebSocket Headers - setHeaderIfNotPresent(HttpHeader.SEC_WEBSOCKET_KEY, genRandomKey()); - setHeaderIfNotPresent(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); - - // (Per the hybi list): Add no-cache headers to avoid compatibility issue. - // There are some proxies that rewrite "Connection: upgrade" - // to "Connection: close" in the response if a request doesn't contain - // these headers. - setHeaderIfNotPresent(HttpHeader.PRAGMA, "no-cache"); - setHeaderIfNotPresent(HttpHeader.CACHE_CONTROL, "no-cache"); - - // Notify upgrade hooks - notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); - } - - private void setHeaderIfNotPresent(HttpHeader header, String value) - { - if (!getHeaders().contains(header)) - { - getHeaders().put(header, value); - } - } - - private void notifyUpgradeListeners(Consumer action) - { - for (UpgradeListener listener : upgradeListeners) - { - try - { - action.accept(listener); - } - catch (Throwable t) - { - LOG.warn("Unhandled error: " + t.getMessage(), t); - } - } - } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpClientProvider.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpClientProvider.java index 224e10268d1..194cddab347 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpClientProvider.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpClientProvider.java @@ -1,26 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.client; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.slf4j.LoggerFactory; public interface HttpClientProvider { @@ -35,7 +35,7 @@ public interface HttpClientProvider } catch (Throwable x) { - Log.getLogger(HttpClientProvider.class).ignore(x); + LoggerFactory.getLogger(HttpClientProvider.class).trace("IGNORED", x); } return HttpClientProvider.newDefaultHttpClient(); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java new file mode 100644 index 00000000000..a4e2dd6d62e --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java @@ -0,0 +1,106 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.client; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.concurrent.ThreadLocalRandom; + +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.HttpUpgrader; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.WebSocketConstants; +import org.eclipse.jetty.websocket.core.internal.WebSocketCore; + +public class HttpUpgraderOverHTTP implements HttpUpgrader +{ + private final ClientUpgradeRequest clientUpgradeRequest; + + public HttpUpgraderOverHTTP(ClientUpgradeRequest clientUpgradeRequest) + { + this.clientUpgradeRequest = clientUpgradeRequest; + } + + @Override + public void prepare(HttpRequest request) + { + request.method(HttpMethod.GET).version(HttpVersion.HTTP_1_1); + request.header(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); + request.header(HttpHeader.UPGRADE, "websocket"); + request.header(HttpHeader.CONNECTION, "Upgrade"); + request.header(HttpHeader.SEC_WEBSOCKET_KEY, generateRandomKey()); + + // Per the hybi list: Add no-cache headers to avoid compatibility issue. + // There are some proxies that rewrite "Connection: upgrade" to + // "Connection: close" in the response if a request doesn't contain + // these headers. + request.header(HttpHeader.PRAGMA, "no-cache"); + request.header(HttpHeader.CACHE_CONTROL, "no-cache"); + + // Notify the UpgradeListeners now the headers are set. + clientUpgradeRequest.requestComplete(); + } + + private String generateRandomKey() + { + byte[] bytes = new byte[16]; + ThreadLocalRandom.current().nextBytes(bytes); + return new String(Base64.getEncoder().encode(bytes), StandardCharsets.US_ASCII); + } + + @Override + public void upgrade(HttpResponse response, EndPoint endPoint, Callback callback) + { + HttpRequest request = (HttpRequest)response.getRequest(); + HttpFields requestHeaders = request.getHeaders(); + if (requestHeaders.contains(HttpHeader.UPGRADE, "websocket")) + { + HttpFields responseHeaders = response.getHeaders(); + if (responseHeaders.contains(HttpHeader.CONNECTION, "upgrade")) + { + // Check the Accept hash + String reqKey = requestHeaders.get(HttpHeader.SEC_WEBSOCKET_KEY); + String expectedHash = WebSocketCore.hashKey(reqKey); + String respHash = responseHeaders.get(HttpHeader.SEC_WEBSOCKET_ACCEPT); + if (expectedHash.equalsIgnoreCase(respHash)) + { + clientUpgradeRequest.upgrade(response, endPoint); + callback.succeeded(); + } + else + callback.failed(new HttpResponseException("Invalid Sec-WebSocket-Accept hash (was: " + respHash + " expected: " + expectedHash + ")", response)); + } + else + { + callback.failed(new HttpResponseException("WebSocket upgrade missing 'Connection: Upgrade' header", response)); + } + } + else + { + callback.failed(new HttpResponseException("Not a WebSocket upgrade", response)); + } + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java new file mode 100644 index 00000000000..12e1a1bba42 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java @@ -0,0 +1,63 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.client; + +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpUpgrader; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.WebSocketConstants; + +public class HttpUpgraderOverHTTP2 implements HttpUpgrader +{ + private final ClientUpgradeRequest clientUpgradeRequest; + + public HttpUpgraderOverHTTP2(ClientUpgradeRequest clientUpgradeRequest) + { + this.clientUpgradeRequest = clientUpgradeRequest; + } + + @Override + public void prepare(HttpRequest request) + { + request.method(HttpMethod.CONNECT); + request.upgradeProtocol("websocket"); + request.header(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); + + // Notify the UpgradeListeners now the headers are set. + clientUpgradeRequest.requestComplete(); + } + + @Override + public void upgrade(HttpResponse response, EndPoint endPoint, Callback callback) + { + try + { + clientUpgradeRequest.upgrade(response, endPoint); + callback.succeeded(); + } + catch (Throwable x) + { + callback.failed(x); + } + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/UpgradeListener.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/UpgradeListener.java index a6575c67c4e..8f7754902ea 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/UpgradeListener.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/UpgradeListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.client; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/WebSocketCoreClient.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/WebSocketCoreClient.java index 2d13e76fcc3..e4aa450d181 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/WebSocketCoreClient.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/WebSocketCoreClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.client; @@ -26,19 +26,19 @@ import java.util.concurrent.CompletableFuture; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.ShutdownThread; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WebSocketCoreClient extends ContainerLifeCycle { public static final String WEBSOCKET_CORECLIENT_ATTRIBUTE = WebSocketCoreClient.class.getName(); - private static final Logger LOG = Log.getLogger(WebSocketCoreClient.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketCoreClient.class); private final HttpClient httpClient; private WebSocketComponents components; @@ -69,13 +69,13 @@ public class WebSocketCoreClient extends ContainerLifeCycle addBean(httpClient); } - public CompletableFuture connect(FrameHandler frameHandler, URI wsUri) throws IOException + public CompletableFuture connect(FrameHandler frameHandler, URI wsUri) throws IOException { ClientUpgradeRequest request = ClientUpgradeRequest.from(this, wsUri, frameHandler); return connect(request); } - public CompletableFuture connect(ClientUpgradeRequest request) throws IOException + public CompletableFuture connect(ClientUpgradeRequest request) throws IOException { if (!isStarted()) throw new IllegalStateException(WebSocketCoreClient.class.getSimpleName() + "@" + this.hashCode() + " is not started"); @@ -92,20 +92,9 @@ public class WebSocketCoreClient extends ContainerLifeCycle if (LOG.isDebugEnabled()) LOG.debug("connect to websocket {}", request.getURI()); - init(); - return request.sendAsync(); } - // TODO: review need for this. - private synchronized void init() throws IOException - { - if (!ShutdownThread.isRegistered(this)) - { - ShutdownThread.register(this); - } - } - public WebSocketExtensionRegistry getExtensionRegistry() { return components.getExtensionRegistry(); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/XmlHttpClientProvider.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/XmlHttpClientProvider.java index 8eaa3742171..26661385300 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/XmlHttpClientProvider.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/XmlHttpClientProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.client; @@ -21,12 +21,15 @@ package org.eclipse.jetty.websocket.core.client; import java.net.URL; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class XmlHttpClientProvider implements HttpClientProvider { + private static final Logger LOG = LoggerFactory.getLogger(XmlHttpClientProvider.class); + @Override public HttpClient newHttpClient() { @@ -43,7 +46,7 @@ class XmlHttpClientProvider implements HttpClientProvider } catch (Throwable t) { - Log.getLogger(XmlHttpClientProvider.class).warn("Unable to load: " + resource, t); + LOG.warn("Unable to load: {}", resource, t); } return null; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/BadPayloadException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/BadPayloadException.java new file mode 100644 index 00000000000..c4f0b7bd208 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/BadPayloadException.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +import org.eclipse.jetty.websocket.core.CloseStatus; + +/** + * Exception to terminate the connection because it has received data within a frame payload that was not consistent with the requirements of that frame + * payload. (eg: not UTF-8 in a text frame, or a unexpected data seen by an extension) + * + * @see RFC6455 : Section 7.4.1 + */ +@SuppressWarnings("serial") +public class BadPayloadException extends CloseException +{ + public BadPayloadException(String message) + { + super(CloseStatus.BAD_PAYLOAD, message); + } + + public BadPayloadException(String message, Throwable t) + { + super(CloseStatus.BAD_PAYLOAD, message, t); + } + + public BadPayloadException(Throwable t) + { + super(CloseStatus.BAD_PAYLOAD, t); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/CloseException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/CloseException.java new file mode 100644 index 00000000000..6243d216de8 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/CloseException.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +@SuppressWarnings("serial") +public class CloseException extends WebSocketException +{ + private int statusCode; + + public CloseException(int closeCode, String message) + { + super(message); + this.statusCode = closeCode; + } + + public CloseException(int closeCode, String message, Throwable cause) + { + super(message, cause); + this.statusCode = closeCode; + } + + public CloseException(int closeCode, Throwable cause) + { + super(cause); + this.statusCode = closeCode; + } + + public int getStatusCode() + { + return statusCode; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/MessageTooLargeException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/MessageTooLargeException.java new file mode 100644 index 00000000000..791b1ed6498 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/MessageTooLargeException.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +import org.eclipse.jetty.websocket.core.CloseStatus; + +/** + * Exception when a message is too large for the internal buffers occurs and should trigger a connection close. + * + * @see RFC6455 : Section 7.4.1 + */ +@SuppressWarnings("serial") +public class MessageTooLargeException extends CloseException +{ + public MessageTooLargeException(String message) + { + super(CloseStatus.MESSAGE_TOO_LARGE, message); + } + + public MessageTooLargeException(String message, Throwable t) + { + super(CloseStatus.MESSAGE_TOO_LARGE, message, t); + } + + public MessageTooLargeException(Throwable t) + { + super(CloseStatus.MESSAGE_TOO_LARGE, t); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/ProtocolException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/ProtocolException.java new file mode 100644 index 00000000000..c74cd19e236 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/ProtocolException.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +import org.eclipse.jetty.websocket.core.CloseStatus; + +/** + * Per spec, a protocol error should result in a Close frame of status code 1002 (PROTOCOL_ERROR) + * + * @see RFC6455 : Section 7.4.1 + */ +@SuppressWarnings("serial") +public class ProtocolException extends CloseException +{ + public ProtocolException(String message) + { + super(CloseStatus.PROTOCOL, message); + } + + public ProtocolException(String message, Throwable t) + { + super(CloseStatus.PROTOCOL, message, t); + } + + public ProtocolException(Throwable t) + { + super(CloseStatus.PROTOCOL, t); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/UpgradeException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/UpgradeException.java similarity index 55% rename from jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/UpgradeException.java rename to jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/UpgradeException.java index 6ad3b78c200..36db91d2095 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/UpgradeException.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/UpgradeException.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.core; +package org.eclipse.jetty.websocket.core.exception; import java.net.URI; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketException.java new file mode 100644 index 00000000000..73346abd76c --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketException.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +/** + * A recoverable exception within the websocket framework. + */ +@SuppressWarnings("serial") +public class WebSocketException extends RuntimeException +{ + public WebSocketException() + { + super(); + } + + public WebSocketException(String message) + { + super(message); + } + + public WebSocketException(String message, Throwable cause) + { + super(message, cause); + } + + public WebSocketException(Throwable cause) + { + super(cause); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketTimeoutException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketTimeoutException.java new file mode 100644 index 00000000000..956b7c68018 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketTimeoutException.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +/** + * Exception thrown to indicate a connection I/O timeout. + */ +public class WebSocketTimeoutException extends WebSocketException +{ + private static final long serialVersionUID = -6145098200250676673L; + + public WebSocketTimeoutException(String message) + { + super(message); + } + + public WebSocketTimeoutException(String message, Throwable cause) + { + super(message, cause); + } + + public WebSocketTimeoutException(Throwable cause) + { + super(cause); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketWriteTimeoutException.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketWriteTimeoutException.java new file mode 100644 index 00000000000..f0d43f5e84a --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketWriteTimeoutException.java @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.exception; + +public class WebSocketWriteTimeoutException extends WebSocketTimeoutException +{ + public WebSocketWriteTimeoutException(String message) + { + super(message); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java index 25f9d799b2e..28f3232c816 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -30,8 +30,6 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Extension; import org.eclipse.jetty.websocket.core.ExtensionConfig; @@ -39,7 +37,9 @@ import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.IncomingFrames; import org.eclipse.jetty.websocket.core.OutgoingFrames; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Represents the stack of Extensions. @@ -47,7 +47,7 @@ import org.eclipse.jetty.websocket.core.WebSocketException; @ManagedObject("Extension Stack") public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable { - private static final Logger LOG = Log.getLogger(ExtensionStack.class); + private static final Logger LOG = LoggerFactory.getLogger(ExtensionStack.class); private final WebSocketComponents components; private final Behavior behavior; @@ -254,7 +254,7 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable for (Extension extension : extensions) { - extension.setWebSocketCoreSession(coreSession); + extension.setCoreSession(coreSession); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java index cf2ed8cacbc..c4dd10da864 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java @@ -1,47 +1,53 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; -import java.nio.ByteBuffer; -import java.util.ArrayDeque; -import java.util.Queue; - import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.AbstractExtension; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Fragment Extension */ public class FragmentExtension extends AbstractExtension { - private static final Logger LOG = Log.getLogger(FragmentExtension.class); + private static final Logger LOG = LoggerFactory.getLogger(FragmentExtension.class); - private final Queue entries = new ArrayDeque<>(); - private final IteratingCallback flusher = new Flusher(); - private int maxLength; + private final FragmentingFlusher flusher; + private final Configuration configuration = new Configuration.ConfigurationCustomizer(); + + public FragmentExtension() + { + flusher = new FragmentingFlusher(configuration) + { + @Override + void forwardFrame(Frame frame, Callback callback, boolean batch) + { + nextOutgoingFrame(frame, callback, batch); + } + }; + } @Override public String getName() @@ -58,154 +64,14 @@ public class FragmentExtension extends AbstractExtension @Override public void sendFrame(Frame frame, Callback callback, boolean batch) { - ByteBuffer payload = frame.getPayload(); - int length = payload != null ? payload.remaining() : 0; - if (OpCode.isControlFrame(frame.getOpCode()) || maxLength <= 0 || length <= maxLength) - { - nextOutgoingFrame(frame, callback, batch); - return; - } - - FrameEntry entry = new FrameEntry(frame, callback, batch); - if (LOG.isDebugEnabled()) - LOG.debug("Queuing {}", entry); - offerEntry(entry); - flusher.iterate(); + flusher.sendFrame(frame, callback, batch); } @Override public void init(ExtensionConfig config, WebSocketComponents components) { super.init(config, components); - maxLength = config.getParameter("maxLength", -1); - } - - private void offerEntry(FrameEntry entry) - { - synchronized (this) - { - entries.offer(entry); - } - } - - private FrameEntry pollEntry() - { - synchronized (this) - { - return entries.poll(); - } - } - - private class Flusher extends IteratingCallback implements Callback - { - private FrameEntry current; - private boolean finished = true; - - @Override - protected Action process() throws Exception - { - if (finished) - { - current = pollEntry(); - LOG.debug("Processing {}", current); - if (current == null) - return Action.IDLE; - fragment(current, true); - } - else - { - fragment(current, false); - } - return Action.SCHEDULED; - } - - private void fragment(FrameEntry entry, boolean first) - { - Frame frame = entry.frame; - ByteBuffer payload = frame.getPayload(); - int remaining = payload.remaining(); - int length = Math.min(remaining, maxLength); - finished = length == remaining; - - boolean continuation = (frame.getOpCode() == OpCode.CONTINUATION) || !first; - Frame fragment = new Frame(continuation ? OpCode.CONTINUATION : frame.getOpCode()); - boolean fin = frame.isFin() && finished; - fragment.setFin(fin); - - int limit = payload.limit(); - int newLimit = payload.position() + length; - payload.limit(newLimit); - ByteBuffer payloadFragment = payload.slice(); - payload.limit(limit); - fragment.setPayload(payloadFragment); - if (LOG.isDebugEnabled()) - LOG.debug("Fragmented {}->{}", frame, fragment); - payload.position(newLimit); - - nextOutgoingFrame(fragment, this, entry.batch); - } - - @Override - protected void onCompleteSuccess() - { - // This IteratingCallback never completes. - } - - @Override - protected void onCompleteFailure(Throwable x) - { - // This IteratingCallback never fails. - // The callback are those provided by WriteCallback (implemented - // below) and even in case of writeFailed() we call succeeded(). - } - - @Override - public void succeeded() - { - // Notify first then call succeeded(), otherwise - // write callbacks may be invoked out of order. - notifyCallbackSuccess(current.callback); - super.succeeded(); - } - - @Override - public void failed(Throwable cause) - { - // Notify first, the call succeeded() to drain the queue. - // We don't want to call failed(x) because that will put - // this flusher into a final state that cannot be exited, - // and the failure of a frame may not mean that the whole - // connection is now invalid. - notifyCallbackFailure(current.callback, cause); - succeeded(); - } - - private void notifyCallbackSuccess(Callback callback) - { - try - { - if (callback != null) - callback.succeeded(); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.debug("Exception while notifying success of callback " + callback, x); - } - } - - private void notifyCallbackFailure(Callback callback, Throwable failure) - { - try - { - if (callback != null) - callback.failed(failure); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.debug("Exception while notifying failure of callback " + callback, x); - } - } + int maxLength = config.getParameter("maxLength", -1); + configuration.setMaxFrameSize(maxLength); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java new file mode 100644 index 00000000000..142f4b5a871 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java @@ -0,0 +1,117 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.internal; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Used to split large data frames into multiple frames below the maxFrameSize. + * Control frames and dataFrames smaller than the maxFrameSize will be forwarded + * directly to {@link #forwardFrame(Frame, Callback, boolean)}. + */ +public abstract class FragmentingFlusher extends TransformingFlusher +{ + private static final Logger LOG = LoggerFactory.getLogger(FragmentingFlusher.class); + private final Configuration configuration; + private FrameEntry current; + private ByteBuffer payload; + + public FragmentingFlusher(Configuration configuration) + { + this.configuration = configuration; + } + + abstract void forwardFrame(Frame frame, Callback callback, boolean batch); + + @Override + protected boolean onFrame(Frame frame, Callback callback, boolean batch) + { + long maxFrameSize = configuration.getMaxFrameSize(); + if (frame.isControlFrame() || maxFrameSize <= 0 || frame.getPayloadLength() <= maxFrameSize) + { + forwardFrame(frame, callback, batch); + return true; + } + + current = new FrameEntry(frame, callback, batch); + payload = frame.getPayload().slice(); + + boolean finished = fragment(callback, true); + if (finished) + { + current = null; + payload = null; + } + return finished; + } + + @Override + protected boolean transform(Callback callback) + { + boolean finished = fragment(callback, false); + if (finished) + { + current = null; + payload = null; + } + return finished; + } + + private boolean fragment(Callback callback, boolean first) + { + Frame frame = current.frame; + int remaining = payload.remaining(); + long maxFrameSize = configuration.getMaxFrameSize(); + int fragmentSize = (int)Math.min(remaining, maxFrameSize); + + boolean continuation = (frame.getOpCode() == OpCode.CONTINUATION) || !first; + Frame fragment = new Frame(continuation ? OpCode.CONTINUATION : frame.getOpCode()); + boolean finished = (maxFrameSize <= 0 || remaining <= maxFrameSize); + fragment.setFin(frame.isFin() && finished); + + // If we don't need to fragment just forward with original payload. + if (finished) + { + fragment.setPayload(payload); + forwardFrame(fragment, callback, current.batch); + return true; + } + + // Slice the fragmented payload from the buffer. + int limit = payload.limit(); + int newLimit = payload.position() + fragmentSize; + payload.limit(newLimit); + ByteBuffer payloadFragment = payload.slice(); + payload.limit(limit); + fragment.setPayload(payloadFragment); + payload.position(newLimit); + if (LOG.isDebugEnabled()) + LOG.debug("Fragmented {}->{}", frame, fragment); + + forwardFrame(fragment, callback, current.batch); + return false; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java index 99b51b5b06c..a4b7ccb73f4 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -27,23 +27,22 @@ import java.nio.file.Path; import java.util.Calendar; import java.util.concurrent.atomic.AtomicInteger; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.AbstractExtension; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.nio.file.StandardOpenOption.CREATE; import static java.nio.file.StandardOpenOption.WRITE; public class FrameCaptureExtension extends AbstractExtension { - private static final Logger LOG = Log.getLogger(FrameCaptureExtension.class); + private static final Logger LOG = LoggerFactory.getLogger(FrameCaptureExtension.class); private static final int BUFSIZE = 32768; private Generator generator; @@ -112,14 +111,12 @@ public class FrameCaptureExtension extends AbstractExtension } ByteBuffer buf = getBufferPool().acquire(BUFSIZE, false); - BufferUtil.flipToFill(buf); try { Frame f = Frame.copy(frame); f.setMask(null); // TODO is this needed? - generator.generateHeaderBytes(f, buf); - BufferUtil.flipToFlush(buf, 0); + generator.generateHeader(f, buf); channel.write(buf); if (frame.hasPayload()) { @@ -178,7 +175,7 @@ public class FrameCaptureExtension extends AbstractExtension incomingChannel = Files.newByteChannel(incomingFramesPath, CREATE, WRITE); outgoingChannel = Files.newByteChannel(outgoingFramesPath, CREATE, WRITE); - this.generator = new Generator(getBufferPool(), true); + this.generator = new Generator(); } catch (IOException e) { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameEntry.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameEntry.java index 966d8d0c2a7..d0bc0299a7c 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameEntry.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameEntry.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java index f53331d4b88..c7633d291e5 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -35,21 +35,23 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.WebSocketException; -import org.eclipse.jetty.websocket.core.WebSocketWriteTimeoutException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.WebSocketWriteTimeoutException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class FrameFlusher extends IteratingCallback { public static final Frame FLUSH_FRAME = new Frame(OpCode.BINARY); - private static final Logger LOG = Log.getLogger(FrameFlusher.class); + private static final Logger LOG = LoggerFactory.getLogger(FrameFlusher.class); private static final Throwable CLOSED_CHANNEL = new ClosedChannelException(); + private final LongAdder messagesOut = new LongAdder(); + private final LongAdder bytesOut = new LongAdder(); private final ByteBufferPool bufferPool; private final EndPoint endPoint; private final int bufferSize; @@ -62,13 +64,13 @@ public class FrameFlusher extends IteratingCallback private final List previousEntries; private final List failedEntries; - private ByteBuffer batchBuffer = null; + private List releasableBuffers = new ArrayList<>(); + private ByteBuffer batchBuffer; private boolean canEnqueue = true; private boolean flushed = true; private Throwable closedCause; - private LongAdder messagesOut = new LongAdder(); - private LongAdder bytesOut = new LongAdder(); - private long idleTimeout = 0; + private long idleTimeout; + private boolean useDirectByteBuffers; public FrameFlusher(ByteBufferPool bufferPool, Scheduler scheduler, Generator generator, EndPoint endPoint, int bufferSize, int maxGather) { @@ -84,6 +86,16 @@ public class FrameFlusher extends IteratingCallback this.timeoutScheduler = scheduler; } + public boolean isUseDirectByteBuffers() + { + return useDirectByteBuffers; + } + + public void setUseDirectByteBuffers(boolean useDirectByteBuffers) + { + this.useDirectByteBuffers = useDirectByteBuffers; + } + /** * Enqueue a Frame to be written to the endpoint. * @@ -189,6 +201,7 @@ public class FrameFlusher extends IteratingCallback LOG.debug("Flushing {}", this); boolean flush = false; + Callback releasingCallback = this; synchronized (this) { if (closedCause != null) @@ -222,42 +235,64 @@ public class FrameFlusher extends IteratingCallback if (batch) { - // Acquire a batchBuffer if we don't have one + // Acquire a batchBuffer if we don't have one. if (batchBuffer == null) { - batchBuffer = bufferPool.acquire(bufferSize, true); + batchBuffer = acquireBuffer(bufferSize); buffers.add(batchBuffer); } - // generate the frame into the batchBuffer - entry.generateHeaderBytes(batchBuffer); - ByteBuffer payload = entry.frame.getPayload(); - if (BufferUtil.hasContent(payload)) - BufferUtil.append(batchBuffer, payload); - } - else if (batchBuffer != null && batchSpace >= Generator.MAX_HEADER_LENGTH) - { - // Use the batch space for our header - entry.generateHeaderBytes(batchBuffer); - flush = true; - - // Add the payload to the list of buffers - ByteBuffer payload = entry.frame.getPayload(); - if (BufferUtil.hasContent(payload)) - buffers.add(payload); + // Generate the frame into the batchBuffer. + generator.generateWholeFrame(entry.frame, batchBuffer); } else { - // Add headers and payload to the list of buffers - buffers.add(entry.generateHeaderBytes()); - flush = true; + if (batchBuffer != null && batchSpace >= Generator.MAX_HEADER_LENGTH) + { + // Use the batch space for our header. + generator.generateHeader(entry.frame, batchBuffer); + } + else + { + // Add headers to the list of buffers. + ByteBuffer headerBuffer = acquireBuffer(Generator.MAX_HEADER_LENGTH); + releasableBuffers.add(headerBuffer); + generator.generateHeader(entry.frame, headerBuffer); + buffers.add(headerBuffer); + } + + // Add the payload to the list of buffers. ByteBuffer payload = entry.frame.getPayload(); if (BufferUtil.hasContent(payload)) - buffers.add(payload); + { + if (entry.frame.isMasked()) + { + payload = acquireBuffer(entry.frame.getPayloadLength()); + releasableBuffers.add(payload); + generator.generatePayload(entry.frame, payload); + } + + buffers.add(payload.slice()); + } + flush = true; } flushed = flush; } + + // If we are going to flush we should release any buffers we have allocated after the callback completes. + if (flush) + { + final List callbackBuffers = releasableBuffers; + releasableBuffers = new ArrayList<>(); + releasingCallback = Callback.from(releasingCallback, () -> + { + for (ByteBuffer buffer : callbackBuffers) + { + bufferPool.release(buffer); + } + }); + } } if (LOG.isDebugEnabled()) @@ -274,7 +309,6 @@ public class FrameFlusher extends IteratingCallback if (entry.frame.getOpCode() == OpCode.CLOSE) endPoint.shutdownOutput(); notifyCallbackSuccess(entry.callback); - entry.release(); } previousEntries.clear(); @@ -296,7 +330,7 @@ public class FrameFlusher extends IteratingCallback bufferArray[i++] = bb; } bytesOut.add(bytes); - endPoint.write(this, bufferArray); + endPoint.write(releasingCallback, bufferArray); buffers.clear(); } else @@ -308,6 +342,11 @@ public class FrameFlusher extends IteratingCallback return Action.SCHEDULED; } + private ByteBuffer acquireBuffer(int capacity) + { + return bufferPool.acquire(capacity, isUseDirectByteBuffers()); + } + private int getQueueSize() { synchronized (this) @@ -378,6 +417,12 @@ public class FrameFlusher extends IteratingCallback failedEntries.addAll(entries); entries.clear(); + for (ByteBuffer buffer : releasableBuffers) + { + bufferPool.release(buffer); + } + releasableBuffers.clear(); + if (closedCause == null) closedCause = failure; else if (closedCause != failure) @@ -387,7 +432,6 @@ public class FrameFlusher extends IteratingCallback for (Entry entry : failedEntries) { notifyCallbackFailure(entry.callback, failure); - entry.release(); } failedEntries.clear(); @@ -474,27 +518,6 @@ public class FrameFlusher extends IteratingCallback super(frame, callback, batch); } - private ByteBuffer generateHeaderBytes() - { - return headerBuffer = generator.generateHeaderBytes(frame); - } - - private void generateHeaderBytes(ByteBuffer buffer) - { - int pos = BufferUtil.flipToFill(buffer); - generator.generateHeaderBytes(frame, buffer); - BufferUtil.flipToFlush(buffer, pos); - } - - private void release() - { - if (headerBuffer != null) - { - generator.getBufferPool().release(headerBuffer); - headerBuffer = null; - } - } - private long getTimeOfCreation() { return timeOfCreation; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameSequence.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameSequence.java index 7e2ed5f805a..5bc9d128270 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameSequence.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameSequence.java @@ -1,25 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; public class FrameSequence { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java index d2571bdeeb5..13886059e25 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java @@ -1,26 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; import java.nio.ByteBuffer; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.Frame; @@ -54,57 +53,27 @@ public class Generator * The overhead (maximum) for a framing header. Assuming a maximum sized payload with masking key. */ public static final int MAX_HEADER_LENGTH = 28; - private static byte[] mask = {0x00, (byte)0xF0, 0x0F, (byte)0xFF}; - - public static void putMask(ByteBuffer buffer) - { - buffer.put(mask, 0, mask.length); - } - - public static void putPayload(ByteBuffer buffer, byte[] payload) - { - int len = payload.length; - for (int i = 0; i < len; i++) - { - buffer.put((byte)(payload[i] ^ mask[i % 4])); - } - } - - private final ByteBufferPool bufferPool; - private final boolean readOnly; /** - * Construct Generator with provided policy and bufferPool - * - * @param bufferPool the buffer pool to use + * Generate the whole frame (header + payload copy) into a single ByteBuffer. + * @param frame the frame to generate. + * @param buffer the buffer to output the generated frame to. */ - public Generator(ByteBufferPool bufferPool) + public void generateWholeFrame(Frame frame, ByteBuffer buffer) { - this(bufferPool, false); + generateHeader(frame, buffer); + generatePayload(frame, buffer); } /** - * Construct Generator with provided policy and bufferPool - * - * @param bufferPool the buffer pool to use + * Generate the header bytes of a frame into a single ByteBuffer. + * @param frame the frame to generate. + * @param buffer the buffer to output the generated frame to. */ - public Generator(ByteBufferPool bufferPool, boolean readOnly) + public void generateHeader(Frame frame, ByteBuffer buffer) { - this.bufferPool = bufferPool; - this.readOnly = readOnly; - } + int pos = BufferUtil.flipToFill(buffer); - public ByteBuffer generateHeaderBytes(Frame frame) - { - ByteBuffer buffer = bufferPool.acquire(MAX_HEADER_LENGTH, false); - BufferUtil.clearToFill(buffer); - generateHeaderBytes(frame, buffer); - BufferUtil.flipToFlush(buffer, 0); - return buffer; - } - - public void generateHeaderBytes(Frame frame, ByteBuffer buffer) - { /* * start the generation process */ @@ -177,68 +146,63 @@ public class Generator } // masking key - if (frame.isMasked() && !readOnly) - { - byte[] mask = frame.getMask(); - buffer.put(mask); - int maskInt = 0; - for (byte maskByte : mask) - { - maskInt = (maskInt << 8) + (maskByte & 0xFF); - } + if (frame.isMasked()) + buffer.put(frame.getMask()); - // perform data masking here - ByteBuffer payload = frame.getPayload(); - if ((payload != null) && (payload.remaining() > 0)) + BufferUtil.flipToFlush(buffer, pos); + } + + /** + * Generate the payload of a frame into a single ByteBuffer, if the frame has a mask the payload + * will be masked as it is copied to the output buffer. + * @param frame the frame to generate. + * @param buffer the buffer to output the generated frame to. + */ + public void generatePayload(Frame frame, ByteBuffer buffer) + { + ByteBuffer payload = frame.getPayload(); + if (!BufferUtil.hasContent(payload)) + return; + + int pos = BufferUtil.flipToFill(buffer); + if (frame.isMasked()) + maskPayload(buffer, frame); + else + buffer.put(payload.slice()); + BufferUtil.flipToFlush(buffer, pos); + } + + private void maskPayload(ByteBuffer buffer, Frame frame) + { + byte[] mask = frame.getMask(); + int maskInt = 0; + for (byte maskByte : mask) + { + maskInt = (maskInt << 8) + (maskByte & 0xFF); + } + + // perform data masking here + ByteBuffer payload = frame.getPayload(); + if ((payload != null) && (payload.remaining() > 0)) + { + int maskOffset = 0; + int start = payload.position(); + int end = payload.limit(); + int remaining; + while ((remaining = end - start) > 0) { - int maskOffset = 0; - int start = payload.position(); - int end = payload.limit(); - int remaining; - while ((remaining = end - start) > 0) + if (remaining >= 4) { - if (remaining >= 4) - { - payload.putInt(start, payload.getInt(start) ^ maskInt); - start += 4; - } - else - { - payload.put(start, (byte)(payload.get(start) ^ mask[maskOffset & 3])); - ++start; - ++maskOffset; - } + buffer.putInt(payload.getInt(start) ^ maskInt); + start += 4; + } + else + { + buffer.put((byte)(payload.get(start) ^ mask[maskOffset & 3])); + ++start; + ++maskOffset; } } } } - - /** - * Generate the whole frame (header + payload copy) into a single ByteBuffer. - *

        - * Note: This is slow, moves lots of memory around. Only use this if you must (such as in unit testing). - * - * @param frame the frame to generate - * @param buf the buffer to output the generated frame to - */ - public void generateWholeFrame(Frame frame, ByteBuffer buf) - { - generateHeaderBytes(frame, buf); - if (frame.hasPayload()) - { - if (readOnly) - { - buf.put(frame.getPayload().slice()); - } - else - { - buf.put(frame.getPayload()); - } - } - } - - public ByteBufferPool getBufferPool() - { - return bufferPool; - } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/IdentityExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/IdentityExtension.java index 20ddd17f8af..2e3dcc4b689 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/IdentityExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/IdentityExtension.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Negotiated.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Negotiated.java index 269fdb8f1a1..fedcaa5345f 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Negotiated.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Negotiated.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -28,6 +28,7 @@ import java.util.Objects; import java.util.stream.Collectors; import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.WebSocketConstants; @@ -50,14 +51,17 @@ public class Negotiated this.extensions = extensions; this.protocolVersion = protocolVersion; + String rawQuery = requestURI.getRawQuery(); Map> map; - if (requestURI.getQuery() == null) + if (StringUtil.isBlank(rawQuery)) + { map = Collections.emptyMap(); + } else { map = new HashMap<>(); MultiMap params = new MultiMap<>(); - UrlEncoded.decodeUtf8To(requestURI.getQuery(), params); + UrlEncoded.decodeUtf8To(rawQuery, params); for (String p : params.keySet()) { map.put(p, Collections.unmodifiableList(params.getValues(p))); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/NullAppendable.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/NullAppendable.java new file mode 100644 index 00000000000..f1301f62f94 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/NullAppendable.java @@ -0,0 +1,60 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.internal; + +import org.eclipse.jetty.util.Utf8Appendable; + +public class NullAppendable extends Utf8Appendable +{ + public NullAppendable() + { + super(new Appendable() + { + @Override + public Appendable append(CharSequence csq) + { + return null; + } + + @Override + public Appendable append(CharSequence csq, int start, int end) + { + return null; + } + + @Override + public Appendable append(char c) + { + return null; + } + }); + } + + @Override + public int length() + { + return 0; + } + + @Override + public String getPartialString() + { + return null; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Parser.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Parser.java index 176adf382dd..204dbec29b8 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Parser.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Parser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -24,16 +24,15 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler.Configuration; -import org.eclipse.jetty.websocket.core.FrameHandler.ConfigurationHolder; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; -import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Parsing of a frames in WebSocket land. @@ -51,7 +50,7 @@ public class Parser FRAGMENT } - private static final Logger LOG = Log.getLogger(Parser.class); + private static final Logger LOG = LoggerFactory.getLogger(Parser.class); private final ByteBufferPool bufferPool; private final Configuration configuration; @@ -65,7 +64,7 @@ public class Parser public Parser(ByteBufferPool bufferPool) { - this(bufferPool, new ConfigurationHolder()); + this(bufferPool, new Configuration.ConfigurationCustomizer()); } public Parser(ByteBufferPool bufferPool, Configuration configuration) @@ -256,12 +255,17 @@ public class Parser protected void checkFrameSize(byte opcode, int payloadLength) throws MessageTooLargeException, ProtocolException { - if (OpCode.isControlFrame(opcode) && payloadLength > Frame.MAX_CONTROL_PAYLOAD) - throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed [" + Frame.MAX_CONTROL_PAYLOAD + "]"); - - long maxFrameSize = configuration.getMaxFrameSize(); - if (!configuration.isAutoFragment() && maxFrameSize > 0 && payloadLength > maxFrameSize) - throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize); + if (OpCode.isControlFrame(opcode)) + { + if (payloadLength > Frame.MAX_CONTROL_PAYLOAD) + throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed [" + Frame.MAX_CONTROL_PAYLOAD + "]"); + } + else + { + long maxFrameSize = configuration.getMaxFrameSize(); + if (!configuration.isAutoFragment() && maxFrameSize > 0 && payloadLength > maxFrameSize) + throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize); + } } protected ParsedFrame newFrame(byte firstByte, byte[] mask, ByteBuffer payload, boolean releaseable) @@ -279,6 +283,32 @@ public class Parser return new ParsedFrame(firstByte, mask, payload, releaseable); } + private ParsedFrame autoFragment(ByteBuffer buffer, int fragmentSize) + { + payloadLength -= fragmentSize; + + byte[] nextMask = null; + if (mask != null) + { + int shift = fragmentSize % 4; + nextMask = new byte[4]; + nextMask[0] = mask[(0 + shift) % 4]; + nextMask[1] = mask[(1 + shift) % 4]; + nextMask[2] = mask[(2 + shift) % 4]; + nextMask[3] = mask[(3 + shift) % 4]; + } + + ByteBuffer content = buffer.slice(); + content.limit(fragmentSize); + buffer.position(buffer.position() + fragmentSize); + + final ParsedFrame frame = newFrame((byte)(firstByte & 0x7F), mask, content, false); + mask = nextMask; + firstByte = (byte)((firstByte & 0x80) | OpCode.CONTINUATION); + state = State.FRAGMENT; + return frame; + } + private ParsedFrame parsePayload(ByteBuffer buffer) { if (payloadLength == 0) @@ -288,35 +318,21 @@ public class Parser return null; int available = buffer.remaining(); + boolean isDataFrame = OpCode.isDataFrame(OpCode.getOpCode(firstByte)); + + // Always autoFragment data frames if payloadLength is greater than maxFrameSize. + long maxFrameSize = configuration.getMaxFrameSize(); + if (maxFrameSize > 0 && isDataFrame && payloadLength > maxFrameSize) + return autoFragment(buffer, (int)Math.min(available, maxFrameSize)); if (aggregate == null) { if (available < payloadLength) { - // not enough to complete this frame - + // not enough to complete this frame // Can we auto-fragment - if (configuration.isAutoFragment() && OpCode.isDataFrame(OpCode.getOpCode(firstByte))) - { - payloadLength -= available; - - byte[] nextMask = null; - if (mask != null) - { - int shift = available % 4; - nextMask = new byte[4]; - nextMask[0] = mask[(0 + shift) % 4]; - nextMask[1] = mask[(1 + shift) % 4]; - nextMask[2] = mask[(2 + shift) % 4]; - nextMask[3] = mask[(3 + shift) % 4]; - } - final ParsedFrame frame = newFrame((byte)(firstByte & 0x7F), mask, buffer.slice(), false); - buffer.position(buffer.limit()); - mask = nextMask; - firstByte = (byte)((firstByte & 0x80) | OpCode.CONTINUATION); - state = State.FRAGMENT; - return frame; - } + if (configuration.isAutoFragment() && isDataFrame) + return autoFragment(buffer, available); // No space in the buffer, so we have to copy the partial payload aggregate = bufferPool.acquire(payloadLength, false); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java new file mode 100644 index 00000000000..a5df5908c34 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java @@ -0,0 +1,456 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.internal; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.AbstractExtension; +import org.eclipse.jetty.websocket.core.ExtensionConfig; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.exception.BadPayloadException; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Per Message Deflate Compression extension for WebSocket. + *

        + * Attempts to follow Compression Extensions for WebSocket + */ +public class PerMessageDeflateExtension extends AbstractExtension +{ + private static final byte[] TAIL_BYTES = new byte[]{0x00, 0x00, (byte)0xFF, (byte)0xFF}; + private static final ByteBuffer TAIL_BYTES_BUF = ByteBuffer.wrap(TAIL_BYTES); + private static final Logger LOG = LoggerFactory.getLogger(PerMessageDeflateExtension.class); + private static final int DEFAULT_BUF_SIZE = 8 * 1024; + + private final TransformingFlusher outgoingFlusher; + private final TransformingFlusher incomingFlusher; + private Deflater deflaterImpl; + private Inflater inflaterImpl; + private boolean incomingCompressed; + + private ExtensionConfig configRequested; + private ExtensionConfig configNegotiated; + private int deflateBufferSize = DEFAULT_BUF_SIZE; + private int inflateBufferSize = DEFAULT_BUF_SIZE; + private boolean incomingContextTakeover = true; + private boolean outgoingContextTakeover = true; + + public PerMessageDeflateExtension() + { + outgoingFlusher = new OutgoingFlusher(); + incomingFlusher = new IncomingFlusher(); + } + + @Override + public String getName() + { + return "permessage-deflate"; + } + + @Override + public boolean isRsv1User() + { + return true; + } + + @Override + public void sendFrame(Frame frame, Callback callback, boolean batch) + { + // Compressed frames may increase in size so we need the flusher to fragment them. + outgoingFlusher.sendFrame(frame, callback, batch); + } + + @Override + public void onFrame(Frame frame, Callback callback) + { + incomingFlusher.sendFrame(frame, callback, false); + } + + @Override + public void init(final ExtensionConfig config, WebSocketComponents components) + { + configRequested = new ExtensionConfig(config); + Map paramsNegotiated = new HashMap<>(); + + for (String key : config.getParameterKeys()) + { + key = key.trim(); + switch (key) + { + case "client_max_window_bits": + case "server_max_window_bits": + { + // Not supported by Jetty + // Don't negotiate these parameters + break; + } + case "client_no_context_takeover": + { + paramsNegotiated.put("client_no_context_takeover", null); + incomingContextTakeover = false; + break; + } + case "server_no_context_takeover": + { + paramsNegotiated.put("server_no_context_takeover", null); + outgoingContextTakeover = false; + break; + } + case "@deflate_buffer_size": + { + deflateBufferSize = config.getParameter(key, DEFAULT_BUF_SIZE); + break; + } + case "@inflate_buffer_size": + { + inflateBufferSize = config.getParameter(key, DEFAULT_BUF_SIZE); + break; + } + default: + { + throw new IllegalArgumentException(); + } + } + } + + configNegotiated = new ExtensionConfig(config.getName(), paramsNegotiated); + LOG.debug("config: outgoingContextTakover={}, incomingContextTakeover={} : {}", outgoingContextTakeover, incomingContextTakeover, this); + + super.init(configNegotiated, components); + } + + private static String toDetail(Inflater inflater) + { + return String.format("Inflater[finished=%b,read=%d,written=%d,remaining=%d,in=%d,out=%d]", inflater.finished(), inflater.getBytesRead(), + inflater.getBytesWritten(), inflater.getRemaining(), inflater.getTotalIn(), inflater.getTotalOut()); + } + + private static String toDetail(Deflater deflater) + { + return String.format("Deflater[finished=%b,read=%d,written=%d,in=%d,out=%d]", deflater.finished(), deflater.getBytesRead(), deflater.getBytesWritten(), + deflater.getTotalIn(), deflater.getTotalOut()); + } + + public static boolean endsWithTail(ByteBuffer buf) + { + if ((buf == null) || (buf.remaining() < TAIL_BYTES.length)) + { + return false; + } + int limit = buf.limit(); + for (int i = TAIL_BYTES.length; i > 0; i--) + { + if (buf.get(limit - i) != TAIL_BYTES[TAIL_BYTES.length - i]) + { + return false; + } + } + return true; + } + + public Deflater getDeflater() + { + if (deflaterImpl == null) + deflaterImpl = getDeflaterPool().acquire(); + return deflaterImpl; + } + + public Inflater getInflater() + { + if (inflaterImpl == null) + inflaterImpl = getInflaterPool().acquire(); + return inflaterImpl; + } + + public void releaseInflater() + { + getInflaterPool().release(inflaterImpl); + inflaterImpl = null; + } + + public void releaseDeflater() + { + getDeflaterPool().release(deflaterImpl); + deflaterImpl = null; + } + + @Override + public String toString() + { + return String.format("%s[requested=\"%s\", negotiated=\"%s\"]", + getClass().getSimpleName(), + configRequested.getParameterizedName(), + configNegotiated.getParameterizedName()); + } + + @Override + protected void nextIncomingFrame(Frame frame, Callback callback) + { + if (frame.isFin() && !incomingContextTakeover) + { + LOG.debug("Incoming Context Reset"); + releaseInflater(); + } + super.nextIncomingFrame(frame, callback); + } + + @Override + protected void nextOutgoingFrame(Frame frame, Callback callback, boolean batch) + { + if (frame.isFin() && !outgoingContextTakeover) + { + LOG.debug("Outgoing Context Reset"); + releaseDeflater(); + } + super.nextOutgoingFrame(frame, callback, batch); + } + + private class OutgoingFlusher extends TransformingFlusher + { + private boolean _first; + private Frame _frame; + private boolean _batch; + + @Override + protected boolean onFrame(Frame frame, Callback callback, boolean batch) + { + if (OpCode.isControlFrame(frame.getOpCode())) + { + nextOutgoingFrame(frame, callback, batch); + return true; + } + + _first = true; + _frame = frame; + _batch = batch; + + // Provide the frames payload as input to the Deflater. + getDeflater().setInput(frame.getPayload().slice()); + callback.succeeded(); + return false; + } + + @Override + protected boolean transform(Callback callback) + { + boolean finished = deflate(callback); + _first = false; + return finished; + } + + private boolean deflate(Callback callback) + { + // Get a buffer for the inflated payload. + long maxFrameSize = getConfiguration().getMaxFrameSize(); + int bufferSize = (maxFrameSize <= 0) ? deflateBufferSize : (int)Math.min(maxFrameSize, deflateBufferSize); + final ByteBuffer buffer = getBufferPool().acquire(bufferSize, false); + callback = Callback.from(callback, () -> getBufferPool().release(buffer)); + BufferUtil.clear(buffer); + + // Fill up the buffer with a max length of bufferSize; + boolean finished = false; + Deflater deflater = getDeflater(); + while (true) + { + int compressed = deflater.deflate(buffer.array(), buffer.arrayOffset() + buffer.position(), + bufferSize - buffer.position(), Deflater.SYNC_FLUSH); + buffer.limit(buffer.limit() + compressed); + if (LOG.isDebugEnabled()) + LOG.debug("Compressed {} bytes {}", compressed, toDetail(deflater)); + + if (buffer.limit() == bufferSize) + { + // We need to fragment. TODO: what if there was only bufferSize of content? + if (!getConfiguration().isAutoFragment()) + throw new MessageTooLargeException("Deflated payload exceeded the compress buffer size"); + break; + } + + if (compressed == 0) + { + finished = true; + break; + } + } + + ByteBuffer payload = buffer; + if (payload.hasRemaining()) + { + // Handle tail bytes generated by SYNC_FLUSH. + if (finished && _frame.isFin() && endsWithTail(payload)) + { + payload.limit(payload.limit() - TAIL_BYTES.length); + if (LOG.isDebugEnabled()) + LOG.debug("payload (TAIL_DROP_FIN_ONLY) = {}", BufferUtil.toDetailString(payload)); + } + } + else if (_frame.isFin()) + { + // Special case: 7.2.3.6. Generating an Empty Fragment Manually + // https://tools.ietf.org/html/rfc7692#section-7.2.3.6 + payload = ByteBuffer.wrap(new byte[]{0x00}); + } + + if (LOG.isDebugEnabled()) + LOG.debug("Compressed {}: payload:{}", _frame, payload.remaining()); + + Frame chunk = new Frame(_first ? _frame.getOpCode() : OpCode.CONTINUATION); + chunk.setRsv1(_first && _frame.getOpCode() != OpCode.CONTINUATION); + chunk.setPayload(payload); + chunk.setFin(_frame.isFin() && finished); + + nextOutgoingFrame(chunk, callback, _batch); + return finished; + } + } + + private class IncomingFlusher extends TransformingFlusher + { + private boolean _first; + private Frame _frame; + private boolean _tailBytes; + + @Override + protected boolean onFrame(Frame frame, Callback callback, boolean batch) + { + _tailBytes = false; + _first = true; + _frame = frame; + + if (OpCode.isControlFrame(_frame.getOpCode())) + { + nextIncomingFrame(_frame, callback); + return true; + } + + // This extension requires the RSV1 bit set only in the first frame. + // Subsequent continuation frames don't have RSV1 set, but are compressed. + switch (_frame.getOpCode()) + { + case OpCode.TEXT: + case OpCode.BINARY: + incomingCompressed = _frame.isRsv1(); + break; + + case OpCode.CONTINUATION: + if (_frame.isRsv1()) + throw new ProtocolException("Invalid RSV1 set on permessage-deflate CONTINUATION frame"); + break; + + default: + break; + } + + if (_first && !incomingCompressed) + { + nextIncomingFrame(_frame, callback); + return true; + } + + if (_frame.isFin()) + incomingCompressed = false; + + // Provide the frames payload as input to the Inflater. + getInflater().setInput(_frame.getPayload().slice()); + callback.succeeded(); + return false; + } + + @Override + protected boolean transform(Callback callback) + { + try + { + boolean finished = inflate(callback); + _first = false; + return finished; + } + catch (DataFormatException e) + { + throw new BadPayloadException(e); + } + } + + private boolean inflate(Callback callback) throws DataFormatException + { + // Get a buffer for the inflated payload. + long maxFrameSize = getConfiguration().getMaxFrameSize(); + int bufferSize = (maxFrameSize <= 0) ? inflateBufferSize : (int)Math.min(maxFrameSize, inflateBufferSize); + final ByteBuffer payload = getBufferPool().acquire(bufferSize, false); + callback = Callback.from(callback, () -> getBufferPool().release(payload)); + BufferUtil.clear(payload); + + // Fill up the ByteBuffer with a max length of bufferSize; + boolean finished = false; + Inflater inflater = getInflater(); + while (true) + { + int read = inflater.inflate(payload.array(), payload.arrayOffset() + payload.position(), bufferSize - payload.position()); + payload.limit(payload.limit() + read); + if (LOG.isDebugEnabled()) + LOG.debug("Decompress: read {} {}", read, toDetail(inflater)); + + if (payload.limit() == bufferSize) + { + // We need to fragment. TODO: what if there was only bufferSize of content? + if (!getConfiguration().isAutoFragment()) + throw new MessageTooLargeException("Inflated payload exceeded the decompress buffer size"); + break; + } + + if (read == 0) + { + if (!_tailBytes && _frame.isFin()) + { + inflater.setInput(TAIL_BYTES_BUF.slice()); + _tailBytes = true; + continue; + } + + finished = true; + break; + } + } + + Frame chunk = new Frame(_first ? _frame.getOpCode() : OpCode.CONTINUATION); + chunk.setRsv1(false); + chunk.setPayload(payload); + chunk.setFin(_frame.isFin() && finished); + + nextIncomingFrame(chunk, callback); + + if (LOG.isDebugEnabled()) + LOG.debug("Decompress finished: {} {}", finished, chunk); + + return finished; + } + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/TransformingFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/TransformingFlusher.java new file mode 100644 index 00000000000..28d30165aa3 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/TransformingFlusher.java @@ -0,0 +1,179 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.internal; + +import java.util.ArrayDeque; +import java.util.Queue; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.IteratingCallback; +import org.eclipse.jetty.websocket.core.Frame; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is used to iteratively transform or process a frame into one or more other frames. + * When a frame is ready to be processed {@link #onFrame(Frame, Callback, boolean)} is called. + * Subsequent calls to {@link #transform(Callback)} are made on each callback success until one of these calls returns + * true to indicate they are done processing the frame and are ready to receive a new one. + * The {@link Callback} passed in to both these method must be succeeded in order to continue processing. + */ +public abstract class TransformingFlusher +{ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + private final Queue entries = new ArrayDeque<>(); + private final IteratingCallback flusher = new Flusher(); + private boolean finished = true; + private Throwable failure; + + /** + * Called when a frame is ready to be transformed. + * @param frame the frame to transform. + * @param callback used to signal to start processing again. + * @param batch whether this frame can be batched. + * @return true to indicate that you have finished transforming this frame. + */ + protected abstract boolean onFrame(Frame frame, Callback callback, boolean batch); + + /** + * Called to transform the frame given in {@link TransformingFlusher#onFrame(Frame, Callback, boolean)}. + * This method is called on each callback success until it returns true. + * If the call to {@link #onFrame(Frame, Callback, boolean)} returns true then this method will not be called. + * @param callback used to signal to start processing again. + * @return true to indicate that you have finished transforming this frame. + */ + protected abstract boolean transform(Callback callback); + + public final void sendFrame(Frame frame, Callback callback, boolean batch) + { + FrameEntry entry = new FrameEntry(frame, callback, batch); + if (log.isDebugEnabled()) + log.debug("Queuing {}", entry); + + boolean enqueued = false; + synchronized (this) + { + if (failure == null) + { + enqueued = entries.add(entry); + } + } + + if (enqueued) + flusher.iterate(); + else + notifyCallbackFailure(callback, failure); + } + + private void onFailure(Throwable t) + { + synchronized (this) + { + if (failure == null) + failure = t; + } + + for (FrameEntry entry : entries) + notifyCallbackFailure(entry.callback, t); + entries.clear(); + } + + private FrameEntry pollEntry() + { + synchronized (this) + { + return entries.poll(); + } + } + + private class Flusher extends IteratingCallback implements Callback + { + private FrameEntry current; + + @Override + protected Action process() + { + if (finished) + { + if (current != null) + notifyCallbackSuccess(current.callback); + + current = pollEntry(); + if (current == null) + return Action.IDLE; + + if (log.isDebugEnabled()) + log.debug("onFrame {}", current); + + finished = onFrame(current.frame, this, current.batch); + return Action.SCHEDULED; + } + + if (log.isDebugEnabled()) + log.debug("transform {}", current); + + finished = transform(this); + return Action.SCHEDULED; + } + + @Override + protected void onCompleteFailure(Throwable t) + { + if (log.isDebugEnabled()) + log.debug("failed {}", t); + + notifyCallbackFailure(current.callback, t); + current = null; + onFailure(t); + } + } + + private void notifyCallbackSuccess(Callback callback) + { + if (log.isDebugEnabled()) + log.debug("notifyCallbackSuccess {}", callback); + + try + { + if (callback != null) + callback.succeeded(); + } + catch (Throwable x) + { + log.warn("Exception while notifying success of callback " + callback, x); + } + } + + private void notifyCallbackFailure(Callback callback, Throwable failure) + { + if (log.isDebugEnabled()) + log.debug("notifyCallbackFailure {} {}", callback, failure); + + try + { + if (callback != null) + callback.failed(failure); + } + catch (Throwable x) + { + log.warn("Exception while notifying failure of callback " + callback, x); + } + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ValidationExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ValidationExtension.java index 496ea84eb16..3a35ae691b0 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ValidationExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ValidationExtension.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -21,14 +21,14 @@ package org.eclipse.jetty.websocket.core.internal; import java.util.Map; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.AbstractExtension; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.NullAppendable; -import org.eclipse.jetty.websocket.core.ProtocolException; import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.websocket.core.OpCode.CONTINUATION; import static org.eclipse.jetty.websocket.core.OpCode.TEXT; @@ -36,8 +36,9 @@ import static org.eclipse.jetty.websocket.core.OpCode.UNDEFINED; public class ValidationExtension extends AbstractExtension { - private static final Logger LOG = Log.getLogger(ValidationExtension.class); + private static final Logger LOG = LoggerFactory.getLogger(ValidationExtension.class); + private WebSocketCoreSession coreSession; private FrameSequence incomingSequence = null; private FrameSequence outgoingSequence = null; private boolean incomingFrameValidation = false; @@ -53,6 +54,17 @@ public class ValidationExtension extends AbstractExtension return "@validation"; } + @Override + public void setCoreSession(CoreSession coreSession) + { + super.setCoreSession(coreSession); + + // TODO: change validation to use static methods instead of down casting CoreSession. + if (!(coreSession instanceof WebSocketCoreSession)) + throw new IllegalArgumentException("ValidationExtension needs a CoreSession Configuration"); + this.coreSession = (WebSocketCoreSession)coreSession; + } + @Override public void onFrame(Frame frame, Callback callback) { @@ -62,7 +74,7 @@ public class ValidationExtension extends AbstractExtension incomingSequence.check(frame.getOpCode(), frame.isFin()); if (incomingFrameValidation) - getWebSocketCoreSession().assertValidIncoming(frame); + coreSession.assertValidIncoming(frame); if (incomingUtf8Validation != null) validateUTF8(frame, incomingUtf8Validation, continuedInOpCode); @@ -85,7 +97,7 @@ public class ValidationExtension extends AbstractExtension outgoingSequence.check(frame.getOpCode(), frame.isFin()); if (outgoingFrameValidation) - getWebSocketCoreSession().assertValidOutgoing(frame); + coreSession.assertValidOutgoing(frame); if (outgoingUtf8Validation != null) validateUTF8(frame, outgoingUtf8Validation, continuedOutOpCode); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java index dacc62bb685..e83759e7285 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -34,19 +34,19 @@ import org.eclipse.jetty.io.RetainableByteBuffer; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.WebSocketTimeoutException; +import org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Provides the implementation of {@link org.eclipse.jetty.io.Connection} that is suitable for WebSocket */ public class WebSocketConnection extends AbstractConnection implements Connection.UpgradeTo, Dumpable, Runnable { - private static final Logger LOG = Log.getLogger(WebSocketConnection.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketConnection.class); /** * Minimum size of a buffer is the determined to be what would be the maximum framing header size (not including payload) @@ -68,6 +68,8 @@ public class WebSocketConnection extends AbstractConnection implements Connectio // Read / Parse variables private RetainableByteBuffer networkBuffer; + private boolean useInputDirectByteBuffers; + private boolean useOutputDirectByteBuffers; /** * Create a WSConnection. @@ -93,7 +95,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio this.coreSession = coreSession; - this.generator = new Generator(bufferPool); + this.generator = new Generator(); this.parser = new Parser(bufferPool, coreSession); this.flusher = new Flusher(scheduler, coreSession.getOutputBufferSize(), generator, endp); this.setInputBufferSize(coreSession.getInputBufferSize()); @@ -132,6 +134,26 @@ public class WebSocketConnection extends AbstractConnection implements Connectio return getEndPoint().getRemoteAddress(); } + public boolean isUseInputDirectByteBuffers() + { + return useInputDirectByteBuffers; + } + + public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers) + { + this.useInputDirectByteBuffers = useInputDirectByteBuffers; + } + + public boolean isUseOutputDirectByteBuffers() + { + return useOutputDirectByteBuffers; + } + + public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers) + { + this.useOutputDirectByteBuffers = useOutputDirectByteBuffers; + } + /** * Physical connection disconnect. *

        @@ -222,7 +244,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio synchronized (this) { if (networkBuffer == null) - networkBuffer = new RetainableByteBuffer(bufferPool, getInputBufferSize()); + networkBuffer = newNetworkBuffer(getInputBufferSize()); } } @@ -237,10 +259,15 @@ public class WebSocketConnection extends AbstractConnection implements Connectio throw new IllegalStateException(); networkBuffer.release(); - networkBuffer = new RetainableByteBuffer(bufferPool, getInputBufferSize()); + networkBuffer = newNetworkBuffer(getInputBufferSize()); } } + private RetainableByteBuffer newNetworkBuffer(int capacity) + { + return new RetainableByteBuffer(bufferPool, capacity, isUseInputDirectByteBuffers()); + } + private void releaseNetworkBuffer() { synchronized (this) @@ -445,7 +472,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio { synchronized (this) { - networkBuffer = new RetainableByteBuffer(bufferPool, prefilled.remaining()); + networkBuffer = newNetworkBuffer(prefilled.remaining()); } ByteBuffer buffer = networkBuffer.getBuffer(); BufferUtil.clearToFill(buffer); @@ -572,6 +599,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio private Flusher(Scheduler scheduler, int bufferSize, Generator generator, EndPoint endpoint) { super(bufferPool, scheduler, generator, endpoint, bufferSize, 8); + setUseDirectByteBuffers(isUseOutputDirectByteBuffers()); } @Override diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCore.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCore.java index 98aec1dee39..bb54544733e 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCore.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java index b94f324b976..984269d4a65 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -23,52 +23,54 @@ import java.net.SocketAddress; import java.net.SocketTimeoutException; import java.net.URI; import java.time.Duration; -import java.util.ArrayDeque; import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.Utf8Appendable; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.Behavior; -import org.eclipse.jetty.websocket.core.CloseException; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.IncomingFrames; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.OutgoingFrames; -import org.eclipse.jetty.websocket.core.ProtocolException; +import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketConstants; -import org.eclipse.jetty.websocket.core.WebSocketTimeoutException; -import org.eclipse.jetty.websocket.core.WebSocketWriteTimeoutException; +import org.eclipse.jetty.websocket.core.exception.CloseException; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException; +import org.eclipse.jetty.websocket.core.exception.WebSocketWriteTimeoutException; import org.eclipse.jetty.websocket.core.internal.Parser.ParsedFrame; -import org.eclipse.jetty.websocket.core.internal.compress.DeflateFrameExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.util.Callback.NOOP; /** * The Core WebSocket Session. */ -public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSession, Dumpable +public class WebSocketCoreSession implements IncomingFrames, CoreSession, Dumpable { - private static final Logger LOG = Log.getLogger(WebSocketCoreSession.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketCoreSession.class); private static final CloseStatus NO_CODE = new CloseStatus(CloseStatus.NO_CODE); + private final WebSocketComponents components; private final Behavior behavior; private final WebSocketSessionState sessionState = new WebSocketSessionState(); private final FrameHandler handler; private final Negotiated negotiated; private final boolean demanding; - private final Flusher flusher = new Flusher(); + private final Flusher flusher = new Flusher(this); private WebSocketConnection connection; private boolean autoFragment = WebSocketConstants.DEFAULT_AUTO_FRAGMENT; @@ -79,16 +81,37 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe private long maxTextMessageSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; private Duration idleTimeout = WebSocketConstants.DEFAULT_IDLE_TIMEOUT; private Duration writeTimeout = WebSocketConstants.DEFAULT_WRITE_TIMEOUT; + private final ContextHandler contextHandler; - public WebSocketCoreSession(FrameHandler handler, Behavior behavior, Negotiated negotiated) + public WebSocketCoreSession(FrameHandler handler, Behavior behavior, Negotiated negotiated, WebSocketComponents components) { + this.components = components; this.handler = handler; this.behavior = behavior; this.negotiated = negotiated; this.demanding = handler.isDemanding(); + + if (behavior == Behavior.SERVER) + { + ContextHandler.Context context = ContextHandler.getCurrentContext(); + this.contextHandler = (context != null) ? context.getContextHandler() : null; + } + else + { + this.contextHandler = null; + } + negotiated.getExtensions().initialize(new IncomingAdaptor(), new OutgoingAdaptor(), this); } + private void handle(Runnable runnable) + { + if (contextHandler != null) + contextHandler.handle(runnable); + else + runnable.run(); + } + /** * @return True if the sessions handling is demanding. */ @@ -101,6 +124,10 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe { assertValidFrame(frame); + // Validate frame size. + if (maxFrameSize > 0 && frame.getPayloadLength() > maxFrameSize) + throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize); + // Assert Incoming Frame Behavior Required by RFC-6455 / Section 5.1 switch (behavior) { @@ -133,6 +160,10 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe { assertValidFrame(frame); + // Validate frame size (allowed to be over max frame size if autoFragment is true). + if (!autoFragment && maxFrameSize > 0 && frame.getPayloadLength() > maxFrameSize) + throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize); + /* * RFC 6455 Section 5.5.1 * close frame payload is specially formatted which is checked in CloseStatus @@ -147,7 +178,6 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe throw new ProtocolException("Frame has non-transmittable status code"); } } - } } @@ -156,7 +186,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe if (!OpCode.isKnown(frame.getOpCode())) throw new ProtocolException("Unknown opcode: " + frame.getOpCode()); - int payloadLength = (frame.getPayload() == null) ? 0 : frame.getPayload().remaining(); + int payloadLength = frame.getPayloadLength(); if (frame.isControlFrame()) { if (!frame.isFin()) @@ -311,9 +341,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe if (LOG.isDebugEnabled()) LOG.debug("closeConnection() {} {} {}", closeStatus, this); - connection.cancelDemand(); - if (connection.getEndPoint().isOpen()) - connection.close(); + abort(); // Forward Errors to Local WebSocket EndPoint if (closeStatus.isAbnormal() && closeStatus.getCause() != null) @@ -322,11 +350,11 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe { try { - handler.onClosed(closeStatus, callback); + handle(() -> handler.onClosed(closeStatus, callback)); } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Failure from onClosed on handler {}", handler, e); callback.failed(e); } }); @@ -334,13 +362,13 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe Throwable cause = closeStatus.getCause(); try { - handler.onError(cause, errorCallback); + handle(() -> handler.onError(cause, errorCallback)); } catch (Throwable e) { if (e != cause) cause.addSuppressed(e); - LOG.warn(cause); + LOG.warn("Failure from onError on handler {}", handler, cause); errorCallback.failed(cause); } } @@ -348,11 +376,11 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe { try { - handler.onClosed(closeStatus, callback); + handle(() -> handler.onClosed(closeStatus, callback)); } catch (Throwable e) { - LOG.warn(e); + LOG.warn("Failure from onClosed on handler {}", handler, e); callback.failed(e); } } @@ -451,7 +479,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe try { // Open connection and handler - handler.onOpen(this, openCallback); + handle(() -> handler.onOpen(this, openCallback)); } catch (Throwable t) { @@ -470,7 +498,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe if (!demanding) throw new IllegalStateException("FrameHandler is not demanding: " + this); if (!sessionState.isInputOpen()) - throw new IllegalStateException("FrameHandler input not open: " + this); // TODO Perhaps this is a NOOP? + throw new IllegalStateException("FrameHandler input not open: " + this); connection.demand(n); } @@ -521,26 +549,22 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe try { - synchronized (flusher) + if (LOG.isDebugEnabled()) + LOG.debug("sendFrame({}, {}, {})", frame, callback, batch); + + boolean closeConnection = sessionState.onOutgoingFrame(frame); + if (closeConnection) { - if (LOG.isDebugEnabled()) - LOG.debug("sendFrame({}, {}, {})", frame, callback, batch); + Callback closeConnectionCallback = Callback.from( + () -> closeConnection(sessionState.getCloseStatus(), callback), + t -> closeConnection(sessionState.getCloseStatus(), Callback.from(callback, t))); - boolean closeConnection = sessionState.onOutgoingFrame(frame); - if (closeConnection) - { - Callback closeConnectionCallback = Callback.from( - () -> closeConnection(sessionState.getCloseStatus(), callback), - t -> closeConnection(sessionState.getCloseStatus(), Callback.from(callback, t))); - - flusher.queue.offer(new FrameEntry(frame, closeConnectionCallback, false)); - } - else - { - flusher.queue.offer(new FrameEntry(frame, callback, batch)); - } + flusher.sendFrame(frame, closeConnectionCallback, false); + } + else + { + flusher.sendFrame(frame, callback, batch); } - flusher.iterate(); } catch (Throwable t) { @@ -563,11 +587,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe @Override public void flush(Callback callback) { - synchronized (flusher) - { - flusher.queue.offer(new FrameEntry(FrameFlusher.FLUSH_FRAME, callback, false)); - } - flusher.iterate(); + flusher.sendFrame(FrameFlusher.FLUSH_FRAME, callback, false); } @Override @@ -589,9 +609,6 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe @Override public void setAutoFragment(boolean autoFragment) { - // TODO: consider adding extensible/generic mechanism for extensions to validate configuration changes if more examples occur - if (autoFragment && getExtensionStack().getRsv1User() instanceof DeflateFrameExtension) - LOG.warn("Frame auto-fragmentation must not be used with DeflateFrameExtension"); this.autoFragment = autoFragment; } @@ -672,7 +689,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe // Handle inbound frame if (frame.getOpCode() != OpCode.CLOSE) { - handler.onFrame(frame, callback); + handle(() -> handler.onFrame(frame, callback)); return; } @@ -780,6 +797,12 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe return behavior; } + @Override + public WebSocketComponents getWebSocketComponents() + { + return components; + } + @Override public String toString() { @@ -795,57 +818,17 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe handler); } - private class Flusher extends IteratingCallback + private class Flusher extends FragmentingFlusher { - private final Queue queue = new ArrayDeque<>(); - FrameEntry entry; - - @Override - protected Action process() throws Throwable + public Flusher(Configuration configuration) { - synchronized (this) - { - entry = queue.poll(); - } - if (entry == null) - return Action.IDLE; - - negotiated.getExtensions().sendFrame(entry.frame, this, entry.batch); - return Action.SCHEDULED; + super(configuration); } @Override - public void succeeded() + void forwardFrame(Frame frame, Callback callback, boolean batch) { - entry.callback.succeeded(); - super.succeeded(); - } - - @Override - protected void onCompleteFailure(Throwable cause) - { - entry.callback.failed(cause); - Queue entries; - synchronized (this) - { - entries = new ArrayDeque<>(queue); - queue.clear(); - } - entries.forEach(e -> failEntry(cause, e)); - } - - private void failEntry(Throwable cause, FrameEntry e) - { - try - { - e.callback.failed(cause); - } - catch (Throwable x) - { - if (cause != x) - cause.addSuppressed(x); - LOG.warn(cause); - } + negotiated.getExtensions().sendFrame(frame, callback, batch); } } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketSessionState.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketSessionState.java index acb18f801ab..1ccf71df9f3 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketSessionState.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketSessionState.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -23,7 +23,7 @@ import java.nio.channels.ClosedChannelException; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; /** * Atomic Connection State @@ -142,7 +142,7 @@ public class WebSocketSessionState } } - public boolean onOutgoingFrame(Frame frame) throws ProtocolException + public boolean onOutgoingFrame(Frame frame) throws Exception { byte opcode = frame.getOpCode(); boolean fin = frame.isFin(); @@ -150,7 +150,7 @@ public class WebSocketSessionState synchronized (this) { if (!isOutputOpen()) - throw new IllegalStateException(_sessionState.toString()); + throw new ClosedChannelException(); if (opcode == OpCode.CLOSE) { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/ByteAccumulator.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/ByteAccumulator.java deleted file mode 100644 index bc5a7232bf7..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/ByteAccumulator.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core.internal.compress; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jetty.websocket.core.MessageTooLargeException; - -/** - * Collect up 1 or more byte arrays for later transfer to a single {@link ByteBuffer}. - *

        - * Used by decompression routines to fail if there is excessive inflation of the - * decompressed data. (either maliciously or accidentally) - *

        - */ -public class ByteAccumulator -{ - private final List chunks = new ArrayList<>(); - private final int maxSize; - private int length = 0; - - public ByteAccumulator(int maxOverallMessageSize) - { - this.maxSize = maxOverallMessageSize; - } - - public void copyChunk(byte[] buf, int offset, int length) - { - if (this.length + length > maxSize) - { - throw new MessageTooLargeException(String.format("Decompressed Message [%,d b] is too large [max %,d b]", this.length + length, maxSize)); - } - - byte[] copy = new byte[length - offset]; - System.arraycopy(buf, offset, copy, 0, length); - - chunks.add(copy); - this.length += length; - } - - public int getLength() - { - return length; - } - - public void transferTo(ByteBuffer bufferInFillMode) - { - if (bufferInFillMode.remaining() < length) - { - throw new IllegalArgumentException(String.format("Not enough space in ByteBuffer remaining [%d] for accumulated buffers length [%d]", - bufferInFillMode.remaining(), length)); - } - - for (byte[] chunk : chunks) - { - bufferInFillMode.put(chunk, 0, chunk.length); - } - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/CompressExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/CompressExtension.java deleted file mode 100644 index adc99d598bc..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/CompressExtension.java +++ /dev/null @@ -1,575 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core.internal.compress; - -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.util.ArrayDeque; -import java.util.Queue; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.zip.DataFormatException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; -import java.util.zip.ZipException; - -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.AbstractExtension; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.internal.FrameEntry; - -public abstract class CompressExtension extends AbstractExtension -{ - protected static final byte[] TAIL_BYTES = new byte[]{0x00, 0x00, (byte)0xFF, (byte)0xFF}; - protected static final ByteBuffer TAIL_BYTES_BUF = ByteBuffer.wrap(TAIL_BYTES); - private static final Logger LOG = Log.getLogger(CompressExtension.class); - - /** - * Never drop tail bytes 0000FFFF, from any frame type - */ - protected static final int TAIL_DROP_NEVER = 0; - /** - * Always drop tail bytes 0000FFFF, from all frame types - */ - protected static final int TAIL_DROP_ALWAYS = 1; - /** - * Only drop tail bytes 0000FFFF, from fin==true frames - */ - protected static final int TAIL_DROP_FIN_ONLY = 2; - - /** - * Always set RSV flag, on all frame types - */ - protected static final int RSV_USE_ALWAYS = 0; - /** - * Only set RSV flag on first frame in multi-frame messages. - *

        - * Note: this automatically means no-continuation frames have the RSV bit set - */ - protected static final int RSV_USE_ONLY_FIRST = 1; - - /** - * Inflater / Decompressed Buffer Size - */ - protected static final int INFLATE_BUFFER_SIZE = 8 * 1024; - - /** - * Deflater / Inflater: Maximum Input Buffer Size - */ - protected static final int INPUT_MAX_BUFFER_SIZE = 8 * 1024; - - /** - * Inflater : Output Buffer Size - */ - private static final int DECOMPRESS_BUF_SIZE = 8 * 1024; - - private final Queue entries = new ArrayDeque<>(); - private final IteratingCallback flusher = new Flusher(); - private Deflater deflaterImpl; - private Inflater inflaterImpl; - protected AtomicInteger decompressCount = new AtomicInteger(0); - private int tailDrop; - private int rsvUse; - - protected CompressExtension() - { - tailDrop = getTailDropMode(); - rsvUse = getRsvUseMode(); - } - - public Deflater getDeflater() - { - if (deflaterImpl == null) - deflaterImpl = getDeflaterPool().acquire(); - return deflaterImpl; - } - - public Inflater getInflater() - { - if (inflaterImpl == null) - inflaterImpl = getInflaterPool().acquire(); - return inflaterImpl; - } - - public void releaseInflater() - { - getInflaterPool().release(inflaterImpl); - inflaterImpl = null; - } - - public void releaseDeflater() - { - getInflaterPool().release(inflaterImpl); - inflaterImpl = null; - } - - /** - * Indicates use of RSV1 flag for indicating deflation is in use. - */ - @Override - public boolean isRsv1User() - { - return true; - } - - /** - * Return the mode of operation for dropping (or keeping) tail bytes in frames generated by compress (outgoing) - * - * @return either {@link #TAIL_DROP_ALWAYS}, {@link #TAIL_DROP_FIN_ONLY}, or {@link #TAIL_DROP_NEVER} - */ - abstract int getTailDropMode(); - - /** - * Return the mode of operation for RSV flag use in frames generate by compress (outgoing) - * - * @return either {@link #RSV_USE_ALWAYS} or {@link #RSV_USE_ONLY_FIRST} - */ - abstract int getRsvUseMode(); - - protected void forwardIncoming(Frame frame, Callback callback, ByteAccumulator accumulator) - { - Frame newFrame = Frame.copyWithoutPayload(frame); - - // Unset RSV1 since it's not compressed anymore. - newFrame.setRsv1(false); - - ByteBuffer buffer = getBufferPool().acquire(accumulator.getLength(), false); - try - { - int position = BufferUtil.flipToFill(buffer); - try - { - accumulator.transferTo(buffer); - } - finally - { - BufferUtil.flipToFlush(buffer, position); - } - - newFrame.setPayload(buffer); - nextIncomingFrame(newFrame, callback); - } - finally - { - getBufferPool().release(buffer); - } - } - - protected void decompress(ByteAccumulator accumulator, ByteBuffer buf) throws DataFormatException - { - if ((buf == null) || (!buf.hasRemaining())) - { - return; - } - byte[] output = new byte[DECOMPRESS_BUF_SIZE]; - - Inflater inflater = getInflater(); - - while (buf.hasRemaining() && inflater.needsInput()) - { - if (!supplyInput(inflater, buf)) - { - LOG.debug("Needed input, but no buffer could supply input"); - return; - } - - int read; - while ((read = inflater.inflate(output)) >= 0) - { - if (read == 0) - { - LOG.debug("Decompress: read 0 {}", toDetail(inflater)); - break; - } - else - { - // do something with output - if (LOG.isDebugEnabled()) - { - LOG.debug("Decompressed {} bytes: {}", read, toDetail(inflater)); - } - - accumulator.copyChunk(output, 0, read); - } - } - } - - if (LOG.isDebugEnabled()) - { - LOG.debug("Decompress: exiting {}", toDetail(inflater)); - } - } - - @Override - public void sendFrame(Frame frame, Callback callback, boolean batch) - { - // We use a queue and an IteratingCallback to handle concurrency. - // We must compress and write atomically, otherwise the compression - // context on the other end gets confused. - - if (flusher.isFailed()) - { - notifyCallbackFailure(callback, new ZipException()); - return; - } - - FrameEntry entry = new FrameEntry(frame, callback, batch); - if (LOG.isDebugEnabled()) - LOG.debug("Queuing {}", entry); - offerEntry(entry); - flusher.iterate(); - } - - private void offerEntry(FrameEntry entry) - { - synchronized (this) - { - entries.offer(entry); - } - } - - private FrameEntry pollEntry() - { - synchronized (this) - { - return entries.poll(); - } - } - - protected void notifyCallbackSuccess(Callback callback) - { - try - { - if (callback != null) - callback.succeeded(); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.debug("Exception while notifying success of callback " + callback, x); - } - } - - protected void notifyCallbackFailure(Callback callback, Throwable failure) - { - try - { - if (callback != null) - callback.failed(failure); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.debug("Exception while notifying failure of callback " + callback, x); - } - } - - private static boolean supplyInput(Inflater inflater, ByteBuffer buf) - { - if (buf.remaining() <= 0) - { - if (LOG.isDebugEnabled()) - { - LOG.debug("No data left left to supply to Inflater"); - } - return false; - } - - byte[] input; - int inputOffset; - int len; - - if (buf.hasArray()) - { - // no need to create a new byte buffer, just return this one. - len = buf.remaining(); - input = buf.array(); - inputOffset = buf.position() + buf.arrayOffset(); - buf.position(buf.position() + len); - } - else - { - // Only create an return byte buffer that is reasonable in size - len = Math.min(INPUT_MAX_BUFFER_SIZE, buf.remaining()); - input = new byte[len]; - inputOffset = 0; - buf.get(input, 0, len); - } - - inflater.setInput(input, inputOffset, len); - if (LOG.isDebugEnabled()) - { - LOG.debug("Supplied {} input bytes: {}", input.length, toDetail(inflater)); - } - return true; - } - - private static boolean supplyInput(Deflater deflater, ByteBuffer buf) - { - if (buf.remaining() <= 0) - { - if (LOG.isDebugEnabled()) - { - LOG.debug("No data left left to supply to Deflater"); - } - return false; - } - - byte[] input; - int inputOffset; - int len; - - if (buf.hasArray()) - { - // no need to create a new byte buffer, just return this one. - len = buf.remaining(); - input = buf.array(); - inputOffset = buf.position() + buf.arrayOffset(); - buf.position(buf.position() + len); - } - else - { - // Only create an return byte buffer that is reasonable in size - len = Math.min(INPUT_MAX_BUFFER_SIZE, buf.remaining()); - input = new byte[len]; - inputOffset = 0; - buf.get(input, 0, len); - } - - deflater.setInput(input, inputOffset, len); - if (LOG.isDebugEnabled()) - { - LOG.debug("Supplied {} input bytes: {}", input.length, toDetail(deflater)); - } - return true; - } - - private static String toDetail(Inflater inflater) - { - return String.format("Inflater[finished=%b,read=%d,written=%d,remaining=%d,in=%d,out=%d]", inflater.finished(), inflater.getBytesRead(), - inflater.getBytesWritten(), inflater.getRemaining(), inflater.getTotalIn(), inflater.getTotalOut()); - } - - private static String toDetail(Deflater deflater) - { - return String.format("Deflater[finished=%b,read=%d,written=%d,in=%d,out=%d]", deflater.finished(), deflater.getBytesRead(), deflater.getBytesWritten(), - deflater.getTotalIn(), deflater.getTotalOut()); - } - - public static boolean endsWithTail(ByteBuffer buf) - { - if ((buf == null) || (buf.remaining() < TAIL_BYTES.length)) - { - return false; - } - int limit = buf.limit(); - for (int i = TAIL_BYTES.length; i > 0; i--) - { - if (buf.get(limit - i) != TAIL_BYTES[TAIL_BYTES.length - i]) - { - return false; - } - } - return true; - } - - @Override - public String toString() - { - return getClass().getSimpleName(); - } - - private class Flusher extends IteratingCallback - { - private FrameEntry current; - private boolean finished = true; - - @Override - public void succeeded() - { - if (finished) - notifyCallbackSuccess(current.callback); - super.succeeded(); - } - - @Override - public void failed(Throwable cause) - { - releaseInflater(); - releaseDeflater(); - notifyCallbackFailure(current.callback, cause); - // If something went wrong, very likely the compression context - // will be invalid, so we need to fail this IteratingCallback. - LOG.warn(cause); - super.failed(cause); - } - - @Override - protected Action process() throws Exception - { - if (finished) - { - current = pollEntry(); - LOG.debug("Processing {}", current); - if (current == null) - return Action.IDLE; - deflate(current); - } - else - { - compress(current, false); - } - return Action.SCHEDULED; - } - - private void deflate(FrameEntry entry) - { - Frame frame = entry.frame; - boolean batch = entry.batch; - if (OpCode.isControlFrame(frame.getOpCode())) - { - // Do not deflate control frames - nextOutgoingFrame(frame, this, batch); - return; - } - - compress(entry, true); - } - - private void compress(FrameEntry entry, boolean first) - { - // Get a chunk of the payload to avoid to blow - // the heap if the payload is a huge mapped file. - Frame frame = entry.frame; - ByteBuffer data = frame.getPayload(); - int remaining = data.remaining(); - int outputLength = Math.max(256, data.remaining()); - if (LOG.isDebugEnabled()) - LOG.debug("Compressing {}: {} bytes in {} bytes chunk", entry, remaining, outputLength); - - boolean needsCompress = true; - - Deflater deflater = getDeflater(); - - if (deflater.needsInput() && !supplyInput(deflater, data)) - { - // no input supplied - needsCompress = false; - } - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - byte[] output = new byte[outputLength]; - - boolean fin = frame.isFin(); - - // Compress the data - while (needsCompress) - { - int compressed = deflater.deflate(output, 0, outputLength, Deflater.SYNC_FLUSH); - - // Append the output for the eventual frame. - if (LOG.isDebugEnabled()) - LOG.debug("Wrote {} bytes to output buffer", compressed); - out.write(output, 0, compressed); - - if (compressed < outputLength) - { - needsCompress = false; - } - } - - ByteBuffer payload = ByteBuffer.wrap(out.toByteArray()); - - if (payload.remaining() > 0) - { - // Handle tail bytes generated by SYNC_FLUSH. - if (LOG.isDebugEnabled()) - LOG.debug("compressed[] bytes = {}", BufferUtil.toDetailString(payload)); - - if (tailDrop == TAIL_DROP_ALWAYS) - { - if (endsWithTail(payload)) - { - payload.limit(payload.limit() - TAIL_BYTES.length); - } - if (LOG.isDebugEnabled()) - LOG.debug("payload (TAIL_DROP_ALWAYS) = {}", BufferUtil.toDetailString(payload)); - } - else if (tailDrop == TAIL_DROP_FIN_ONLY) - { - if (frame.isFin() && endsWithTail(payload)) - { - payload.limit(payload.limit() - TAIL_BYTES.length); - } - if (LOG.isDebugEnabled()) - LOG.debug("payload (TAIL_DROP_FIN_ONLY) = {}", BufferUtil.toDetailString(payload)); - } - } - else if (fin) - { - // Special case: 7.2.3.6. Generating an Empty Fragment Manually - // https://tools.ietf.org/html/rfc7692#section-7.2.3.6 - payload = ByteBuffer.wrap(new byte[]{0x00}); - } - - if (LOG.isDebugEnabled()) - { - LOG.debug("Compressed {}: input:{} -> payload:{}", entry, outputLength, payload.remaining()); - } - - boolean continuation = (frame.getOpCode() == OpCode.CONTINUATION) || !first; - Frame chunk = new Frame(continuation ? OpCode.CONTINUATION : frame.getOpCode()); - if (rsvUse == RSV_USE_ONLY_FIRST) - { - chunk.setRsv1(!continuation); - } - else - { - // always set - chunk.setRsv1(true); - } - chunk.setPayload(payload); - chunk.setFin(fin); - - nextOutgoingFrame(chunk, this, entry.batch); - } - - @Override - protected void onCompleteSuccess() - { - // This IteratingCallback never completes. - } - - @Override - protected void onCompleteFailure(Throwable x) - { - // Fail all the frames in the queue. - FrameEntry entry; - while ((entry = pollEntry()) != null) - { - notifyCallbackFailure(entry.callback, x); - } - } - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/DeflateFrameExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/DeflateFrameExtension.java deleted file mode 100644 index f9847abe129..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/DeflateFrameExtension.java +++ /dev/null @@ -1,93 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core.internal.compress; - -import java.util.zip.DataFormatException; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.BadPayloadException; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; - -/** - * Implementation of the - * deflate-frame - * extension seen out in the wild. - */ -public class DeflateFrameExtension extends CompressExtension -{ - private static final Logger LOG = Log.getLogger(DeflateFrameExtension.class); - - @Override - public String getName() - { - return "deflate-frame"; - } - - @Override - int getRsvUseMode() - { - return RSV_USE_ALWAYS; - } - - @Override - int getTailDropMode() - { - return TAIL_DROP_ALWAYS; - } - - @Override - public void onFrame(Frame frame, Callback callback) - { - // Incoming frames are always non concurrent because - // they are read and parsed with a single thread, and - // therefore there is no need for synchronization. - if ((OpCode.isControlFrame(frame.getOpCode())) || !frame.isRsv1() || !frame.hasPayload()) - { - nextIncomingFrame(frame, callback); - return; - } - - try - { - //TODO fix this to use long instead of int - if (getWebSocketCoreSession().getMaxFrameSize() > Integer.MAX_VALUE) - throw new IllegalArgumentException("maxFrameSize too large for ByteAccumulator"); - ByteAccumulator accumulator = new ByteAccumulator((int)getWebSocketCoreSession().getMaxFrameSize()); - decompress(accumulator, frame.getPayload()); - decompress(accumulator, TAIL_BYTES_BUF.slice()); - forwardIncoming(frame, callback, accumulator); - } - catch (DataFormatException e) - { - throw new BadPayloadException(e); - } - } - - @Override - public void setWebSocketCoreSession(WebSocketCoreSession coreSession) - { - // Frame auto-fragmentation must not be used with DeflateFrameExtension - coreSession.setAutoFragment(false); - super.setWebSocketCoreSession(coreSession); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/PerMessageDeflateExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/PerMessageDeflateExtension.java deleted file mode 100644 index d5f883d9a78..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/PerMessageDeflateExtension.java +++ /dev/null @@ -1,199 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core.internal.compress; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.DataFormatException; - -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.BadPayloadException; -import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; -import org.eclipse.jetty.websocket.core.WebSocketComponents; - -/** - * Per Message Deflate Compression extension for WebSocket. - *

        - * Attempts to follow Compression Extensions for WebSocket - */ -public class PerMessageDeflateExtension extends CompressExtension -{ - private static final Logger LOG = Log.getLogger(PerMessageDeflateExtension.class); - - private ExtensionConfig configRequested; - private ExtensionConfig configNegotiated; - private boolean incomingContextTakeover = true; - private boolean outgoingContextTakeover = true; - private boolean incomingCompressed; - - @Override - public String getName() - { - return "permessage-deflate"; - } - - @Override - public void onFrame(Frame frame, Callback callback) - { - // Incoming frames are always non concurrent because - // they are read and parsed with a single thread, and - // therefore there is no need for synchronization. - - // This extension requires the RSV1 bit set only in the first frame. - // Subsequent continuation frames don't have RSV1 set, but are compressed. - switch (frame.getOpCode()) - { - case OpCode.TEXT: - case OpCode.BINARY: - incomingCompressed = frame.isRsv1(); - break; - - case OpCode.CONTINUATION: - if (frame.isRsv1()) - callback.failed(new ProtocolException("Invalid RSV1 set on permessage-deflate CONTINUATION frame")); - break; - default: - break; - } - - if (OpCode.isControlFrame(frame.getOpCode()) || !incomingCompressed) - { - nextIncomingFrame(frame, callback); - return; - } - - //TODO fix this to use long instead of int - if (getWebSocketCoreSession().getMaxFrameSize() > Integer.MAX_VALUE) - throw new IllegalArgumentException("maxFrameSize too large for ByteAccumulator"); - - ByteAccumulator accumulator = new ByteAccumulator((int)getWebSocketCoreSession().getMaxFrameSize()); - - try - { - ByteBuffer payload = frame.getPayload(); - decompress(accumulator, payload); - if (frame.isFin()) - { - decompress(accumulator, TAIL_BYTES_BUF.slice()); - } - - forwardIncoming(frame, callback, accumulator); - } - catch (DataFormatException e) - { - throw new BadPayloadException(e); - } - - if (frame.isFin()) - incomingCompressed = false; - } - - @Override - protected void nextIncomingFrame(Frame frame, Callback callback) - { - if (frame.isFin() && !incomingContextTakeover) - { - LOG.debug("Incoming Context Reset"); - decompressCount.set(0); - releaseInflater(); - } - super.nextIncomingFrame(frame, callback); - } - - @Override - protected void nextOutgoingFrame(Frame frame, Callback callback, boolean batch) - { - if (frame.isFin() && !outgoingContextTakeover) - { - LOG.debug("Outgoing Context Reset"); - releaseDeflater(); - } - super.nextOutgoingFrame(frame, callback, batch); - } - - @Override - int getRsvUseMode() - { - return RSV_USE_ONLY_FIRST; - } - - @Override - int getTailDropMode() - { - return TAIL_DROP_FIN_ONLY; - } - - @Override - public void init(final ExtensionConfig config, WebSocketComponents components) - { - configRequested = new ExtensionConfig(config); - Map paramsNegotiated = new HashMap<>(); - - for (String key : config.getParameterKeys()) - { - key = key.trim(); - switch (key) - { - case "client_max_window_bits": - case "server_max_window_bits": - { - // Not supported by Jetty - // Don't negotiate these parameters - break; - } - case "client_no_context_takeover": - { - paramsNegotiated.put("client_no_context_takeover", null); - incomingContextTakeover = false; - break; - } - case "server_no_context_takeover": - { - paramsNegotiated.put("server_no_context_takeover", null); - outgoingContextTakeover = false; - break; - } - default: - { - throw new IllegalArgumentException(); - } - } - } - - configNegotiated = new ExtensionConfig(config.getName(), paramsNegotiated); - LOG.debug("config: outgoingContextTakover={}, incomingContextTakeover={} : {}", outgoingContextTakeover, incomingContextTakeover, this); - - super.init(configNegotiated, components); - } - - @Override - public String toString() - { - return String.format("%s[requested=\"%s\", negotiated=\"%s\"]", - getClass().getSimpleName(), - configRequested.getParameterizedName(), - configNegotiated.getParameterizedName()); - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/XWebkitDeflateFrameExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/XWebkitDeflateFrameExtension.java deleted file mode 100644 index fbf4f297ecd..00000000000 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/compress/XWebkitDeflateFrameExtension.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core.internal.compress; - -/** - * Implementation of the x-webkit-deflate-frame extension seen out - * in the wild. Using the alternate extension identification - */ -public class XWebkitDeflateFrameExtension extends DeflateFrameExtension -{ - @Override - public String getName() - { - return "x-webkit-deflate-frame"; - } -} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java index 8241c520132..e3cc18fc7ea 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.server; @@ -22,20 +22,15 @@ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.server.internal.HandshakerSelector; public interface Handshaker { static Handshaker newInstance() { - return new RFC6455Handshaker(); + return new HandshakerSelector(); } - boolean upgradeRequest( - WebSocketNegotiator negotiator, - HttpServletRequest request, - HttpServletResponse response, - FrameHandler.Customizer defaultCustomizer) - throws IOException; + boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, Configuration.Customizer defaultCustomizer) throws IOException; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java index 7db266a0d24..1e0658762f2 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.server; @@ -31,151 +31,29 @@ import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.QuotedCSV; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; -public class Negotiation +public abstract class Negotiation { private final Request baseRequest; private final HttpServletRequest request; private final HttpServletResponse response; - private final List offeredExtensions; - private final List offeredSubprotocols; private final WebSocketComponents components; - private final String version; - private final Boolean upgrade; - private final String key; - + private String version; + private List offeredExtensions; private List negotiatedExtensions; - private String subprotocol; + private List offeredProtocols; private ExtensionStack extensionStack; + private String protocol; - /** - * @throws BadMessageException if there is any errors parsing the upgrade request - */ - public Negotiation( - Request baseRequest, - HttpServletRequest request, - HttpServletResponse response, - WebSocketComponents components) throws BadMessageException + public Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) { this.baseRequest = baseRequest; this.request = request; this.response = response; - this.components = components; - - Boolean upgrade = null; - String key = null; - String version = null; - QuotedCSV connectionCSVs = null; - QuotedCSV extensions = null; - QuotedCSV subprotocols = null; - - try - { - for (HttpField field : baseRequest.getHttpFields()) - { - if (field.getHeader() != null) - { - switch (field.getHeader()) - { - case UPGRADE: - if (upgrade == null && "websocket".equalsIgnoreCase(field.getValue())) - upgrade = Boolean.TRUE; - break; - - case CONNECTION: - if (connectionCSVs == null) - connectionCSVs = new QuotedCSV(); - connectionCSVs.addValue(field.getValue()); - break; - - case SEC_WEBSOCKET_KEY: - key = field.getValue(); - break; - - case SEC_WEBSOCKET_VERSION: - version = field.getValue(); - break; - - case SEC_WEBSOCKET_EXTENSIONS: - if (extensions == null) - extensions = new QuotedCSV(field.getValue()); - else - extensions.addValue(field.getValue()); - break; - - case SEC_WEBSOCKET_SUBPROTOCOL: - if (subprotocols == null) - subprotocols = new QuotedCSV(field.getValue()); - else - subprotocols.addValue(field.getValue()); - break; - - default: - } - } - } - - this.version = version; - this.key = key; - this.upgrade = upgrade != null && connectionCSVs != null && connectionCSVs.getValues().stream().anyMatch(s -> s.equalsIgnoreCase("Upgrade")); - - Set available = components.getExtensionRegistry().getAvailableExtensionNames(); - offeredExtensions = extensions == null - ? Collections.emptyList() - : extensions.getValues().stream() - .map(ExtensionConfig::parse) - .filter(ec -> available.contains(ec.getName().toLowerCase()) && !ec.getName().startsWith("@")) - .collect(Collectors.toList()); - - offeredSubprotocols = subprotocols == null - ? Collections.emptyList() - : subprotocols.getValues(); - - negotiatedExtensions = new ArrayList<>(); - for (ExtensionConfig config : offeredExtensions) - { - long matches = negotiatedExtensions.stream() - .filter(negotiatedConfig -> negotiatedConfig.getName().equals(config.getName())).count(); - if (matches == 0) - negotiatedExtensions.add(config); - } - } - catch (Throwable t) - { - throw new BadMessageException("Invalid Handshake Request", t); - } - } - - public String getKey() - { - return key; - } - - public List getOfferedExtensions() - { - return offeredExtensions; - } - - public void setNegotiatedExtensions(List extensions) - { - if (extensions == offeredExtensions) - return; - negotiatedExtensions = extensions == null ? null : new ArrayList<>(extensions); - extensionStack = null; - } - - public List getNegotiatedExtensions() - { - return negotiatedExtensions; - } - - public List getOfferedSubprotocols() - { - return offeredSubprotocols; + this.components = webSocketComponents; } public Request getBaseRequest() @@ -193,50 +71,123 @@ public class Negotiation return response; } - public void setSubprotocol(String subprotocol) + public void negotiate() throws BadMessageException { - this.subprotocol = subprotocol; - response.setHeader(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), subprotocol); + try + { + negotiateHeaders(getBaseRequest()); + } + catch (Throwable x) + { + throw new BadMessageException("Invalid upgrade request", x); + } } - public String getSubprotocol() + protected void negotiateHeaders(Request baseRequest) { - return subprotocol; + QuotedCSV extensions = null; + QuotedCSV protocols = null; + for (HttpField field : baseRequest.getHttpFields()) + { + if (field.getHeader() != null) + { + switch (field.getHeader()) + { + case SEC_WEBSOCKET_VERSION: + version = field.getValue(); + break; + + case SEC_WEBSOCKET_EXTENSIONS: + if (extensions == null) + extensions = new QuotedCSV(field.getValue()); + else + extensions.addValue(field.getValue()); + break; + + case SEC_WEBSOCKET_SUBPROTOCOL: + if (protocols == null) + protocols = new QuotedCSV(field.getValue()); + else + protocols.addValue(field.getValue()); + break; + + default: + break; + } + } + } + + Set available = components.getExtensionRegistry().getAvailableExtensionNames(); + offeredExtensions = extensions == null + ? Collections.emptyList() + : extensions.getValues().stream() + .map(ExtensionConfig::parse) + .filter(ec -> available.contains(ec.getName().toLowerCase()) && !ec.getName().startsWith("@")) + .collect(Collectors.toList()); + + // Remove any parameters starting with "@", these are not to be negotiated by client (internal parameters). + offeredExtensions.forEach(ExtensionConfig::removeInternalParameters); + + offeredProtocols = protocols == null + ? Collections.emptyList() + : protocols.getValues(); + + negotiatedExtensions = new ArrayList<>(); + for (ExtensionConfig config : offeredExtensions) + { + long matches = negotiatedExtensions.stream() + .filter(negotiatedConfig -> negotiatedConfig.getName().equals(config.getName())).count(); + if (matches == 0) + negotiatedExtensions.add(new ExtensionConfig(config)); + } } + public abstract boolean validateHeaders(); + public String getVersion() { return version; } - public boolean isUpgrade() + public String getSubprotocol() { - return upgrade; + return protocol; } - public ExtensionStack getExtensionStack() + public void setSubprotocol(String protocol) { - if (extensionStack == null) - { - // Extension stack can decide to drop any of these extensions or their parameters - extensionStack = new ExtensionStack(components, Behavior.SERVER); - extensionStack.negotiate(offeredExtensions, negotiatedExtensions); - negotiatedExtensions = extensionStack.getNegotiatedExtensions(); + this.protocol = protocol; + response.setHeader(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), protocol); + } - if (extensionStack.hasNegotiatedExtensions()) - baseRequest.getResponse().setHeader(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, - ExtensionConfig.toHeaderValue(negotiatedExtensions)); - else - baseRequest.getResponse().setHeader(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, null); - } + public List getOfferedSubprotocols() + { + return offeredProtocols; + } - return extensionStack; + public List getOfferedExtensions() + { + return offeredExtensions; + } + + public List getNegotiatedExtensions() + { + return negotiatedExtensions; + } + + public void setNegotiatedExtensions(List extensions) + { + if (extensions == offeredExtensions) + return; + negotiatedExtensions = extensions; + extensionStack = null; } @Override public String toString() { - return String.format("Negotiation@%x{uri=%s,oe=%s,op=%s}", + return String.format("%s@%x{uri=%s,oe=%s,op=%s}", + getClass().getSimpleName(), hashCode(), getRequest().getRequestURI(), getOfferedExtensions(), diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketNegotiator.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketNegotiator.java index e02a110dc76..49815689baf 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketNegotiator.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketNegotiator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.server; @@ -23,11 +23,12 @@ import java.util.function.Function; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; -public interface WebSocketNegotiator extends FrameHandler.Customizer +public interface WebSocketNegotiator extends Configuration.Customizer { FrameHandler negotiate(Negotiation negotiation) throws IOException; @@ -51,7 +52,7 @@ public interface WebSocketNegotiator extends FrameHandler.Customizer }; } - static WebSocketNegotiator from(Function negotiate, FrameHandler.Customizer customizer) + static WebSocketNegotiator from(Function negotiate, Configuration.Customizer customizer) { return new AbstractNegotiator(null, customizer) { @@ -66,7 +67,7 @@ public interface WebSocketNegotiator extends FrameHandler.Customizer static WebSocketNegotiator from( Function negotiate, WebSocketComponents components, - FrameHandler.Customizer customizer) + Configuration.Customizer customizer) { return new AbstractNegotiator(components, customizer) { @@ -81,21 +82,21 @@ public interface WebSocketNegotiator extends FrameHandler.Customizer abstract class AbstractNegotiator implements WebSocketNegotiator { final WebSocketComponents components; - final FrameHandler.Customizer customizer; + final Configuration.Customizer customizer; public AbstractNegotiator() { this(null, null); } - public AbstractNegotiator(WebSocketComponents components, FrameHandler.Customizer customizer) + public AbstractNegotiator(WebSocketComponents components, Configuration.Customizer customizer) { this.components = components == null ? new WebSocketComponents() : components; this.customizer = customizer; } @Override - public void customize(FrameHandler.Configuration configurable) + public void customize(Configuration configurable) { if (customizer != null) customizer.customize(configurable); @@ -125,7 +126,7 @@ public interface WebSocketNegotiator extends FrameHandler.Customizer return components; } - public FrameHandler.Customizer getCustomizer() + public Configuration.Customizer getCustomizer() { return customizer; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java index 651ccd984de..e85fda1d2be 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.server; import java.io.IOException; +import java.util.Objects; import java.util.function.Function; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -27,13 +28,13 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.pathmap.PathSpecSet; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.FrameHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WebSocketUpgradeHandler extends HandlerWrapper { - static final Logger LOG = Log.getLogger(WebSocketUpgradeHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketUpgradeHandler.class); final Handshaker handshaker = Handshaker.newInstance(); final PathSpecSet paths = new PathSpecSet(); final WebSocketNegotiator negotiator; @@ -47,7 +48,7 @@ public class WebSocketUpgradeHandler extends HandlerWrapper public WebSocketUpgradeHandler(WebSocketNegotiator negotiator, String... pathSpecs) { - this.negotiator = negotiator; + this.negotiator = Objects.requireNonNull(negotiator); addPathSpec(pathSpecs); } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java new file mode 100644 index 00000000000..afd98b662d8 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java @@ -0,0 +1,216 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.server.internal; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.Executor; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.PreEncodedHttpField; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpTransport; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.websocket.core.Behavior; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.ExtensionConfig; +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.WebSocketConstants; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.eclipse.jetty.websocket.core.internal.ExtensionStack; +import org.eclipse.jetty.websocket.core.internal.Negotiated; +import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.eclipse.jetty.websocket.core.server.Handshaker; +import org.eclipse.jetty.websocket.core.server.Negotiation; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractHandshaker implements Handshaker +{ + protected static final Logger LOG = LoggerFactory.getLogger(AbstractHandshaker.class); + private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); + + @Override + public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, Configuration.Customizer defaultCustomizer) throws IOException + { + if (!validateRequest(request)) + return false; + + WebSocketComponents components = negotiator.getWebSocketComponents(); + Negotiation negotiation = newNegotiation(request, response, components); + if (LOG.isDebugEnabled()) + LOG.debug("negotiation {}", negotiation); + negotiation.negotiate(); + + if (!validateNegotiation(negotiation)) + return false; + + // Negotiate the FrameHandler + FrameHandler handler = negotiator.negotiate(negotiation); + if (!validateFrameHandler(handler, response)) + return false; + + // Handle error responses + Request baseRequest = negotiation.getBaseRequest(); + if (response.isCommitted()) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: response committed {}", request); + baseRequest.setHandled(true); + return false; + } + int httpStatus = response.getStatus(); + if (httpStatus > 200) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: invalid http code {} {}", httpStatus, request); + response.flushBuffer(); + baseRequest.setHandled(true); + return false; + } + + // Validate negotiated protocol + String protocol = negotiation.getSubprotocol(); + List offeredProtocols = negotiation.getOfferedSubprotocols(); + if (protocol != null) + { + if (!offeredProtocols.contains(protocol)) + throw new WebSocketException("not upgraded: selected a protocol not present in offered protocols"); + } + else + { + if (!offeredProtocols.isEmpty()) + throw new WebSocketException("not upgraded: no protocol selected from offered protocols"); + } + + // validate negotiated extensions + for (ExtensionConfig config : negotiation.getNegotiatedExtensions()) + { + if (config.getName().startsWith("@")) + continue; + + long matches = negotiation.getOfferedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (matches < 1) + throw new WebSocketException("Upgrade failed: negotiated extension not requested"); + + matches = negotiation.getNegotiatedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (matches > 1) + throw new WebSocketException("Upgrade failed: multiple negotiated extensions of the same name"); + } + + // Create and Negotiate the ExtensionStack. (ExtensionStack can drop any extensions or their parameters.) + ExtensionStack extensionStack = new ExtensionStack(components, Behavior.SERVER); + extensionStack.negotiate(negotiation.getOfferedExtensions(), negotiation.getNegotiatedExtensions()); + negotiation.setNegotiatedExtensions(extensionStack.getNegotiatedExtensions()); + if (extensionStack.hasNegotiatedExtensions()) + baseRequest.getResponse().setHeader(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, ExtensionConfig.toHeaderValue(negotiation.getNegotiatedExtensions())); + else + baseRequest.getResponse().setHeader(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, null); + + Negotiated negotiated = new Negotiated(baseRequest.getHttpURI().toURI(), protocol, baseRequest.isSecure(), extensionStack, WebSocketConstants.SPEC_VERSION_STRING); + + // Create the Session + WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated, components); + if (defaultCustomizer != null) + defaultCustomizer.customize(coreSession); + negotiator.customize(coreSession); + + if (LOG.isDebugEnabled()) + LOG.debug("session {}", coreSession); + + WebSocketConnection connection = createWebSocketConnection(baseRequest, coreSession); + if (LOG.isDebugEnabled()) + LOG.debug("connection {}", connection); + if (connection == null) + throw new WebSocketException("not upgraded: no connection"); + + HttpChannel httpChannel = baseRequest.getHttpChannel(); + HttpConfiguration httpConfig = httpChannel.getHttpConfiguration(); + connection.setUseInputDirectByteBuffers(httpConfig.isUseInputDirectByteBuffers()); + connection.setUseOutputDirectByteBuffers(httpChannel.isUseOutputDirectByteBuffers()); + + httpChannel.getConnector().getEventListeners().forEach(connection::addEventListener); + + coreSession.setWebSocketConnection(connection); + + baseRequest.setHandled(true); + Response baseResponse = baseRequest.getResponse(); + prepareResponse(baseResponse, negotiation); + if (httpConfig.getSendServerVersion()) + baseResponse.getHttpFields().put(SERVER_VERSION); + baseResponse.flushBuffer(); + + baseRequest.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, connection); + + if (LOG.isDebugEnabled()) + LOG.debug("upgrade connection={} session={} framehandler={}", connection, coreSession, handler); + + return true; + } + + protected abstract boolean validateRequest(HttpServletRequest request); + + protected abstract Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents); + + protected abstract boolean validateFrameHandler(FrameHandler frameHandler, HttpServletResponse response); + + protected boolean validateNegotiation(Negotiation negotiation) + { + if (!negotiation.validateHeaders()) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no upgrade header or connection upgrade", negotiation.getBaseRequest()); + return false; + } + + if (!WebSocketConstants.SPEC_VERSION_STRING.equals(negotiation.getVersion())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: unsupported version {} {}", negotiation.getVersion(), negotiation.getBaseRequest()); + return false; + } + + return true; + } + + protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated, WebSocketComponents components) + { + return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated, components); + } + + protected abstract WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession); + + protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + { + return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); + } + + protected abstract void prepareResponse(Response response, Negotiation negotiation); +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java new file mode 100644 index 00000000000..30a59cd2219 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.server.internal; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.server.Handshaker; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; + +/** + * Selects between the two Handshaker implementations, + * RFC6455 (HTTP/1.1 WebSocket Upgrades) + * and RFC68441 (HTTP/2 WebSocket Upgrades) + */ +public class HandshakerSelector implements Handshaker +{ + private final RFC6455Handshaker rfc6455 = new RFC6455Handshaker(); + private final RFC8441Handshaker rfc8441 = new RFC8441Handshaker(); + + @Override + public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, Configuration.Customizer defaultCustomizer) throws IOException + { + // Try HTTP/1.1 WS upgrade, if this fails try an HTTP/2 WS upgrade if no response was committed. + return rfc6455.upgradeRequest(negotiator, request, response, defaultCustomizer) || + !response.isCommitted() && rfc8441.upgradeRequest(negotiator, request, response, defaultCustomizer); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java index b5c7db8dbd7..6c876730f02 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java @@ -1,264 +1,114 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.server.internal; -import java.io.IOException; -import java.util.concurrent.Executor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.PreEncodedHttpField; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannel; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnection; -import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Scheduler; -import org.eclipse.jetty.websocket.core.Behavior; -import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketConstants; -import org.eclipse.jetty.websocket.core.WebSocketException; -import org.eclipse.jetty.websocket.core.internal.ExtensionStack; -import org.eclipse.jetty.websocket.core.internal.Negotiated; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; import org.eclipse.jetty.websocket.core.internal.WebSocketCore; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; -import org.eclipse.jetty.websocket.core.server.Handshaker; import org.eclipse.jetty.websocket.core.server.Negotiation; -import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; -public final class RFC6455Handshaker implements Handshaker +public final class RFC6455Handshaker extends AbstractHandshaker { - static final Logger LOG = Log.getLogger(RFC6455Handshaker.class); private static final HttpField UPGRADE_WEBSOCKET = new PreEncodedHttpField(HttpHeader.UPGRADE, "WebSocket"); private static final HttpField CONNECTION_UPGRADE = new PreEncodedHttpField(HttpHeader.CONNECTION, HttpHeader.UPGRADE.asString()); - private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); - public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, - FrameHandler.Customizer defaultCustomizer) throws IOException + @Override + protected boolean validateRequest(HttpServletRequest request) { - final Request baseRequest = Request.getBaseRequest(request); - final HttpChannel httpChannel = baseRequest.getHttpChannel(); - final Connector connector = httpChannel.getConnector(); - - if (negotiator == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no WebSocketNegotiator {}", baseRequest); - return false; - } - if (!HttpMethod.GET.is(request.getMethod())) { if (LOG.isDebugEnabled()) - LOG.debug("not upgraded method!=GET {}", baseRequest); + LOG.debug("not upgraded method!=GET {}", request); return false; } - if (!HttpVersion.HTTP_1_1.equals(baseRequest.getHttpVersion())) + if (!HttpVersion.HTTP_1_1.is(request.getProtocol())) { if (LOG.isDebugEnabled()) - LOG.debug("not upgraded version!=1.1 {}", baseRequest); + LOG.debug("not upgraded version!=1.1 {}", request); return false; } - ByteBufferPool pool = negotiator.getByteBufferPool(); - if (pool == null) - pool = baseRequest.getHttpChannel().getConnector().getByteBufferPool(); - - Negotiation negotiation = new Negotiation( - baseRequest, - request, - response, - new WebSocketComponents()); - if (LOG.isDebugEnabled()) - LOG.debug("negotiation {}", negotiation); - - if (!negotiation.isUpgrade()) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no upgrade header or connection upgrade", baseRequest); - return false; - } - - if (!WebSocketConstants.SPEC_VERSION_STRING.equals(negotiation.getVersion())) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: unsupported version {} {}", negotiation.getVersion(), baseRequest); - return false; - } - - if (negotiation.getKey() == null) - throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'"); - - // Negotiate the FrameHandler - FrameHandler handler = negotiator.negotiate(negotiation); - if (LOG.isDebugEnabled()) - LOG.debug("negotiated handler {}", handler); - - // Handle error responses - if (response.isCommitted()) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: response committed {}", baseRequest); - baseRequest.setHandled(true); - return false; - } - if (response.getStatus() > 200) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: error sent {} {}", response.getStatus(), baseRequest); - response.flushBuffer(); - baseRequest.setHandled(true); - return false; - } - - // Check for handler - if (handler == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no frame handler provided {}", baseRequest); - return false; - } - - // validate negotiated subprotocol - String subprotocol = negotiation.getSubprotocol(); - if (subprotocol != null) - { - if (!negotiation.getOfferedSubprotocols().contains(subprotocol)) - throw new WebSocketException("not upgraded: selected a subprotocol not present in offered subprotocols"); - } - else - { - if (!negotiation.getOfferedSubprotocols().isEmpty()) - throw new WebSocketException("not upgraded: no subprotocol selected from offered subprotocols"); - } - - // validate negotiated extensions - for (ExtensionConfig config : negotiation.getNegotiatedExtensions()) - { - if (config.getName().startsWith("@")) - continue; - - long matches = negotiation.getOfferedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (matches < 1) - throw new WebSocketException("Upgrade failed: negotiated extension not requested"); - - matches = negotiation.getNegotiatedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (matches > 1) - throw new WebSocketException("Upgrade failed: multiple negotiated extensions of the same name"); - } - - // Create and Negotiate the ExtensionStack - ExtensionStack extensionStack = negotiation.getExtensionStack(); - - Negotiated negotiated = new Negotiated( - baseRequest.getHttpURI().toURI(), - subprotocol, - baseRequest.isSecure(), - extensionStack, - WebSocketConstants.SPEC_VERSION_STRING); - - // Create the Session - WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated); - if (defaultCustomizer != null) - defaultCustomizer.customize(coreSession); - negotiator.customize(coreSession); - - if (LOG.isDebugEnabled()) - LOG.debug("session {}", coreSession); - - // Create a connection - WebSocketConnection connection = newWebSocketConnection(httpChannel.getEndPoint(), connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); - if (LOG.isDebugEnabled()) - LOG.debug("connection {}", connection); - if (connection == null) - throw new WebSocketException("not upgraded: no connection"); - - for (Connection.Listener listener : connector.getBeans(Connection.Listener.class)) - { - connection.addListener(listener); - } - - coreSession.setWebSocketConnection(connection); - - // send upgrade response - Response baseResponse = baseRequest.getResponse(); - baseResponse.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); - baseResponse.getHttpFields().put(UPGRADE_WEBSOCKET); - baseResponse.getHttpFields().put(CONNECTION_UPGRADE); - baseResponse.getHttpFields().put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(negotiation.getKey())); - - // See bugs.eclipse.org/485969 - if (getSendServerVersion(connector)) - { - baseResponse.getHttpFields().put(SERVER_VERSION); - } - - baseResponse.flushBuffer(); - baseRequest.setHandled(true); - - // upgrade - if (LOG.isDebugEnabled()) - LOG.debug("upgrade connection={} session={}", connection, coreSession); - - baseRequest.setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, connection); return true; } - protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) + @Override + protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) { - return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated); + return new RFC6455Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); } - protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + @Override + protected boolean validateNegotiation(Negotiation negotiation) { - return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); - } - - private boolean getSendServerVersion(Connector connector) - { - ConnectionFactory connFactory = connector.getConnectionFactory(HttpVersion.HTTP_1_1.asString()); - if (connFactory == null) + boolean result = super.validateNegotiation(negotiation); + if (!result) return false; + if (((RFC6455Negotiation)negotiation).getKey() == null) + throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'"); + return true; + } - if (connFactory instanceof HttpConnectionFactory) + @Override + protected boolean validateFrameHandler(FrameHandler frameHandler, HttpServletResponse response) + { + if (frameHandler == null) { - HttpConfiguration httpConf = ((HttpConnectionFactory)connFactory).getHttpConfiguration(); - if (httpConf != null) - return httpConf.getSendServerVersion(); + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no frame handler provided"); + return false; } - return false; + + return true; + } + + @Override + protected WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession) + { + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); + return newWebSocketConnection(httpChannel.getEndPoint(), connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); + } + + @Override + protected void prepareResponse(Response response, Negotiation negotiation) + { + response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + HttpFields responseFields = response.getHttpFields(); + responseFields.put(UPGRADE_WEBSOCKET); + responseFields.put(CONNECTION_UPGRADE); + responseFields.put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(((RFC6455Negotiation)negotiation).getKey())); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java new file mode 100644 index 00000000000..b36a46a3b37 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java @@ -0,0 +1,90 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.server.internal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.QuotedCSV; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.server.Negotiation; + +public class RFC6455Negotiation extends Negotiation +{ + private boolean successful; + private String key; + + public RFC6455Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException + { + super(baseRequest, request, response, components); + } + + @Override + protected void negotiateHeaders(Request baseRequest) + { + super.negotiateHeaders(baseRequest); + + boolean upgrade = false; + QuotedCSV connectionCSVs = null; + for (HttpField field : baseRequest.getHttpFields()) + { + HttpHeader header = field.getHeader(); + if (header != null) + { + switch (header) + { + case UPGRADE: + upgrade = "websocket".equalsIgnoreCase(field.getValue()); + break; + + case CONNECTION: + if (connectionCSVs == null) + connectionCSVs = new QuotedCSV(); + connectionCSVs.addValue(field.getValue()); + break; + + case SEC_WEBSOCKET_KEY: + key = field.getValue(); + break; + + default: + break; + } + } + } + + successful = upgrade && connectionCSVs != null && + connectionCSVs.getValues().stream().anyMatch(s -> s.equalsIgnoreCase("upgrade")); + } + + @Override + public boolean validateHeaders() + { + return successful; + } + + public String getKey() + { + return key; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java new file mode 100644 index 00000000000..138d7f47844 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java @@ -0,0 +1,94 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.server.internal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.eclipse.jetty.websocket.core.server.Negotiation; + +public class RFC8441Handshaker extends AbstractHandshaker +{ + @Override + protected boolean validateRequest(HttpServletRequest request) + { + if (!HttpMethod.CONNECT.is(request.getMethod())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded method!=GET {}", request); + return false; + } + + if (!HttpVersion.HTTP_2.is(request.getProtocol())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded HttpVersion!=2 {}", request); + return false; + } + + return true; + } + + @Override + protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) + { + return new RFC8441Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); + } + + @Override + protected boolean validateFrameHandler(FrameHandler frameHandler, HttpServletResponse response) + { + if (frameHandler == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no frame handler provided"); + + response.setStatus(HttpStatus.SERVICE_UNAVAILABLE_503); + } + + return true; + } + + @Override + protected WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession) + { + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); + EndPoint endPoint = httpChannel.getTunnellingEndPoint(); + return newWebSocketConnection(endPoint, connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); + } + + @Override + protected void prepareResponse(Response response, Negotiation negotiation) + { + response.setStatus(HttpStatus.OK_200); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java new file mode 100644 index 00000000000..c8e3e6570d9 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.server.internal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.server.Negotiation; + +public class RFC8441Negotiation extends Negotiation +{ + public RFC8441Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException + { + super(baseRequest, request, response, components); + } + + @Override + public boolean validateHeaders() + { + MetaData.Request metaData = getBaseRequest().getMetaData(); + if (metaData == null) + return false; + return "websocket".equals(metaData.getProtocol()); + } +} diff --git a/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension b/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension index 00e77738e94..1e4404b3a0d 100644 --- a/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension +++ b/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension @@ -1,6 +1,5 @@ org.eclipse.jetty.websocket.core.internal.IdentityExtension org.eclipse.jetty.websocket.core.internal.FragmentExtension +org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension org.eclipse.jetty.websocket.core.internal.ValidationExtension -org.eclipse.jetty.websocket.core.internal.compress.PerMessageDeflateExtension -org.eclipse.jetty.websocket.core.internal.compress.DeflateFrameExtension -org.eclipse.jetty.websocket.core.internal.compress.XWebkitDeflateFrameExtension +org.eclipse.jetty.websocket.core.internal.FrameCaptureExtension \ No newline at end of file diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AcceptHashTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AcceptHashTest.java index 6eb5e7440bf..0aa761a35d6 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AcceptHashTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AcceptHashTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java new file mode 100644 index 00000000000..06de7da071b --- /dev/null +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java @@ -0,0 +1,345 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core; + +import java.io.ByteArrayOutputStream; +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.zip.Deflater; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class AutoFragmentTest +{ + private WebSocketServer server; + private TestFrameHandler serverHandler; + private URI serverUri; + + private WebSocketCoreClient client; + + @BeforeEach + public void setup() throws Exception + { + serverHandler = new TestFrameHandler(); + + server = new WebSocketServer(serverHandler); + server.start(); + serverUri = new URI("ws://localhost:" + server.getLocalPort()); + + client = new WebSocketCoreClient(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + @Test + public void testOutgoingAutoFragmentToMaxFrameSize() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, serverUri); + connect.get(5, TimeUnit.SECONDS); + + // Turn off fragmentation on the server. + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.coreSession.setMaxFrameSize(0); + serverHandler.coreSession.setAutoFragment(false); + + // Set the client to fragment to the maxFrameSize. + int maxFrameSize = 30; + clientHandler.coreSession.setMaxFrameSize(maxFrameSize); + clientHandler.coreSession.setAutoFragment(true); + + // Send a message which is too large. + int size = maxFrameSize * 2; + byte[] array = new byte[size]; + Arrays.fill(array, 0, size, (byte)'X'); + ByteBuffer message = BufferUtil.toBuffer(array); + Frame sentFrame = new Frame(OpCode.BINARY, BufferUtil.copy(message)); + clientHandler.coreSession.sendFrame(sentFrame, Callback.NOOP, false); + + // We should not receive any frames larger than the max frame size. + // So our message should be split into two frames. + Frame frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); + assertNotNull(frame); + assertThat(frame.getOpCode(), is(OpCode.BINARY)); + assertThat(frame.getPayloadLength(), is(maxFrameSize)); + assertThat(frame.isFin(), is(false)); + + // Second frame should be final and contain rest of the data. + frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); + assertNotNull(frame); + assertThat(frame.getOpCode(), is(OpCode.CONTINUATION)); + assertThat(frame.getPayloadLength(), is(maxFrameSize)); + assertThat(frame.isFin(), is(true)); + + // Original frame payload should not have been changed. + assertThat(sentFrame.getPayload(), is(message)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testIncomingAutoFragmentToMaxFrameSize() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, serverUri); + connect.get(5, TimeUnit.SECONDS); + + // Turn off fragmentation on the client. + clientHandler.coreSession.setMaxFrameSize(0); + clientHandler.coreSession.setAutoFragment(false); + + // Set the server should fragment to the maxFrameSize. + int maxFrameSize = 30; + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.coreSession.setMaxFrameSize(maxFrameSize); + serverHandler.coreSession.setAutoFragment(true); + + // Send a message which is too large. + int size = maxFrameSize * 2; + byte[] message = new byte[size]; + Arrays.fill(message, 0, size, (byte)'X'); + clientHandler.coreSession.sendFrame(new Frame(OpCode.BINARY, BufferUtil.toBuffer(message)), Callback.NOOP, false); + + // We should not receive any frames larger than the max frame size. + // So our message should be split into two frames. + Frame frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); + assertNotNull(frame); + assertThat(frame.getOpCode(), is(OpCode.BINARY)); + assertThat(frame.getPayloadLength(), is(maxFrameSize)); + assertThat(frame.isFin(), is(false)); + + // Second frame should be final and contain rest of the data. + frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); + assertNotNull(frame); + assertThat(frame.getOpCode(), is(OpCode.CONTINUATION)); + assertThat(frame.getPayloadLength(), is(maxFrameSize)); + assertThat(frame.isFin(), is(true)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testIncomingAutoFragmentWithPermessageDeflate() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate"); + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Turn off fragmentation on the client. + clientHandler.coreSession.setMaxFrameSize(0); + clientHandler.coreSession.setAutoFragment(false); + + // Set a small maxFrameSize on the server. + int maxFrameSize = 10; + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.coreSession.setMaxFrameSize(maxFrameSize); + serverHandler.coreSession.setAutoFragment(true); + + // Generate a large random payload. + int payloadSize = 1000; + Random rand = new Random(); + ByteBuffer payload = BufferUtil.allocate(payloadSize); + BufferUtil.clearToFill(payload); + for (int i = 0; i < payloadSize; i++) + { + payload.put((byte)rand.nextInt(Byte.MAX_VALUE)); + } + BufferUtil.flipToFlush(payload, 0); + + // Send the large random payload which should be fragmented on the server. + clientHandler.coreSession.sendFrame(new Frame(OpCode.BINARY, BufferUtil.copy(payload)), Callback.NOOP, false); + + // Assemble the message from the fragmented frames. + ByteBuffer message = BufferUtil.allocate(payloadSize * 2); + Frame frame = serverHandler.receivedFrames.poll(1, TimeUnit.SECONDS); + while (frame != null) + { + int framePayloadLen = frame.getPayloadLength(); + assertThat(framePayloadLen, lessThanOrEqualTo(maxFrameSize)); + int appended = BufferUtil.append(message, frame.getPayload()); + assertThat(appended, is(framePayloadLen)); + + frame = serverHandler.receivedFrames.poll(1, TimeUnit.SECONDS); + } + + assertThat(message, is(payload)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testGzipBomb() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate"); + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Turn off fragmentation on the client. + clientHandler.coreSession.setMaxFrameSize(0); + clientHandler.coreSession.setAutoFragment(false); + + // Set a small maxFrameSize on the server. + int maxFrameSize = 1024; + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.coreSession.setMaxFrameSize(maxFrameSize); + serverHandler.coreSession.setAutoFragment(true); + + // Highly compressible payload. + byte[] data = new byte[512 * 1024]; + Arrays.fill(data, (byte)'X'); + ByteBuffer payload = ByteBuffer.wrap(data); + + // Send the payload which should be fragmented on the server. + clientHandler.coreSession.sendFrame(new Frame(OpCode.BINARY, BufferUtil.copy(payload)), Callback.NOOP, false); + + // Assemble the message from the fragmented frames. + ByteBuffer message = BufferUtil.allocate(payload.remaining() * 2); + Frame frame = serverHandler.receivedFrames.poll(1, TimeUnit.SECONDS); + while (frame != null) + { + int framePayloadLen = frame.getPayloadLength(); + assertThat(framePayloadLen, lessThanOrEqualTo(maxFrameSize)); + int appended = BufferUtil.append(message, frame.getPayload()); + assertThat(appended, is(framePayloadLen)); + + frame = serverHandler.receivedFrames.poll(1, TimeUnit.SECONDS); + } + + assertThat(message, is(payload)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testOutgoingAutoFragmentWithPermessageDeflate() throws Exception + { + // Send a frame smaller than the max frame size that increases in size when compressed. + // It should then be fragmented by permessage-deflate so no frame is sent larger than the maxFrameSize. + + // Compress a large payload a few times so compressing again will only increase size. + int payloadSize = 10000; + byte[] array = new byte[payloadSize]; + Arrays.fill(array, (byte)'X'); + ByteBuffer payload = compress(compress(BufferUtil.toBuffer(array))); + ByteBuffer compressedPayload = compress(payload); + + // Use a maxFameSize bigger than uncompressed payload but smaller than the compressed payload. + int maxFrameSize = 37; + assertThat(payload.remaining(), lessThanOrEqualTo(maxFrameSize)); + assertThat(compressedPayload.remaining(), greaterThan(maxFrameSize)); + + // Connect to server with permessage-deflate enabled. + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate"); + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Turn off fragmentation on the client. + clientHandler.coreSession.setMaxFrameSize(0); + clientHandler.coreSession.setAutoFragment(false); + + // Set maxFrameSize and autoFragment on the server. + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.coreSession.setMaxFrameSize(maxFrameSize); + serverHandler.coreSession.setAutoFragment(true); + + // Send the payload which should be fragmented by the server permessage-deflate. + ByteBuffer sendPayload = BufferUtil.copy(payload); + serverHandler.sendFrame(new Frame(OpCode.BINARY, sendPayload), Callback.NOOP, false); + + // Assemble the message from the fragmented frames. + ByteBuffer message = BufferUtil.allocate(payload.remaining() * 2); + Frame frame = clientHandler.receivedFrames.poll(1, TimeUnit.SECONDS); + int numFrames = 0; + while (frame != null) + { + numFrames++; + int framePayloadLen = frame.getPayloadLength(); + assertThat(framePayloadLen, lessThanOrEqualTo(maxFrameSize)); + int appended = BufferUtil.append(message, frame.getPayload()); + assertThat(appended, is(framePayloadLen)); + + frame = clientHandler.receivedFrames.poll(1, TimeUnit.SECONDS); + } + + // We received correct payload in 2 frames. + assertThat(message, is(payload)); + assertThat(message, is(sendPayload)); + assertThat(numFrames, is(2)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + } + + private ByteBuffer compress(ByteBuffer input) + { + Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true); + deflater.setInput(BufferUtil.copy(input)); + + int bufferSize = 1000; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[bufferSize]; + while (true) + { + int compressed = deflater.deflate(buffer, 0, bufferSize, Deflater.SYNC_FLUSH); + if (compressed <= 0) + break; + out.write(buffer, 0, compressed); + } + + return BufferUtil.toBuffer(out.toByteArray()); + } +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CapturedHexPayloads.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CapturedHexPayloads.java index 73874d4293f..14a641f1cd7 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CapturedHexPayloads.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CapturedHexPayloads.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CloseStatusTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CloseStatusTest.java index 4dc70c9d5cf..5db9469b954 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CloseStatusTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/CloseStatusTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -170,6 +170,7 @@ public class CloseStatusTest String reason = "___The WebSocket Connection Close Reason_ is defined as" + " the UTF-8-encoded data following the status code (Section 7.4)"; + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck String utf4Bytes = "\uD801\uDC00"; assertThat(reason.getBytes().length, lessThan(CloseStatus.MAX_REASON_PHRASE)); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/EchoFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/EchoFrameHandler.java index af66bb01a67..ee38f271f92 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/EchoFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/EchoFrameHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -37,7 +37,8 @@ public class EchoFrameHandler extends TestAsyncFrameHandler @Override public void onFrame(Frame frame, Callback callback) { - LOG.info("[{}] onFrame {}", name, frame); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onFrame {}", name, frame); receivedFrames.offer(Frame.copy(frame)); if (throwOnFrame) @@ -45,8 +46,10 @@ public class EchoFrameHandler extends TestAsyncFrameHandler if (frame.isDataFrame()) { - LOG.info("[{}] echoDataFrame {}", name, frame); - coreSession.sendFrame(new Frame(frame.getOpCode(), frame.getPayload()), callback, false); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] echoDataFrame {}", name, frame); + Frame echo = Frame.copy(frame).setMask(null); + coreSession.sendFrame(echo, callback, false); } else { diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FlushTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FlushTest.java new file mode 100644 index 00000000000..f787ae8fd89 --- /dev/null +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FlushTest.java @@ -0,0 +1,135 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core; + +import java.nio.channels.ClosedChannelException; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FlushTest +{ + private WebSocketServer server; + private TestFrameHandler serverHandler = new TestFrameHandler(); + private WebSocketCoreClient client; + private WebSocketComponents components = new WebSocketComponents(); + + @BeforeEach + public void startup() throws Exception + { + WebSocketNegotiator negotiator = WebSocketNegotiator.from((negotiation) -> serverHandler); + server = new WebSocketServer(negotiator); + client = new WebSocketCoreClient(null, components); + + server.start(); + client.start(); + } + + @AfterEach + public void shutdown() throws Exception + { + server.stop(); + client.stop(); + } + + @Test + public void testStandardFlush() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, server.getUri()); + connect.get(5, TimeUnit.SECONDS); + + // Send a batched frame. + clientHandler.sendFrame(new Frame(OpCode.TEXT, "text payload"), Callback.NOOP, true); + + // We have batched the frame and not sent it. + assertNull(serverHandler.receivedFrames.poll(1, TimeUnit.SECONDS)); + + // Once we flush the frame is received. + clientHandler.getCoreSession().flush(Callback.NOOP); + Frame frame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + assertThat(frame.getOpCode(), is(OpCode.TEXT)); + assertThat(frame.getPayloadAsUTF8(), is("text payload")); + + clientHandler.sendClose(); + frame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + assertThat(CloseStatus.getCloseStatus(frame).getCode(), is(CloseStatus.NO_CODE)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + assertThat(clientHandler.closeStatus.getCode(), is(CloseStatus.NO_CODE)); + } + + @Test + public void testFlushOnCloseFrame() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, server.getUri()); + connect.get(5, TimeUnit.SECONDS); + + // Send a batched frame. + clientHandler.sendFrame(new Frame(OpCode.TEXT, "text payload"), Callback.NOOP, true); + + // We have batched the frame and not sent it. + assertNull(serverHandler.receivedFrames.poll(1, TimeUnit.SECONDS)); + + // Sending the close initiates the flush and the frame is received. + clientHandler.sendClose(); + Frame frame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + assertThat(frame.getOpCode(), is(OpCode.TEXT)); + assertThat(frame.getPayloadAsUTF8(), is("text payload")); + + frame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + assertThat(CloseStatus.getCloseStatus(frame).getCode(), is(CloseStatus.NO_CODE)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + assertThat(clientHandler.closeStatus.getCode(), is(CloseStatus.NO_CODE)); + } + + @Test + public void testFlushAfterClose() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, server.getUri()); + connect.get(5, TimeUnit.SECONDS); + + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + + Callback.Completable flushCallback = new Callback.Completable(); + clientHandler.getCoreSession().flush(flushCallback); + ExecutionException e = assertThrows(ExecutionException.class, () -> flushCallback.get(5, TimeUnit.SECONDS)); + assertThat(e.getCause(), instanceOf(ClosedChannelException.class)); + } +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java new file mode 100644 index 00000000000..a891d6d932f --- /dev/null +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java @@ -0,0 +1,115 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core; + +import java.nio.ByteBuffer; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FrameBufferTest extends WebSocketTester +{ + private WebSocketServer server; + private TestFrameHandler serverHandler = new TestFrameHandler(); + private WebSocketCoreClient client; + private WebSocketComponents components = new WebSocketComponents(); + + @BeforeEach + public void startup() throws Exception + { + WebSocketNegotiator negotiator = WebSocketNegotiator.from((negotiation) -> serverHandler); + server = new WebSocketServer(negotiator); + client = new WebSocketCoreClient(null, components); + + server.start(); + client.start(); + } + + @AfterEach + public void shutdown() throws Exception + { + server.start(); + client.start(); + } + + @Test + public void testSingleFrame() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, server.getUri()); + connect.get(5, TimeUnit.SECONDS); + + ByteBuffer message = BufferUtil.toBuffer("hello world"); + ByteBuffer sendPayload = BufferUtil.copy(message); + clientHandler.sendFrame(new Frame(OpCode.BINARY, sendPayload), Callback.NOOP, false); + + Frame frame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + + assertThat(frame.getOpCode(), is(OpCode.BINARY)); + assertThat(frame.getPayload(), is(message)); + assertThat(sendPayload, is(message)); + + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + } + + @Test + public void testSendSameFrameMultipleTimes() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + client.connect(clientHandler, server.getUri()).get(5, TimeUnit.SECONDS); + serverHandler.open.await(5, TimeUnit.SECONDS); + clientHandler.coreSession.setAutoFragment(false); + serverHandler.coreSession.setAutoFragment(false); + + int payloadLen = 32 * 1024; + byte[] array = new byte[payloadLen]; + new Random().nextBytes(array); + ByteBuffer message = ByteBuffer.wrap(array); + + Frame frame = new Frame(OpCode.BINARY, BufferUtil.copy(message)); + for (int i = 0; i < 200; i++) + { + clientHandler.sendFrame(frame, Callback.NOOP, false); + Frame recvFrame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + assertThat(recvFrame.getOpCode(), is(OpCode.BINARY)); + assertThat(recvFrame.getPayload(), is(message)); + assertThat(frame.getPayload(), is(message)); + } + + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + } +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java index 93aba40780d..af413ce7ea7 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -22,6 +22,8 @@ import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.stream.Stream; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; import org.eclipse.jetty.websocket.core.internal.Generator; import org.eclipse.jetty.websocket.core.internal.Negotiated; @@ -62,7 +64,7 @@ public class GeneratorFrameFlagsTest { ExtensionStack exStack = new ExtensionStack(components, Behavior.SERVER); exStack.negotiate(new LinkedList<>(), new LinkedList<>()); - this.coreSession = new WebSocketCoreSession(new TestMessageHandler(), Behavior.CLIENT, Negotiated.from(exStack)); + this.coreSession = new WebSocketCoreSession(new TestMessageHandler(), Behavior.CLIENT, Negotiated.from(exStack), components); } @ParameterizedTest @@ -71,8 +73,8 @@ public class GeneratorFrameFlagsTest { setup(invalidFrame); - ByteBuffer buffer = ByteBuffer.allocate(100); - new Generator(components.getBufferPool()).generateWholeFrame(invalidFrame, buffer); + ByteBuffer buffer = BufferUtil.allocate(100); + new Generator().generateWholeFrame(invalidFrame, buffer); assertThrows(ProtocolException.class, () -> coreSession.assertValidOutgoing(invalidFrame)); } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundtripTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java similarity index 60% rename from jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundtripTest.java rename to jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java index 49177bf6db6..449afdd7fd6 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundtripTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.internal.Generator; import org.junit.jupiter.api.Test; @@ -32,14 +31,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertTrue; -public class GeneratorParserRoundtripTest +public class GeneratorParserRoundTripTest { private ByteBufferPool bufferPool = new MappedByteBufferPool(); @Test public void testParserAndGenerator() throws Exception { - Generator gen = new Generator(bufferPool); + Generator gen = new Generator(); ParserCapture capture = new ParserCapture(); String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"; @@ -48,15 +47,11 @@ public class GeneratorParserRoundtripTest try { // Generate Buffer - BufferUtil.flipToFill(out); Frame frame = new Frame(OpCode.TEXT).setPayload(message); - ByteBuffer header = gen.generateHeaderBytes(frame); - ByteBuffer payload = frame.getPayload(); - out.put(header); - out.put(payload); + gen.generateHeader(frame, out); + gen.generatePayload(frame, out); // Parse Buffer - BufferUtil.flipToFlush(out, 0); capture.parse(out); } finally @@ -72,13 +67,12 @@ public class GeneratorParserRoundtripTest @Test public void testParserAndGeneratorMasked() throws Exception { - Generator gen = new Generator(bufferPool); + Generator gen = new Generator(); ParserCapture capture = new ParserCapture(true, Behavior.SERVER); String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"; ByteBuffer out = bufferPool.acquire(8192, false); - BufferUtil.flipToFill(out); try { // Setup Frame @@ -90,13 +84,10 @@ public class GeneratorParserRoundtripTest frame.setMask(mask); // Generate Buffer - ByteBuffer header = gen.generateHeaderBytes(frame); - ByteBuffer payload = frame.getPayload(); - out.put(header); - out.put(payload); + gen.generateHeader(frame, out); + gen.generatePayload(frame, out); // Parse Buffer - BufferUtil.flipToFlush(out, 0); capture.parse(out); } finally diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java index fec7167ae8f..5456640b22e 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -24,19 +24,20 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.ByteBufferAssert; import org.eclipse.jetty.toolchain.test.Hex; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; import org.eclipse.jetty.websocket.core.internal.Generator; import org.eclipse.jetty.websocket.core.internal.Negotiated; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -44,17 +45,18 @@ import static org.junit.jupiter.api.Assertions.assertThrows; public class GeneratorTest { - private static final Logger LOG = Log.getLogger(Helper.class); + private static final Logger LOG = LoggerFactory.getLogger(Helper.class); - private static Generator generator = new Generator(new MappedByteBufferPool()); + private static Generator generator = new Generator(); private static WebSocketCoreSession coreSession = newWebSocketCoreSession(Behavior.SERVER); + private static WebSocketComponents components = new WebSocketComponents(); private static WebSocketCoreSession newWebSocketCoreSession(Behavior behavior) { WebSocketComponents components = new WebSocketComponents(); ExtensionStack exStack = new ExtensionStack(components, Behavior.SERVER); exStack.negotiate(new LinkedList<>(), new LinkedList<>()); - return new WebSocketCoreSession(new TestMessageHandler(), behavior, Negotiated.from(exStack)); + return new WebSocketCoreSession(new TestMessageHandler(), behavior, Negotiated.from(exStack), components); } /** @@ -64,7 +66,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_Binary_125BytePayload() + public void testGenerateBinary125BytePayload() { int length = 125; @@ -107,7 +109,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_Binary_126BytePayload() + public void testGenerateBinary126BytePayload() { int length = 126; @@ -152,7 +154,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_Binary_127BytePayload() + public void testGenerateBinary127BytePayload() { int length = 127; @@ -197,7 +199,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_Binary_128BytePayload() + public void testGenerateBinary128BytePayload() { int length = 128; @@ -242,7 +244,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_Binary_65535BytePayload() + public void testGenerateBinary65535BytePayload() { int length = 65535; @@ -286,7 +288,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_Binary_65536BytePayload() + public void testGenerateBinary65536BytePayload() { int length = 65536; @@ -327,7 +329,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.2.1 */ @Test - public void testGenerate_Binary_Empty() + public void testGenerateBinaryEmpty() { Frame binaryFrame = new Frame(OpCode.BINARY).setPayload(new byte[]{}); @@ -347,13 +349,13 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 7.3.2 */ @Test - public void testGenerate_Close_1BytePayload() + public void testGenerateClose1BytePayload() { assertThrows(ProtocolException.class, () -> new CloseStatus(Hex.asByteBuffer("00"))); } @Test - public void testGenerate_Close_CodeNoReason() + public void testGenerateCloseCodeNoReason() { CloseStatus close = new CloseStatus(CloseStatus.NORMAL); // 2 byte payload (2 bytes for status code) @@ -361,7 +363,7 @@ public class GeneratorTest } @Test - public void testGenerate_Close_CodeOkReason() + public void testGenerateCloseCodeOkReason() { CloseStatus close = new CloseStatus(CloseStatus.NORMAL, "OK"); // 4 byte payload (2 bytes for status code, 2 more for "OK") @@ -372,7 +374,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 7.3.1 */ @Test - public void testGenerate_Close_Empty() + public void testGenerateCloseEmpty() { // 0 byte payload (no status code) assertGeneratedBytes("8800", new Frame(OpCode.CLOSE)); @@ -382,7 +384,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 7.3.6 */ @Test - public void testGenerate_Close_WithInvalidStatusReason() + public void testGenerateCloseWithInvalidStatusReason() { StringBuilder message = new StringBuilder(); for (int i = 0; i < 124; ++i) @@ -409,7 +411,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 7.3.3 */ @Test - public void testGenerate_Close_WithStatus() + public void testGenerateCloseWithStatus() { CloseStatus close = new CloseStatus(1000); @@ -429,7 +431,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 7.3.5 */ @Test - public void testGenerate_Close_WithStatusMaxReason() + public void testGenerateCloseWithStatusMaxReason() { StringBuilder message = new StringBuilder(); for (int i = 0; i < 123; ++i) @@ -463,7 +465,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 7.3.4 */ @Test - public void testGenerate_Close_WithStatusReason() + public void testGenerateCloseWithStatusReason() { String message = "bad cough"; byte[] messageBytes = message.getBytes(); @@ -492,7 +494,7 @@ public class GeneratorTest * Prevent regression of masking of many packets. */ @Test - public void testGenerate_Masked_ManyFrames() + public void testGenerateMaskedManyFrames() { int pingCount = 2; @@ -529,7 +531,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 2.4 */ @Test - public void testGenerate_Ping_125BytePayload() + public void testGeneratePing125BytePayload() { byte[] bytes = new byte[125]; @@ -561,7 +563,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 2.3 */ @Test - public void testGenerate_Ping_BinaryPaylod() + public void testGeneratePingBinaryPaylod() { byte[] bytes = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; @@ -588,7 +590,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 2.1 */ @Test - public void testGenerate_Ping_Empty() + public void testGeneratePingEmpty() { Frame pingFrame = new Frame(OpCode.PING); @@ -608,7 +610,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 2.2 */ @Test - public void testGenerate_Ping_HelloPayload() + public void testGeneratePingHelloPayload() { String message = "Hello, world!"; byte[] messageBytes = StringUtil.getUtf8Bytes(message); @@ -636,7 +638,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 2.5 */ @Test - public void testGenerate_Ping_OverSizedPayload() + public void testGeneratePingOverSizedPayload() { byte[] bytes = new byte[126]; Arrays.fill(bytes, (byte)0x00); @@ -650,7 +652,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 2.5 */ @Test - public void testGenerate_Pong_OverSizedPayload() + public void testGeneratePongOverSizedPayload() { byte[] bytes = new byte[126]; Arrays.fill(bytes, (byte)0x00); @@ -667,7 +669,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_FragmentedUnmaskedTextMessage() + public void testGenerateRFC6455FragmentedUnmaskedTextMessage() { Frame text1 = new Frame(OpCode.TEXT).setPayload("Hel").setFin(false); Frame text2 = new Frame(OpCode.CONTINUATION).setPayload("lo"); @@ -699,7 +701,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_SingleMaskedPongRequest() + public void testGenerateRFC6455SingleMaskedPongRequest() { Frame pong = new Frame(OpCode.PONG).setPayload("Hello"); pong.setMask(new byte[] @@ -724,7 +726,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_SingleMaskedTextMessage() + public void testGenerateRFC6455SingleMaskedTextMessage() { Frame text = new Frame(OpCode.TEXT).setPayload("Hello"); text.setMask(new byte[] @@ -749,7 +751,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_SingleUnmasked256ByteBinaryMessage() + public void testGenerateRFC6455SingleUnmasked256ByteBinaryMessage() { int dataSize = 256; @@ -784,7 +786,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_SingleUnmasked64KBinaryMessage() + public void testGenerateRFC6455SingleUnmasked64KBinaryMessage() { int dataSize = 1024 * 64; @@ -820,7 +822,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_SingleUnmaskedPingRequest() throws Exception + public void testGenerateRFC6455SingleUnmaskedPingRequest() throws Exception { Frame ping = new Frame(OpCode.PING).setPayload("Hello"); @@ -841,7 +843,7 @@ public class GeneratorTest *

        */ @Test - public void testGenerate_RFC6455_SingleUnmaskedTextMessage() + public void testGenerateRFC6455SingleUnmaskedTextMessage() { Frame text = new Frame(OpCode.TEXT).setPayload("Hello"); @@ -861,7 +863,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.2 */ @Test - public void testGenerate_Text_125BytePaylod() + public void testGenerateText125BytePaylod() { int length = 125; byte[] buf = new byte[length]; @@ -895,7 +897,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.3 */ @Test - public void testGenerate_Text_126BytePaylod() + public void testGenerateText126BytePaylod() { int length = 126; @@ -935,7 +937,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.4 */ @Test - public void testGenerate_Text_127BytePayload() + public void testGenerateText127BytePayload() { int length = 127; @@ -975,7 +977,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.5 */ @Test - public void testGenerate_Text_128BytePayload() + public void testGenerateText128BytePayload() { int length = 128; @@ -1017,7 +1019,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.6 */ @Test - public void testGenerate_Text_65535BytePayload() + public void testGenerateText65535BytePayload() { int length = 65535; @@ -1057,7 +1059,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.7 */ @Test - public void testGenerate_Text_65536BytePayload() + public void testGenerateText65536BytePayload() { int length = 65536; @@ -1097,7 +1099,7 @@ public class GeneratorTest * From Autobahn WebSocket Client Testcase 1.1.1 */ @Test - public void testGenerate_Text_Empty() + public void testGenerateTextEmpty() { Frame textFrame = new Frame(OpCode.TEXT).setPayload(""); @@ -1114,7 +1116,7 @@ public class GeneratorTest } @Test - public void testGenerate_Text_Hello() + public void testGenerateTextHello() { Frame frame = new Frame(OpCode.TEXT).setPayload("Hello"); byte[] utf = StringUtil.getUtf8Bytes("Hello"); @@ -1122,7 +1124,7 @@ public class GeneratorTest } @Test - public void testGenerate_Text_Masked() + public void testGenerateTextMasked() { Frame frame = new Frame(OpCode.TEXT).setPayload("Hello"); byte[] maskingKey = Hex.asByteArray("11223344"); @@ -1138,7 +1140,7 @@ public class GeneratorTest } @Test - public void testGenerate_Text_Masked_OffsetSourceByteBuffer() + public void testGenerateTextMaskedOffsetSourceByteBuffer() { ByteBuffer payload = ByteBuffer.allocate(100); payload.position(5); @@ -1167,7 +1169,7 @@ public class GeneratorTest * Test the windowed generate of a frame that has no masking. */ @Test - public void testGenerate_Windowed() + public void testGenerateWindowed() { // A decent sized frame, no masking byte[] payload = new byte[10240]; @@ -1195,7 +1197,7 @@ public class GeneratorTest * This is to prevent a regression in the masking of many frames. */ @Test - public void testGenerate_WithMasking() throws Exception + public void testGenerateWithMasking() throws Exception { // A decent sized frame, with masking byte[] payload = new byte[10240]; @@ -1270,26 +1272,26 @@ public class GeneratorTest completeBufSize += Generator.MAX_HEADER_LENGTH + f.getPayloadLength(); } - ByteBuffer completeBuf = ByteBuffer.allocate(completeBufSize); - BufferUtil.clearToFill(completeBuf); + ByteBuffer completeBuf = BufferUtil.allocate(completeBufSize); // Generate from all frames for (Frame f : frames) { - ByteBuffer header = generator.generateHeaderBytes(f); - totalBytes += BufferUtil.put(header, completeBuf); + int remaining = completeBuf.remaining(); + generator.generateHeader(f, completeBuf); + totalBytes += completeBuf.remaining() - remaining; - if (f.hasPayload()) + remaining = completeBuf.remaining(); + generator.generatePayload(f, completeBuf); + + if (completeBuf.remaining() - remaining > 0) { - ByteBuffer payload = f.getPayload(); - totalBytes += payload.remaining(); + totalBytes += completeBuf.remaining() - remaining; totalParts++; - completeBuf.put(payload.slice()); } } // Return results - BufferUtil.flipToFlush(completeBuf, 0); return completeBuf; } } @@ -1323,9 +1325,8 @@ public class GeneratorTest private static ByteBuffer generate(Frame... frames) { int length = Arrays.stream(frames).mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); - ByteBuffer buffer = ByteBuffer.allocate(length); + ByteBuffer buffer = BufferUtil.allocate(length); Arrays.stream(frames).forEach(frame -> generator.generateWholeFrame(frame, buffer)); - BufferUtil.flipToFlush(buffer, 0); return buffer; } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/IncomingFramesCapture.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/IncomingFramesCapture.java index 29166ea968e..2b854a2ca03 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/IncomingFramesCapture.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/IncomingFramesCapture.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/MessageHandlerTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/MessageHandlerTest.java index e4e67f8e3ff..e48d38d58a7 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/MessageHandlerTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/MessageHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -29,7 +29,8 @@ import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.websocket.core.FrameHandler.CoreSession; +import org.eclipse.jetty.websocket.core.exception.BadPayloadException; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -43,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; public class MessageHandlerTest { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck // Testing with 4 byte UTF8 character "\uD842\uDF9F" static String fourByteUtf8String = "\uD842\uDF9F"; static byte[] fourByteUtf8Bytes = fourByteUtf8String.getBytes(StandardCharsets.UTF_8); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OpCodeTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OpCodeTest.java index c68a4d1eaa2..6d70a594ada 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OpCodeTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OpCodeTest.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; import org.eclipse.jetty.websocket.core.internal.FrameSequence; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingFramesCapture.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingFramesCapture.java index 3c4f927a59e..40ca7adf663 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingFramesCapture.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingFramesCapture.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java index dd7759ace9b..1c067d2a157 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -62,9 +62,8 @@ public class OutgoingNetworkBytesCapture implements OutgoingFrames @Override public void sendFrame(Frame frame, Callback callback, boolean batch) { - ByteBuffer buf = ByteBuffer.allocate(Generator.MAX_HEADER_LENGTH + frame.getPayloadLength()); + ByteBuffer buf = BufferUtil.allocate(Generator.MAX_HEADER_LENGTH + frame.getPayloadLength()); generator.generateWholeFrame(frame, buf); - BufferUtil.flipToFlush(buf, 0); captured.add(buf); if (callback != null) { diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java index fd5693a4bee..5f4dca8515a 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -62,6 +62,7 @@ public class ParsePayloadLengthTest public void testPayloadLength(int size, String description) throws InterruptedException { ParserCapture capture = new ParserCapture(); + capture.getCoreSession().setMaxFrameSize(0); ByteBuffer raw = BufferUtil.allocate(size + Generator.MAX_HEADER_LENGTH); BufferUtil.clearToFill(raw); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadCloseStatusCodesTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadCloseStatusCodesTest.java index 3dc9212ffa6..6fe3e60b6c5 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadCloseStatusCodesTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadCloseStatusCodesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -23,8 +23,9 @@ import java.util.stream.Stream; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; import org.eclipse.jetty.websocket.core.internal.Parser; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -91,7 +92,7 @@ public class ParserBadCloseStatusCodesTest @ParameterizedTest(name = "closeCode={0} {1}") @MethodSource("data") - public void testBadStatusCode_WithReasonPhrase(int closeCode, String description) + public void testBadStatusCodeWithReasonPhrase(int closeCode, String description) { ParserCapture capture = new ParserCapture(); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadOpCodesTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadOpCodesTest.java index 48286570d8e..a0dfcd2167a 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadOpCodesTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserBadOpCodesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -23,8 +23,9 @@ import java.util.stream.Stream; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; import org.eclipse.jetty.websocket.core.internal.Parser; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -82,7 +83,7 @@ public class ParserBadOpCodesTest @ParameterizedTest(name = "opcode={0} {1}") @MethodSource("data") - public void testText_BadOpCode_Ping(byte opcode, String description) + public void testTextBadOpCodePing(byte opcode, String description) { ParserCapture capture = new ParserCapture(); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserCapture.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserCapture.java index a15fe771eed..b69e6800135 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserCapture.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserCapture.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -56,7 +56,9 @@ public class ParserCapture WebSocketComponents components = new WebSocketComponents(); ExtensionStack exStack = new ExtensionStack(components, Behavior.SERVER); exStack.negotiate(new LinkedList<>(), new LinkedList<>()); - this.coreSession = new WebSocketCoreSession(new TestMessageHandler(), behavior, Negotiated.from(exStack)); + this.coreSession = new WebSocketCoreSession(new TestMessageHandler(), behavior, Negotiated.from(exStack), components); + coreSession.setAutoFragment(false); + coreSession.setMaxFrameSize(0); this.parser = new Parser(components.getBufferPool(), coreSession); } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserGoodCloseStatusCodesTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserGoodCloseStatusCodesTest.java index 8695230eaf6..ca6d3a83b4c 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserGoodCloseStatusCodesTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserGoodCloseStatusCodesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -86,7 +86,7 @@ public class ParserGoodCloseStatusCodesTest @ParameterizedTest(name = "closeCode={0} {1}") @MethodSource("data") - public void testGoodCloseCode_WithReasonPhrase(int closeCode, String description) throws InterruptedException + public void testGoodCloseCodeWithReasonPhrase(int closeCode, String description) throws InterruptedException { ParserCapture capture = new ParserCapture(); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java index 119250d3378..de95ce6a109 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -23,10 +23,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; import org.eclipse.jetty.websocket.core.internal.Generator; import org.eclipse.jetty.websocket.core.internal.Parser; import org.junit.jupiter.api.Test; @@ -40,19 +39,15 @@ import static org.junit.jupiter.api.Assertions.assertThrows; */ public class ParserReservedBitTest { - private ByteBufferPool bufferPool = new MappedByteBufferPool(); - private void expectProtocolException(List frames) { ParserCapture parserCapture = new ParserCapture(); // generate raw bytebuffer of provided frames int size = frames.stream().mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); + Generator generator = new Generator(); ByteBuffer raw = BufferUtil.allocate(size); - BufferUtil.clearToFill(raw); - Generator generator = new Generator(bufferPool); frames.forEach(frame -> generator.generateWholeFrame(frame, raw)); - BufferUtil.flipToFlush(raw, 0); // parse buffer try (StacklessLogging ignore = new StacklessLogging(Parser.class)) @@ -71,7 +66,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_1() + public void testCase31() { List send = new ArrayList<>(); send.add(new Frame(OpCode.TEXT).setPayload("small").setRsv1(true)); // intentionally bad @@ -88,7 +83,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_2() + public void testCase32() { List send = new ArrayList<>(); send.add(new Frame(OpCode.TEXT).setPayload("small")); @@ -107,7 +102,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_3() + public void testCase33() { List send = new ArrayList<>(); send.add(new Frame(OpCode.TEXT).setPayload("small")); @@ -126,7 +121,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_4() + public void testCase34() { List send = new ArrayList<>(); send.add(new Frame(OpCode.TEXT).setPayload("small")); @@ -145,7 +140,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_5() + public void testCase35() { byte[] payload = new byte[8]; Arrays.fill(payload, (byte)0xFF); @@ -165,7 +160,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_6() + public void testCase36() { byte[] payload = new byte[8]; Arrays.fill(payload, (byte)0xFF); @@ -185,7 +180,7 @@ public class ParserReservedBitTest * @throws Exception on test failure */ @Test - public void testCase3_7() + public void testCase37() { List send = new ArrayList<>(); Frame frame = CloseStatus.toFrame(1000); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java index f1eac07f18f..773f7a55285 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -25,11 +25,12 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.Hex; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; import org.eclipse.jetty.websocket.core.internal.Generator; import org.eclipse.jetty.websocket.core.internal.Parser; import org.hamcrest.Matchers; @@ -50,6 +51,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class ParserTest { private static final int MAX_ALLOWED_FRAME_SIZE = 4 * 1024 * 1024; + private static final byte[] mask = {0x00, (byte)0xF0, 0x0F, (byte)0xFF}; + + public static void putPayload(ByteBuffer buffer, byte[] payload) + { + int len = payload.length; + for (int i = 0; i < len; i++) + { + buffer.put((byte)(payload[i] ^ mask[i % 4])); + } + } private ParserCapture parse(Behavior behavior, int maxAllowedFrameSize, ByteBuffer buffer) { @@ -83,8 +94,8 @@ public class ParserTest buffer.put(b); if (masked) { - Generator.putMask(buffer); - Generator.putPayload(buffer, messageBytes); + buffer.put(mask); + putPayload(buffer, messageBytes); } else { @@ -98,7 +109,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.2 */ @Test - public void testParse_Binary_125BytePayload() throws InterruptedException + public void testParseBinary125BytePayload() throws InterruptedException { int length = 125; @@ -128,7 +139,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.3 */ @Test - public void testParse_Binary_126BytePayload() throws InterruptedException + public void testParseBinary126BytePayload() throws InterruptedException { int length = 126; @@ -161,7 +172,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.4 */ @Test - public void testParse_Binary_127BytePayload() throws InterruptedException + public void testParseBinary127BytePayload() throws InterruptedException { int length = 127; @@ -193,7 +204,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.5 */ @Test - public void testParse_Binary_128BytePayload() throws InterruptedException + public void testParseBinary128BytePayload() throws InterruptedException { int length = 128; @@ -225,7 +236,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.6 */ @Test - public void testParse_Binary_65535BytePayload() throws InterruptedException + public void testParseBinary65535BytePayload() throws InterruptedException { int length = 65535; @@ -257,7 +268,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.7 */ @Test - public void testParse_Binary_65536BytePayload() throws InterruptedException + public void testParseBinary65536BytePayload() throws InterruptedException { int length = 65536; @@ -289,7 +300,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.2.1 */ @Test - public void testParse_Binary_Empty() throws InterruptedException + public void testParseBinaryEmpty() throws InterruptedException { ByteBuffer expected = ByteBuffer.allocate(5); @@ -309,7 +320,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 7.3.2 */ @Test - public void testParse_Close_1BytePayload() + public void testParseClose1BytePayload() { ByteBuffer expected = Hex.asByteBuffer("880100"); @@ -321,7 +332,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 7.3.1 */ @Test - public void testParse_Close_Empty() throws InterruptedException + public void testParseCloseEmpty() throws InterruptedException { ByteBuffer expected = ByteBuffer.allocate(5); @@ -342,7 +353,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 7.4.6 */ @Test - public void testParse_Close_WithInvalidStatusReason() + public void testParseCloseWithInvalidStatusReason() { byte[] messageBytes = new byte[124]; Arrays.fill(messageBytes, (byte)'*'); @@ -380,7 +391,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 7.3.3 */ @Test - public void testParse_Close_WithStatus() throws InterruptedException + public void testParseCloseWithStatus() throws InterruptedException { ByteBuffer expected = ByteBuffer.allocate(5); @@ -401,7 +412,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 7.3.5 */ @Test - public void testParse_Close_WithStatusMaxReason() throws InterruptedException + public void testParseCloseWithStatusMaxReason() throws InterruptedException { StringBuilder message = new StringBuilder(); for (int i = 0; i < 123; ++i) @@ -436,7 +447,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 7.3.4 */ @Test - public void testParse_Close_WithStatusReason() throws InterruptedException + public void testParseCloseWithStatusReason() throws InterruptedException { String message = "bad cough"; byte[] messageBytes = message.getBytes(); @@ -467,8 +478,9 @@ public class ParserTest *

        */ @Test - public void testParse_Continuation_ManySmall() + public void testParseContinuationManySmall() { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck String utf8 = "Hello-\uC2B5@\uC39F\uC3A4\uC3BC\uC3A0\uC3A1-UTF-8!!"; byte[] msg = StringUtil.getUtf8Bytes(utf8); @@ -515,7 +527,7 @@ public class ParserTest *

        */ @Test - public void testParse_Interleaved_PingFrames() + public void testParseInterleavedPingFrames() { List send = new ArrayList<>(); send.add(new Frame(OpCode.TEXT).setPayload("f1").setFin(false)); @@ -538,7 +550,7 @@ public class ParserTest } @Test - public void testParse_Nothing() + public void testParseNothing() { ByteBuffer buf = ByteBuffer.allocate(16); // Put nothing in the buffer. @@ -553,7 +565,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 4.2.1 */ @Test - public void testParse_OpCode11() throws Exception + public void testParseOpCode11() throws Exception { ByteBuffer expected = ByteBuffer.allocate(32); @@ -569,7 +581,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 4.2.2 */ @Test - public void testParse_OpCode12() throws Exception + public void testParseOpCode12() throws Exception { ByteBuffer expected = ByteBuffer.allocate(32); @@ -585,7 +597,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 4.1.1 */ @Test - public void testParse_OpCode3() throws Exception + public void testParseOpCode3() throws Exception { ByteBuffer expected = ByteBuffer.allocate(32); @@ -601,7 +613,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 4.1.2 */ @Test - public void testParse_OpCode4() throws Exception + public void testParseOpCode4() throws Exception { ByteBuffer expected = ByteBuffer.allocate(32); @@ -617,7 +629,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 2.4 */ @Test - public void testParse_Ping_125BytePayload() throws InterruptedException + public void testParsePing125BytePayload() throws InterruptedException { byte[] bytes = new byte[125]; @@ -648,7 +660,7 @@ public class ParserTest } @Test - public void testParse_Ping_Basic() throws InterruptedException + public void testParsePingBasic() throws InterruptedException { ByteBuffer buf = ByteBuffer.allocate(16); BufferUtil.clearToFill(buf); @@ -669,7 +681,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 2.3 */ @Test - public void testParse_Ping_BinaryPayload() throws InterruptedException + public void testParsePingBinaryPayload() throws InterruptedException { byte[] bytes = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; @@ -698,7 +710,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 2.1 */ @Test - public void testParse_Ping_Empty() throws InterruptedException + public void testParsePingEmpty() throws InterruptedException { ByteBuffer expected = ByteBuffer.allocate(5); @@ -720,7 +732,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 2.2 */ @Test - public void testParse_Ping_HelloPayload() throws InterruptedException + public void testParsePingHelloPayload() throws InterruptedException { String message = "Hello, world!"; byte[] messageBytes = message.getBytes(); @@ -750,7 +762,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 2.5 */ @Test - public void testParse_Ping_OverSizedPayload() + public void testParsePingOverSizedPayload() { byte[] bytes = new byte[126]; Arrays.fill(bytes, (byte)0x00); @@ -789,7 +801,7 @@ public class ParserTest *

        */ @Test - public void testParse_PongTextClose() + public void testParsePongTextClose() { List send = new ArrayList<>(); send.add(new Frame(OpCode.PONG).setPayload("ping")); @@ -809,7 +821,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 2.5 */ @Test - public void testParse_Pong_OverSizedPayload() + public void testParsePongOverSizedPayload() { byte[] bytes = new byte[126]; Arrays.fill(bytes, (byte)0x00); @@ -848,7 +860,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_FragmentedUnmaskedTextMessage() throws InterruptedException + public void testParseRFC6455FragmentedUnmaskedTextMessage() throws InterruptedException { ParserCapture capture = new ParserCapture(); @@ -891,7 +903,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_SingleMaskedPongRequest() throws InterruptedException + public void testParseRFC6455SingleMaskedPongRequest() throws InterruptedException { ByteBuffer buf = ByteBuffer.allocate(16); // Raw bytes as found in RFC 6455, Section 5.7 - Examples @@ -916,7 +928,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_SingleMaskedTextMessage() throws InterruptedException + public void testParseRFC6455SingleMaskedTextMessage() throws InterruptedException { ByteBuffer buf = ByteBuffer.allocate(16); // Raw bytes as found in RFC 6455, Section 5.7 - Examples @@ -941,7 +953,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_SingleUnmasked256ByteBinaryMessage() throws InterruptedException + public void testParseRFC6455SingleUnmasked256ByteBinaryMessage() throws InterruptedException { int dataSize = 256; @@ -981,7 +993,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_SingleUnmasked64KByteBinaryMessage() throws InterruptedException + public void testParseRFC6455SingleUnmasked64KByteBinaryMessage() throws InterruptedException { int dataSize = 1024 * 64; @@ -1021,7 +1033,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_SingleUnmaskedPingRequest() throws InterruptedException + public void testParseRFC6455SingleUnmaskedPingRequest() throws InterruptedException { ByteBuffer buf = ByteBuffer.allocate(16); // Raw bytes as found in RFC 6455, Section 5.7 - Examples @@ -1046,7 +1058,7 @@ public class ParserTest *

        */ @Test - public void testParse_RFC6455_SingleUnmaskedTextMessage() throws InterruptedException + public void testParseRFC6455SingleUnmaskedTextMessage() throws InterruptedException { ByteBuffer buf = ByteBuffer.allocate(16); // Raw bytes as found in RFC 6455, Section 5.7 - Examples @@ -1068,7 +1080,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.2 */ @Test - public void testParse_Text_125BytePayload() throws InterruptedException + public void testParseText125BytePayload() throws InterruptedException { int length = 125; @@ -1100,7 +1112,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.3 */ @Test - public void testParse_Text_126BytePayload() throws InterruptedException + public void testParseText126BytePayload() throws InterruptedException { int length = 126; @@ -1133,7 +1145,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.4 */ @Test - public void testParse_Text_127BytePayload() throws InterruptedException + public void testParseText127BytePayload() throws InterruptedException { int length = 127; @@ -1166,7 +1178,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.5 */ @Test - public void testParse_Text_128BytePayload() throws InterruptedException + public void testParseText128BytePayload() throws InterruptedException { int length = 128; @@ -1199,7 +1211,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.6 */ @Test - public void testParse_Text_65535BytePayload() throws InterruptedException + public void testParseText65535BytePayload() throws InterruptedException { int length = 65535; @@ -1231,7 +1243,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.7 */ @Test - public void testParse_Text_65536BytePayload() throws InterruptedException + public void testParseText65536BytePayload() throws InterruptedException { int length = 65536; @@ -1264,7 +1276,7 @@ public class ParserTest * From Autobahn WebSocket Server Testcase 1.1.1 */ @Test - public void testParse_Text_Empty() throws InterruptedException + public void testParseTextEmpty() throws InterruptedException { ByteBuffer expected = ByteBuffer.allocate(5); @@ -1282,7 +1294,7 @@ public class ParserTest } @Test - public void testParse_Text_FrameTooLargeDueToPolicy() throws Exception + public void testParseTextFrameTooLargeDueToPolicy() throws Exception { // Artificially small buffer/payload final int maxAllowedFrameSize = 1024; @@ -1296,8 +1308,8 @@ public class ParserTest buf.put((byte)0x81); // text frame, fin = true buf.put((byte)(0x80 | 0x7E)); // 0x7E == 126 (a 2 byte payload length) buf.putShort((short)utf.length); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = new ParserCapture(true, Behavior.SERVER); @@ -1307,9 +1319,10 @@ public class ParserTest } @Test - public void testParse_Text_LongMasked() throws Exception + public void testParseTextLongMasked() throws Exception { StringBuilder sb = new StringBuilder(); + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck for (int i = 0; i < 3500; i++) { sb.append("Hell\uFF4f Big W\uFF4Frld "); @@ -1325,8 +1338,8 @@ public class ParserTest buf.put((byte)0x81); // text frame, fin = true buf.put((byte)(0x80 | 0x7F)); // 0x7F == 127 (a 8 byte payload length) buf.putLong(utf.length); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, 100000, buf, true); @@ -1337,7 +1350,7 @@ public class ParserTest } @Test - public void testParse_Text_ManySmallBuffers_NoAutoFragmentation() throws InterruptedException + public void testParseTextManySmallBuffersNoAutoFragmentation() throws InterruptedException { // Create frames byte[] payload = new byte[65536]; @@ -1379,9 +1392,10 @@ public class ParserTest } @Test - public void testParse_Text_MediumMasked() throws Exception + public void testParseTextMediumMasked() throws Exception { StringBuilder sb = new StringBuilder(); + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck for (int i = 0; i < 14; i++) { sb.append("Hell\uFF4f Medium W\uFF4Frld "); @@ -1397,8 +1411,8 @@ public class ParserTest buf.put((byte)0x81); buf.put((byte)(0x80 | 0x7E)); // 0x7E == 126 (a 2 byte payload length) buf.putShort((short)utf.length); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1409,7 +1423,7 @@ public class ParserTest } @Test - public void testParse_Text_ShortMasked() throws Exception + public void testParseTextShortMasked() throws Exception { String expectedText = "Hello World"; byte[] utf = expectedText.getBytes(StandardCharsets.UTF_8); @@ -1417,8 +1431,8 @@ public class ParserTest ByteBuffer buf = ByteBuffer.allocate(24); buf.put((byte)0x81); buf.put((byte)(0x80 | utf.length)); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1429,27 +1443,27 @@ public class ParserTest } @Test - public void testParse_Text_ShortMaskedFragmented() throws Exception + public void testParseTextShortMaskedFragmented() throws Exception { String part1 = "Hello "; String part2 = "World"; - byte b1[] = part1.getBytes(StandardCharsets.UTF_8); - byte b2[] = part2.getBytes(StandardCharsets.UTF_8); + byte[] b1 = part1.getBytes(StandardCharsets.UTF_8); + byte[] b2 = part2.getBytes(StandardCharsets.UTF_8); ByteBuffer buf = ByteBuffer.allocate(32); // part 1 buf.put((byte)0x01); // no fin + text buf.put((byte)(0x80 | b1.length)); - Generator.putMask(buf); - Generator.putPayload(buf, b1); + buf.put(mask); + putPayload(buf, b1); // part 2 buf.put((byte)0x80); // fin + continuation buf.put((byte)(0x80 | b2.length)); - Generator.putMask(buf); - Generator.putPayload(buf, b2); + buf.put(mask); + putPayload(buf, b2); buf.flip(); @@ -1464,8 +1478,9 @@ public class ParserTest } @Test - public void testParse_Text_ShortMaskedUtf8() throws Exception + public void testParseTextShortMaskedUtf8() throws Exception { + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck String expectedText = "Hell\uFF4f W\uFF4Frld"; byte[] utf = expectedText.getBytes(StandardCharsets.UTF_8); @@ -1473,8 +1488,8 @@ public class ParserTest ByteBuffer buf = ByteBuffer.allocate(24); buf.put((byte)0x81); buf.put((byte)(0x80 | utf.length)); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1485,7 +1500,7 @@ public class ParserTest } @Test - public void testParse_Autobahn_7_9_3() throws Exception + public void testParseAutobahn793() throws Exception { ByteBuffer buf = BufferUtil.toBuffer(TypeUtil.fromHexString("8882c2887e61c164")); Exception e = assertThrows(ProtocolException.class, () -> parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true)); @@ -1493,7 +1508,7 @@ public class ParserTest } @Test - public void testParse_Autobahn_7_9_6() throws Exception + public void testParseAutobahn796() throws Exception { ByteBuffer buf = BufferUtil.toBuffer(TypeUtil.fromHexString("88824c49cb474fbf")); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1542,6 +1557,7 @@ public class ParserTest ByteBuffer buffer = BufferUtil.allocate(32); ParserCapture capture = new ParserCapture(false, Behavior.SERVER); + capture.getCoreSession().setAutoFragment(true); data.limit(6 + 5); BufferUtil.append(buffer, data); @@ -1649,13 +1665,12 @@ public class ParserTest private ByteBuffer generate(Behavior behavior, List frames) { - Generator generator = new Generator(new MappedByteBufferPool()); + Generator generator = new Generator(); int length = frames.stream().mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); - ByteBuffer buffer = ByteBuffer.allocate(length); + ByteBuffer buffer = BufferUtil.allocate(length); frames.stream() .peek(frame -> maskIfClient(behavior, frame)) .forEach(frame -> generator.generateWholeFrame(frame, buffer)); - BufferUtil.flipToFlush(buffer, 0); return buffer; } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/RawFrameBuilder.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/RawFrameBuilder.java index f498d314a3b..16c2c655c7d 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/RawFrameBuilder.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/RawFrameBuilder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -39,7 +39,7 @@ public class RawFrameBuilder buf.put(b); } - public static void putLengthAndMask(ByteBuffer buf, int length, byte mask[]) + public static void putLengthAndMask(ByteBuffer buf, int length, byte[] mask) { if (mask != null) { @@ -53,7 +53,7 @@ public class RawFrameBuilder } } - public static void mask(final byte[] data, final byte mask[]) + public static void mask(final byte[] data, final byte[] mask) { assertThat("Mask.length", mask.length, is(4)); int len = data.length; @@ -96,7 +96,7 @@ public class RawFrameBuilder } } - public static void putMask(ByteBuffer buf, byte mask[]) + public static void putMask(ByteBuffer buf, byte[] mask) { assertThat("Mask.length", mask.length, is(4)); buf.put(mask); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/SynchronousFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/SynchronousFrameHandler.java index a04d588962c..4c286b90678 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/SynchronousFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/SynchronousFrameHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java index faac67ec21b..626cb32df8a 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -23,16 +23,17 @@ import java.util.concurrent.CountDownLatch; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestAsyncFrameHandler implements FrameHandler { - protected static final Logger LOG = Log.getLogger(TestAsyncFrameHandler.class); + protected static final Logger LOG = LoggerFactory.getLogger(TestAsyncFrameHandler.class); protected final String name; public CoreSession coreSession; public BlockingQueue receivedFrames = new BlockingArrayQueue<>(); + public CloseStatus closeStatus; public volatile Throwable error; public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch errorLatch = new CountDownLatch(1); @@ -51,7 +52,8 @@ public class TestAsyncFrameHandler implements FrameHandler @Override public void onOpen(CoreSession coreSession, Callback callback) { - LOG.info("[{}] onOpen {}", name, coreSession); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onOpen {}", name, coreSession); this.coreSession = coreSession; callback.succeeded(); openLatch.countDown(); @@ -60,7 +62,8 @@ public class TestAsyncFrameHandler implements FrameHandler @Override public void onFrame(Frame frame, Callback callback) { - LOG.info("[{}] onFrame {}", name, frame); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onFrame {}", name, frame); receivedFrames.offer(Frame.copy(frame)); callback.succeeded(); } @@ -68,7 +71,9 @@ public class TestAsyncFrameHandler implements FrameHandler @Override public void onClosed(CloseStatus closeStatus, Callback callback) { - LOG.info("[{}] onClosed {}", name, closeStatus); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onClosed {}", name, closeStatus); + this.closeStatus = closeStatus; closeLatch.countDown(); callback.succeeded(); } @@ -76,7 +81,8 @@ public class TestAsyncFrameHandler implements FrameHandler @Override public void onError(Throwable cause, Callback callback) { - LOG.info("[{}] onError {} ", name, cause == null?null:cause.toString()); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onError {} ", name, cause == null ? null : cause.toString()); error = cause; errorLatch.countDown(); callback.succeeded(); @@ -84,14 +90,16 @@ public class TestAsyncFrameHandler implements FrameHandler public void sendText(String text) { - LOG.info("[{}] sendText {} ", name, text); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] sendText {} ", name, text); Frame frame = new Frame(OpCode.TEXT, text); coreSession.sendFrame(frame, Callback.NOOP, false); } public void sendFrame(Frame frame) { - LOG.info("[{}] sendFrame {} ", name, frame); + if (LOG.isDebugEnabled()) + LOG.debug("[{}] sendFrame {} ", name, frame); coreSession.sendFrame(frame, Callback.NOOP, false); } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java index 7b0c3f40bcf..b5f0f5317cb 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -24,15 +24,16 @@ import java.util.concurrent.CountDownLatch; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestFrameHandler implements SynchronousFrameHandler { - private static Logger LOG = Log.getLogger(TestFrameHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(TestFrameHandler.class); protected CoreSession coreSession; public BlockingQueue receivedFrames = new BlockingArrayQueue<>(); + protected CloseStatus closeStatus; protected Throwable failure; public CountDownLatch open = new CountDownLatch(1); @@ -57,7 +58,8 @@ public class TestFrameHandler implements SynchronousFrameHandler @Override public void onOpen(CoreSession coreSession) { - LOG.info("onOpen {}", coreSession); + if (LOG.isDebugEnabled()) + LOG.debug("onOpen {}", coreSession); this.coreSession = coreSession; open.countDown(); } @@ -65,41 +67,53 @@ public class TestFrameHandler implements SynchronousFrameHandler @Override public void onFrame(Frame frame) { - LOG.info("onFrame: " + OpCode.name(frame.getOpCode()) + ":" + BufferUtil.toDetailString(frame.getPayload())); + if (LOG.isDebugEnabled()) + LOG.debug("onFrame: " + OpCode.name(frame.getOpCode()) + ":" + BufferUtil.toDetailString(frame.getPayload())); receivedFrames.offer(Frame.copy(frame)); } @Override public void onClosed(CloseStatus closeStatus) { - LOG.info("onClosed {}", closeStatus); + if (LOG.isDebugEnabled()) + LOG.debug("onClosed {}", closeStatus); + this.closeStatus = closeStatus; closed.countDown(); } @Override public void onError(Throwable cause) { - LOG.info("onError {} ", cause == null ? null : cause.toString()); + if (LOG.isDebugEnabled()) + LOG.debug("onError ", cause); failure = cause; error.countDown(); } public void sendText(String text) { - LOG.info("sendText {} ", text); + if (LOG.isDebugEnabled()) + LOG.debug("sendText {} ", text); Frame frame = new Frame(OpCode.TEXT, text); getCoreSession().sendFrame(frame, Callback.NOOP, false); } public void sendFrame(Frame frame) { - LOG.info("sendFrame {} ", frame); - getCoreSession().sendFrame(frame, Callback.NOOP, false); + sendFrame(frame, Callback.NOOP, false); + } + + public void sendFrame(Frame frame, Callback callback, boolean batch) + { + if (LOG.isDebugEnabled()) + LOG.debug("sendFrame {} ", frame); + getCoreSession().sendFrame(frame, callback, batch); } public void sendClose() { - LOG.info("sendClose"); + if (LOG.isDebugEnabled()) + LOG.debug("sendClose"); Frame frame = new Frame(OpCode.CLOSE); getCoreSession().sendFrame(frame, Callback.NOOP, false); } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestMessageHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestMessageHandler.java index 448eef59a30..9cabd34c483 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestMessageHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestMessageHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -24,12 +24,12 @@ import java.util.concurrent.CountDownLatch; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestMessageHandler extends MessageHandler { - protected final Logger LOG = Log.getLogger(TestMessageHandler.class); + protected static final Logger LOG = LoggerFactory.getLogger(TestMessageHandler.class); public CoreSession coreSession; public BlockingQueue textMessages = new BlockingArrayQueue<>(); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestUpgradeHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestUpgradeHandler.java index 6726f59fada..8cbb9543598 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestUpgradeHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestUpgradeHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketNegotiator.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketNegotiator.java index 53430af39e5..0b78759587c 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketNegotiator.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketNegotiator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -53,7 +53,7 @@ public class TestWebSocketNegotiator implements WebSocketNegotiator } @Override - public void customize(FrameHandler.Configuration configurable) + public void customize(Configuration configurable) { } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketUpgradeHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketUpgradeHandler.java index f63a1f65f06..c75eb8ceeaf 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketUpgradeHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketUpgradeHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/Timeouts.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/Timeouts.java index 2a3d06854dd..bfe9ab2214c 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/Timeouts.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/Timeouts.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java index 2e56a37c6ab..334b3984238 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java @@ -1,29 +1,33 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; import java.net.Socket; +import java.nio.channels.ClosedChannelException; import java.time.Duration; +import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -32,9 +36,6 @@ import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; @@ -44,14 +45,19 @@ import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.util.Callback.NOOP; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -60,7 +66,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class WebSocketCloseTest extends WebSocketTester { - private static Logger LOG = Log.getLogger(WebSocketCloseTest.class); + private static Logger LOG = LoggerFactory.getLogger(WebSocketCloseTest.class); private static final String WS_SCHEME = "ws"; private static final String WSS_SCHEME = "wss"; @@ -140,7 +146,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void serverClose_ISHUT(String scheme) throws Exception + public void testServerCloseISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -154,7 +160,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void serverDifferentClose_ISHUT(String scheme) throws Exception + public void testServerDifferentCloseISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -169,7 +175,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void serverFailClose_ISHUT(String scheme) throws Exception + public void testServerFailCloseISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); server.handler.receivedCallback.poll().failed(new Exception("test failure")); @@ -184,7 +190,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientClosesOutput_ISHUT(String scheme) throws Exception + public void testClientClosesOutputISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -198,7 +204,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientClose_OSHUT(String scheme) throws Exception + public void testClientCloseOSHUT(String scheme) throws Exception { setup(State.OSHUT, scheme); server.handler.getCoreSession().demand(1); @@ -214,7 +220,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientDifferentClose_OSHUT(String scheme) throws Exception + public void testClientDifferentCloseOSHUT(String scheme) throws Exception { setup(State.OSHUT, scheme); server.handler.getCoreSession().demand(1); @@ -230,9 +236,9 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientCloseServerFailClose_OSHUT(String scheme) throws Exception + public void testClientCloseServerFailCloseOSHUT(String scheme) throws Exception { - try (StacklessLogging stackless = new StacklessLogging(WebSocketCoreSession.class)) + try (StacklessLogging ignored = new StacklessLogging(WebSocketCoreSession.class)) { setup(State.OSHUT, scheme); server.handler.getCoreSession().demand(1); @@ -249,7 +255,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientSendsBadFrame_OPEN(String scheme) throws Exception + public void testClientSendsBadFrameOPEN(String scheme) throws Exception { setup(State.OPEN, scheme); @@ -262,7 +268,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientSendsBadFrame_OSHUT(String scheme) throws Exception + public void testClientSendsBadFrameOSHUT(String scheme) throws Exception { setup(State.OSHUT, scheme); @@ -275,7 +281,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientSendsBadFrame_ISHUT(String scheme) throws Exception + public void testClientSendsBadFrameISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -290,7 +296,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientHalfClose_ISHUT(String scheme) throws Exception + public void testClientHalfCloseISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -309,7 +315,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientCloseServerWrite_ISHUT(String scheme) throws Exception + public void testClientCloseServerWriteISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -337,7 +343,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientAborts_OPEN(String scheme) throws Exception + public void testClientAbortsOPEN(String scheme) throws Exception { setup(State.OPEN, scheme); @@ -350,7 +356,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientAborts_OSHUT(String scheme) throws Exception + public void testClientAbortsOSHUT(String scheme) throws Exception { setup(State.OSHUT, scheme); @@ -363,7 +369,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void clientAborts_ISHUT(String scheme) throws Exception + public void testClientAbortsISHUT(String scheme) throws Exception { setup(State.ISHUT, scheme); @@ -376,7 +382,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void onFrameThrows_OPEN(String scheme) throws Exception + public void testOnFrameThrowsOPEN(String scheme) throws Exception { setup(State.OPEN, scheme); @@ -394,7 +400,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void onFrameThrows_OSHUT(String scheme) throws Exception + public void testOnFrameThrowsOSHUT(String scheme) throws Exception { setup(State.OSHUT, scheme); @@ -412,7 +418,7 @@ public class WebSocketCloseTest extends WebSocketTester @ParameterizedTest @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) - public void abnormalCloseStatusIsHardClose(String scheme) throws Exception + public void testAbnormalCloseStatusIsHardClose(String scheme) throws Exception { setup(State.OPEN, scheme); @@ -425,6 +431,97 @@ public class WebSocketCloseTest extends WebSocketTester assertThat(CloseStatus.getCloseStatus(frame).getCode(), is(CloseStatus.SERVER_ERROR)); } + @ParameterizedTest + @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) + public void doubleNormalClose(String scheme) throws Exception + { + setup(State.OPEN, scheme); + + Callback.Completable callback1 = new Callback.Completable(); + server.handler.getCoreSession().close(CloseStatus.NORMAL, "normal 1", callback1); + Callback.Completable callback2 = new Callback.Completable(); + server.handler.getCoreSession().close(CloseStatus.NORMAL, "normal 2", callback2); + + // First Callback Succeeded + assertDoesNotThrow(() -> callback1.get(5, TimeUnit.SECONDS)); + + // Second Callback Failed with ClosedChannelException + ExecutionException error = assertThrows(ExecutionException.class, () -> callback2.get(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(ClosedChannelException.class)); + + // Normal close frame received on client. + Frame closeFrame = receiveFrame(client.getInputStream()); + assertThat(closeFrame.getOpCode(), is(OpCode.CLOSE)); + CloseStatus closeStatus = CloseStatus.getCloseStatus(closeFrame); + assertThat(closeStatus.getCode(), is(CloseStatus.NORMAL)); + assertThat(closeStatus.getReason(), is("normal 1")); + + // Send close response from client. + client.getOutputStream().write(RawFrameBuilder.buildClose( + new CloseStatus(CloseStatus.NORMAL, "normal response 1"), true)); + + server.handler.getCoreSession().demand(1); + assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS)); + Callback closeFrameCallback = Objects.requireNonNull(server.handler.receivedCallback.poll()); + closeFrameCallback.succeeded(); + + assertTrue(server.handler.closed.await(5, TimeUnit.SECONDS)); + assertThat(server.handler.closeStatus.getCode(), is(CloseStatus.NORMAL)); + assertThat(server.handler.closeStatus.getReason(), is("normal response 1")); + } + + @ParameterizedTest + @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) + public void doubleAbnormalClose(String scheme) throws Exception + { + setup(State.OPEN, scheme); + + Callback.Completable callback1 = new Callback.Completable(); + server.handler.getCoreSession().close(CloseStatus.SERVER_ERROR, "server error should succeed", callback1); + Callback.Completable callback2 = new Callback.Completable(); + server.handler.getCoreSession().close(CloseStatus.PROTOCOL, "protocol error should fail", callback2); + + // First Callback Succeeded + assertDoesNotThrow(() -> callback1.get(5, TimeUnit.SECONDS)); + + // Second Callback Failed with ClosedChannelException + ExecutionException error = assertThrows(ExecutionException.class, () -> callback2.get(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(ClosedChannelException.class)); + + assertTrue(server.handler.closed.await(5, TimeUnit.SECONDS)); + assertThat(server.handler.closeStatus.getCode(), is(CloseStatus.SERVER_ERROR)); + assertThat(server.handler.closeStatus.getReason(), containsString("server error should succeed")); + + Frame frame = receiveFrame(client.getInputStream()); + assertThat(CloseStatus.getCloseStatus(frame).getCode(), is(CloseStatus.SERVER_ERROR)); + } + + @ParameterizedTest + @ValueSource(strings = {WS_SCHEME, WSS_SCHEME}) + public void doubleCloseAbnormalOvertakesNormalClose(String scheme) throws Exception + { + setup(State.OPEN, scheme); + + Callback.Completable callback1 = new Callback.Completable(); + server.handler.getCoreSession().close(CloseStatus.NORMAL, "normal close (client does not complete close handshake)", callback1); + Callback.Completable callback2 = new Callback.Completable(); + server.handler.getCoreSession().close(CloseStatus.SERVER_ERROR, "error close should overtake normal close", callback2); + + // First Callback Succeeded + assertDoesNotThrow(() -> callback1.get(5, TimeUnit.SECONDS)); + + // Second Callback Failed with ClosedChannelException + ExecutionException error = assertThrows(ExecutionException.class, () -> callback2.get(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(ClosedChannelException.class)); + + assertTrue(server.handler.closed.await(5, TimeUnit.SECONDS)); + assertThat(server.handler.closeStatus.getCode(), is(CloseStatus.SERVER_ERROR)); + assertThat(server.handler.closeStatus.getReason(), containsString("error close should overtake normal close")); + + Frame frame = receiveFrame(client.getInputStream()); + assertThat(CloseStatus.getCloseStatus(frame).getCode(), is(CloseStatus.NORMAL)); + } + static class DemandingTestFrameHandler implements SynchronousFrameHandler { private CoreSession coreSession; @@ -504,7 +601,7 @@ public class WebSocketCloseTest extends WebSocketTester static class WebSocketServer extends AbstractLifeCycle { - private static Logger LOG = Log.getLogger(WebSocketServer.class); + private static Logger LOG = LoggerFactory.getLogger(WebSocketServer.class); private final Server server; private final DemandingTestFrameHandler handler; @@ -526,7 +623,7 @@ public class WebSocketCloseTest extends WebSocketTester private SslContextFactory.Server createServerSslContextFactory() { SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); return sslContextFactory; } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java index 13f0f3b5daf..3ef42883dce 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java @@ -1,33 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; import java.nio.ByteBuffer; -import org.eclipse.jetty.io.LeakTrackingByteBufferPool; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.Hex; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.websocket.core.internal.Generator; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -36,50 +32,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class WebSocketFrameTest { - public LeakTrackingByteBufferPool bufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()); - - @AfterEach - public void afterEach() - { - String id = WebSocketFrameTest.class.getSimpleName(); - assertThat("Leaked Acquires Count for [" + id + "]", bufferPool.getLeakedAcquires(), is(0L)); - assertThat("Leaked Releases Count for [" + id + "]", bufferPool.getLeakedReleases(), is(0L)); - assertThat("Leaked Resource Count for [" + id + "]", bufferPool.getLeakedResources(), is(0L)); - } - - private Generator generator; + private Generator generator = new Generator(); private ByteBuffer generateWholeFrame(Generator generator, Frame frame) { - ByteBuffer buf = ByteBuffer.allocate(frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH); + ByteBuffer buf = BufferUtil.allocate(frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH); generator.generateWholeFrame(frame, buf); - BufferUtil.flipToFlush(buf, 0); return buf; } - @BeforeEach - public void initGenerator() - { - generator = new Generator(bufferPool); - } - - @AfterEach - public void verifyNoLeaks() - { - //TODO is this right and should it be other way around - bufferPool.clearTracking(); - assertNoLeaks(bufferPool); - } - - public void assertNoLeaks(LeakTrackingByteBufferPool pool) - { - String id = this.getClass().getName(); - - assertThat("Leaked Acquires Count for [" + id + "]", pool.getLeakedAcquires(), is(0L)); - assertThat("Leaked Releases Count for [" + id + "]", pool.getLeakedReleases(), is(0L)); - assertThat("Leaked Resource Count for [" + id + "]", pool.getLeakedResources(), is(0L)); - } - private void assertFrameHex(String message, String expectedHex, ByteBuffer actual) { String actualHex = Hex.asHex(actual); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java index 848724c5e05..5f9e5482426 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -27,27 +27,35 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.websocket.core.FrameHandler.CoreSession; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.core.client.UpgradeListener; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.core.exception.UpgradeException; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.eclipse.jetty.websocket.core.server.Negotiation; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -68,11 +76,12 @@ public class WebSocketNegotiationTest extends WebSocketTester private WebSocketServer server; private WebSocketCoreClient client; + private WebSocketComponents components = new WebSocketComponents(); @BeforeEach public void startup() throws Exception { - WebSocketNegotiator negotiator = new WebSocketNegotiator.AbstractNegotiator() + WebSocketNegotiator negotiator = new WebSocketNegotiator.AbstractNegotiator(components, null) { @Override public FrameHandler negotiate(Negotiation negotiation) throws IOException @@ -96,7 +105,7 @@ public class WebSocketNegotiationTest extends WebSocketTester break; case "testNotAcceptingExtensions": - negotiation.setNegotiatedExtensions(Collections.EMPTY_LIST); + negotiation.setNegotiatedExtensions(Collections.emptyList()); break; case "testNoSubProtocolSelected": @@ -104,6 +113,7 @@ public class WebSocketNegotiationTest extends WebSocketTester break; case "test": + case "testExtensionThatDoesNotExist": case "testInvalidExtensionParameter": case "testAcceptTwoExtensionsOfSameName": case "testInvalidUpgradeRequest": @@ -118,7 +128,7 @@ public class WebSocketNegotiationTest extends WebSocketTester }; server = new WebSocketServer(negotiator); - client = new WebSocketCoreClient(); + client = new WebSocketCoreClient(null, components); server.start(); client.start(); @@ -239,6 +249,23 @@ public class WebSocketNegotiationTest extends WebSocketTester assertNull(extensionHeader.get(5, TimeUnit.SECONDS)); } + @Test + public void testExtensionThatDoesNotExist() throws Exception + { + Socket client = new Socket(); + client.connect(new InetSocketAddress("127.0.0.1", server.getLocalPort())); + + HttpFields httpFields = newUpgradeRequest("nonExistentExtensionName"); + String upgradeRequest = "GET / HTTP/1.1\r\n" + httpFields; + client.getOutputStream().write(upgradeRequest.getBytes(StandardCharsets.ISO_8859_1)); + String response = getUpgradeResponse(client.getInputStream()); + + assertThat(response, startsWith("HTTP/1.1 101 Switching Protocols")); + assertThat(response, containsString("Sec-WebSocket-Protocol: test")); + assertThat(response, containsString("Sec-WebSocket-Accept: +WahVcVmeMLKQUMm0fvPrjSjwzI=")); + assertThat(response, not(containsString(HttpHeader.SEC_WEBSOCKET_EXTENSIONS.asString()))); + } + @Test public void testAcceptTwoExtensionsOfSameName() throws Exception { @@ -334,4 +361,133 @@ public class WebSocketNegotiationTest extends WebSocketTester assertThat(response, containsString("400 Bad Request")); } -} \ No newline at end of file + + @Test + public void testListenerExtensionSelection() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, server.getUri(), clientHandler); + upgradeRequest.setSubProtocols("test"); + + CompletableFuture extensionHeader = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeRequest(HttpRequest request) + { + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "permessage-deflate"); + } + + @Override + public void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + extensionHeader.complete(response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS)); + } + }); + + client.connect(upgradeRequest).get(5, TimeUnit.SECONDS); + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + + assertThat(extensionHeader.get(5, TimeUnit.SECONDS), is("permessage-deflate")); + } + + @Test + public void testListenerExtensionSelectionError() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, server.getUri(), clientHandler); + upgradeRequest.setSubProtocols("test"); + upgradeRequest.addExtensions("permessage-deflate;server_no_context_takeover"); + + CompletableFuture extensionHeader = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeRequest(HttpRequest request) + { + request.getHeaders().put(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "permessage-deflate"); + } + }); + + ExecutionException error = assertThrows(ExecutionException.class, + () -> client.connect(upgradeRequest).get(5, TimeUnit.SECONDS)); + + Throwable upgradeException = error.getCause(); + assertThat(upgradeException, instanceOf(UpgradeException.class)); + Throwable cause = upgradeException.getCause(); + assertThat(cause, instanceOf(IllegalStateException.class)); + assertThat(cause.getMessage(), is("Extensions set in both the ClientUpgradeRequest and UpgradeListener")); + } + + public static Stream internalExtensionScenarios() throws Exception + { + return Stream.of( + Arguments.of("", ""), + Arguments.of("ext1", "ext1"), + Arguments.of("@int1", "@int1"), + Arguments.of("ext1, ext1", "ext1"), + Arguments.of("ext1, @int1", "ext1, @int1"), + Arguments.of("@int1, ext1", "@int1, ext1"), + Arguments.of("@int1, @int1", "@int1, @int1"), + Arguments.of("@int1, ext1, ext2", "@int1, ext1, ext2"), + Arguments.of("ext1, @int1, ext2", "ext1, @int1, ext2"), + Arguments.of("ext1, ext2, @int1", "ext1, ext2, @int1"), + Arguments.of("@int1, ext1, @int2, ext2, @int3", "@int1, ext1, @int2, ext2, @int3"), + Arguments.of("ext1, ext1, ext1, @int1, ext2", "ext1, @int1, ext2"), + Arguments.of("ext1, @int1, ext1, ext1, ext2", "@int1, ext1, ext2"), + Arguments.of("ext1, ext2, ext3, @int1", "ext1, ext2, ext3, @int1") + ); + } + + @ParameterizedTest + @MethodSource("internalExtensionScenarios") + public void testClientRequestedInternalExtensions(String reqExts, String negExts) throws Exception + { + // Add some simple Extensions for to make test examples clearer. + WebSocketExtensionRegistry extRegistry = components.getExtensionRegistry(); + extRegistry.register("ext1", AbstractExtension.class); + extRegistry.register("ext2", AbstractExtension.class); + extRegistry.register("ext3", AbstractExtension.class); + extRegistry.register("@int1", AbstractExtension.class); + extRegistry.register("@int2", AbstractExtension.class); + extRegistry.register("@int3", AbstractExtension.class); + + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture extensionHeader = new CompletableFuture<>(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, server.getUri(), clientHandler); + upgradeRequest.setSubProtocols("test"); + if (!StringUtil.isEmpty(reqExts)) + upgradeRequest.addExtensions(reqExts.split(",")); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + extensionHeader.complete(response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS)); + } + }); + + // Connect to the client then close the Session. + client.connect(upgradeRequest).get(5, TimeUnit.SECONDS); + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + + // We had no internal Extensions in the response headers. + assertThat(extensionHeader.get(5, TimeUnit.SECONDS), not(containsString("@"))); + + // The list of Extensions on the client contains the internal Extensions. + StringBuilder negotiatedExtensions = new StringBuilder(); + List extensions = ((WebSocketCoreSession)clientHandler.coreSession).getExtensionStack().getExtensions(); + for (int i = 0; i < extensions.size(); i++) + { + negotiatedExtensions.append(extensions.get(i).getConfig().getParameterizedName()); + if (i != extensions.size() - 1) + negotiatedExtensions.append(", "); + } + assertThat(negotiatedExtensions.toString(), is(negExts)); + } +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java index 7d42b3e2a51..a96241d613d 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java @@ -1,38 +1,36 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; import java.net.Socket; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; -import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.core.internal.Parser; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.util.Callback.NOOP; import static org.hamcrest.MatcherAssert.assertThat; @@ -48,10 +46,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class WebSocketOpenTest extends WebSocketTester { - private static Logger LOG = Log.getLogger(WebSocketOpenTest.class); + private static Logger LOG = LoggerFactory.getLogger(WebSocketOpenTest.class); private WebSocketServer server; - private TestFrameHandler serverHandler; + private DemandingAsyncFrameHandler serverHandler; private Socket client; @AfterEach @@ -61,9 +59,9 @@ public class WebSocketOpenTest extends WebSocketTester server.stop(); } - public void setup(BiFunction onOpen) throws Exception + public void setup(BiFunction onOpen) throws Exception { - serverHandler = new TestFrameHandler(onOpen); + serverHandler = new DemandingAsyncFrameHandler(onOpen); server = new WebSocketServer(serverHandler); server.start(); client = newClient(server.getLocalPort()); @@ -75,7 +73,7 @@ public class WebSocketOpenTest extends WebSocketTester setup((s, c) -> { assertThat(s.toString(), containsString("CONNECTED")); - WebSocketOpenTest.TestFrameHandler.sendText(s, "Hello", Callback.NOOP); + s.sendFrame(new Frame(OpCode.TEXT, "Hello"), NOOP, false); c.succeeded(); s.demand(1); return null; @@ -84,7 +82,7 @@ public class WebSocketOpenTest extends WebSocketTester assertThat(frame.getPayloadAsUTF8(), is("Hello")); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.NORMAL)); frame = receiveFrame(client.getInputStream()); @@ -104,10 +102,10 @@ public class WebSocketOpenTest extends WebSocketTester return null; }); - assertTrue(serverHandler.onError.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.error, notNullValue()); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.SERVER_ERROR)); Parser.ParsedFrame frame = receiveFrame(client.getInputStream()); @@ -131,14 +129,14 @@ public class WebSocketOpenTest extends WebSocketTester assertThat(new CloseStatus(frame).getCode(), is(CloseStatus.SHUTDOWN)); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.SHUTDOWN)); } @Test public void testAsyncOnOpen() throws Exception { - Exchanger sx = new Exchanger<>(); + Exchanger sx = new Exchanger<>(); Exchanger cx = new Exchanger<>(); setup((s, c) -> { @@ -155,23 +153,23 @@ public class WebSocketOpenTest extends WebSocketTester return null; }); - FrameHandler.CoreSession coreSession = sx.exchange(null); + CoreSession coreSession = sx.exchange(null); Callback onOpenCallback = cx.exchange(null); Thread.sleep(100); // Can send while onOpen is active - WebSocketOpenTest.TestFrameHandler.sendText(coreSession, "Hello", NOOP); + coreSession.sendFrame(new Frame(OpCode.TEXT, "Hello"), NOOP, false); Parser.ParsedFrame frame = receiveFrame(client.getInputStream()); assertThat(frame.getPayloadAsUTF8(), is("Hello")); // But cannot receive client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertFalse(serverHandler.onClosed.await(1, TimeUnit.SECONDS)); + assertFalse(serverHandler.closeLatch.await(1, TimeUnit.SECONDS)); // Can't demand until open assertThrows(Throwable.class, () -> coreSession.demand(1)); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertFalse(serverHandler.onClosed.await(1, TimeUnit.SECONDS)); + assertFalse(serverHandler.closeLatch.await(1, TimeUnit.SECONDS)); // Succeeded moves to OPEN state and still does not read CLOSE frame onOpenCallback.succeeded(); @@ -180,36 +178,21 @@ public class WebSocketOpenTest extends WebSocketTester // Demand start receiving frames coreSession.demand(1); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); // Closed handled normally - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.NORMAL)); frame = receiveFrame(client.getInputStream()); assertThat(frame.getOpCode(), is(OpCode.CLOSE)); assertThat(new CloseStatus(frame).getCode(), is(CloseStatus.NORMAL)); } - static class TestFrameHandler implements SynchronousFrameHandler + static class DemandingAsyncFrameHandler extends TestAsyncFrameHandler { - private CoreSession coreSession; private BiFunction onOpen; - private CloseStatus closeStatus; - private CountDownLatch onClosed = new CountDownLatch(1); - private Throwable error; - private CountDownLatch onError = new CountDownLatch(1); - private Frame frame; - private CountDownLatch onFrame = new CountDownLatch(1); - public CoreSession getCoreSession() - { - synchronized (this) - { - return coreSession; - } - } - - TestFrameHandler(BiFunction onOpen) + DemandingAsyncFrameHandler(BiFunction onOpen) { this.onOpen = onOpen; } @@ -217,44 +200,11 @@ public class WebSocketOpenTest extends WebSocketTester @Override public void onOpen(CoreSession coreSession, Callback callback) { - LOG.info("onOpen {}", coreSession); - synchronized (this) - { - this.coreSession = coreSession; - } + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onOpen {}", name, coreSession); + this.coreSession = coreSession; onOpen.apply(coreSession, callback); - } - - @Override - public void onFrame(Frame frame, Callback callback) - { - LOG.info("onFrame: " + BufferUtil.toDetailString(frame.getPayload())); - callback.succeeded(); - if (onFrame.getCount() == 1) - { - this.frame = frame; - onFrame.countDown(); - } - } - - @Override - public void onError(Throwable cause) - { - LOG.info("onError {} ", cause == null ? null : cause.toString()); - if (onError.getCount() != 1) - throw new IllegalStateException(); - error = cause; - onError.countDown(); - } - - @Override - public void onClosed(CloseStatus closeStatus) - { - LOG.info("onClosed {}", closeStatus); - if (onClosed.getCount() != 1) - throw new IllegalStateException(); - this.closeStatus = closeStatus; - onClosed.countDown(); + openLatch.countDown(); } @Override @@ -262,29 +212,5 @@ public class WebSocketOpenTest extends WebSocketTester { return true; } - - public void sendText(String text) - { - sendText(coreSession, text); - } - - public void sendText(String text, Callback callback) - { - sendText(coreSession, text, callback); - } - - static void sendText(FrameHandler.CoreSession coreSession, String text) - { - sendText(coreSession, text, NOOP); - } - - static void sendText(FrameHandler.CoreSession coreSession, String text, Callback callback) - { - Frame frame = new Frame(OpCode.TEXT); - frame.setFin(true); - frame.setPayload(text); - - coreSession.sendFrame(frame, callback, false); - } } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java index 478a57fb013..a76cd1057bb 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -26,15 +26,12 @@ import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.server.Negotiation; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler; public class WebSocketServer { - private static Logger LOG = Log.getLogger(WebSocketServer.class); private final Server server; private URI serverUri; @@ -59,12 +56,12 @@ public class WebSocketServer return server; } - public WebSocketServer(FrameHandler frameHandler) throws Exception + public WebSocketServer(FrameHandler frameHandler) { this(new DefaultNegotiator(frameHandler)); } - public WebSocketServer(WebSocketNegotiator negotiator) throws Exception + public WebSocketServer(WebSocketNegotiator negotiator) { server = new Server(); ServerConnector connector = new ServerConnector(server); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketTester.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketTester.java index 7be82f0db0c..d54fa0938e5 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketTester.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketTester.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core; @@ -47,6 +47,7 @@ public class WebSocketTester private static String NON_RANDOM_KEY = Base64.getEncoder().encodeToString("0123456701234567".getBytes()); private static SslContextFactory.Client sslContextFactory; protected ByteBufferPool bufferPool; + protected ByteBuffer buffer; protected Parser parser; @BeforeAll @@ -159,33 +160,34 @@ public class WebSocketTester protected Parser.ParsedFrame receiveFrame(InputStream in) throws IOException { - ByteBuffer buffer = bufferPool.acquire(4096, false); + if (buffer == null) + buffer = bufferPool.acquire(4096, false); + while (true) { + Parser.ParsedFrame frame = parser.parse(buffer); + if (!buffer.hasRemaining()) + BufferUtil.clear(buffer); + if (frame != null) + return frame; + int p = BufferUtil.flipToFill(buffer); int len = in.read(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); if (len < 0) return null; buffer.position(buffer.position() + len); BufferUtil.flipToFlush(buffer, p); - - Parser.ParsedFrame frame = parser.parse(buffer); - if (frame != null) - return frame; } } protected void receiveEof(InputStream in) throws IOException { ByteBuffer buffer = bufferPool.acquire(4096, false); - while (true) - { - BufferUtil.flipToFill(buffer); - int len = in.read(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); - if (len < 0) - return; + BufferUtil.clearToFill(buffer); + int len = in.read(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); + if (len < 0) + return; - throw new IllegalStateException("unexpected content"); - } + throw new IllegalStateException("unexpected content"); } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnFrameHandler.java index c4adf5d00d4..a28aa155d13 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnFrameHandler.java @@ -1,20 +1,20 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// package org.eclipse.jetty.websocket.core.autobahn; @@ -22,8 +22,8 @@ import java.nio.ByteBuffer; import java.time.Duration; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.TestMessageHandler; -import org.eclipse.jetty.websocket.core.WebSocketConstants; public class AutobahnFrameHandler extends TestMessageHandler { @@ -33,7 +33,6 @@ public class AutobahnFrameHandler extends TestMessageHandler coreSession.setIdleTimeout(Duration.ofSeconds(5)); coreSession.setMaxTextMessageSize(Integer.MAX_VALUE); coreSession.setMaxBinaryMessageSize(Integer.MAX_VALUE); - coreSession.setMaxFrameSize(WebSocketConstants.DEFAULT_MAX_FRAME_SIZE * 2); super.onOpen(coreSession, callback); } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnWebSocketClient.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnClient.java similarity index 78% rename from jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnWebSocketClient.java rename to jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnClient.java index 62291bb8684..79252a0c1a3 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnWebSocketClient.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.autobahn; @@ -27,11 +27,11 @@ import java.util.concurrent.TimeoutException; import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.UrlEncoded; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.TestMessageHandler; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -62,7 +62,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; * Running Autobahn Fuzzing Server (which you run this client implementation against): *

        *
        - *     # Change to websocket-core
        + *     # Change to websocket-core first
          *     $ cd jetty-websocket/websocket-core
          *     $ wstest --mode=fuzzingserver --spec=fuzzingserver.json
          *
        @@ -70,7 +70,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
          *     $ ls target/reports/clients/
          * 
        */ -public class AutobahnWebSocketClient +public class CoreAutobahnClient { public static void main(String[] args) { @@ -95,11 +95,11 @@ public class AutobahnWebSocketClient } } - AutobahnWebSocketClient client = null; + CoreAutobahnClient client = null; try { String userAgent = "JettyWebsocketClient/" + Jetty.VERSION; - client = new AutobahnWebSocketClient(hostname, port, userAgent); + client = new CoreAutobahnClient(hostname, port, userAgent); LOG.info("Running test suite..."); LOG.info("Using Fuzzing Server: {}:{}", hostname, port); @@ -137,12 +137,12 @@ public class AutobahnWebSocketClient } } - private static final Logger LOG = Log.getLogger(AutobahnWebSocketClient.class); + private static final Logger LOG = LoggerFactory.getLogger(CoreAutobahnClient.class); private URI baseWebsocketUri; private WebSocketCoreClient client; private String userAgent; - public AutobahnWebSocketClient(String hostname, int port, String userAgent) throws Exception + public CoreAutobahnClient(String hostname, int port, String userAgent) throws Exception { this.userAgent = userAgent; this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port); @@ -154,7 +154,7 @@ public class AutobahnWebSocketClient { URI wsUri = baseWebsocketUri.resolve("/getCaseCount"); TestMessageHandler onCaseCount = new TestMessageHandler(); - Future response = client.connect(onCaseCount, wsUri); + Future response = client.connect(onCaseCount, wsUri); if (waitForUpgrade(wsUri, response)) { @@ -173,7 +173,7 @@ public class AutobahnWebSocketClient LOG.info("test uri: {}", wsUri); AutobahnFrameHandler echoHandler = new AutobahnFrameHandler(); - Future response = client.connect(echoHandler, wsUri); + Future response = client.connect(echoHandler, wsUri); if (waitForUpgrade(wsUri, response)) { // Wait up to 5 min as some of the tests can take a while @@ -201,14 +201,14 @@ public class AutobahnWebSocketClient { URI wsUri = baseWebsocketUri.resolve("/updateReports?agent=" + UrlEncoded.encodeString(userAgent)); TestMessageHandler onUpdateReports = new TestMessageHandler(); - Future response = client.connect(onUpdateReports, wsUri); + Future response = client.connect(onUpdateReports, wsUri); response.get(5, TimeUnit.SECONDS); assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS)); LOG.info("Reports updated."); LOG.info("Test suite finished!"); } - private boolean waitForUpgrade(URI wsUri, Future response) throws InterruptedException + private boolean waitForUpgrade(URI wsUri, Future response) throws InterruptedException { try { diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnWebSocketServer.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnServer.java similarity index 71% rename from jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnWebSocketServer.java rename to jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnServer.java index 9f1978534d1..bbfcbd29958 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnWebSocketServer.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.autobahn; @@ -57,7 +57,7 @@ import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler; * $ ls target/reports/servers/ *
      */ -public class AutobahnWebSocketServer +public class CoreAutobahnServer { public static void main(String[] args) throws Exception { diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketClient.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketClient.java index f8eafa1cb6e..e5192c37dc3 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketClient.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.chat; @@ -28,15 +28,15 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.MessageHandler; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ChatWebSocketClient { - private static Logger LOG = Log.getLogger(ChatWebSocketClient.class); + private static Logger LOG = LoggerFactory.getLogger(ChatWebSocketClient.class); private URI baseWebsocketUri; private WebSocketCoreClient client; @@ -102,7 +102,7 @@ public class ChatWebSocketClient } LOG.debug("sending {}...", line); - handler.sendText(Callback.from(() -> LOG.debug("message sent"), LOG::warn), false, name, ": ", line); + handler.sendText(Callback.from(() -> LOG.debug("message sent"), (cause) -> LOG.warn("message send failure", cause)), false, name, ": ", line); } public static void main(String[] args) diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java index 8b9e87911c0..493946f2183 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.chat; @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -34,9 +33,8 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.MessageHandler; import org.eclipse.jetty.websocket.core.server.Negotiation; @@ -47,8 +45,6 @@ import static org.eclipse.jetty.util.Callback.NOOP; public class ChatWebSocketServer { - private static Logger LOG = Log.getLogger(ChatWebSocketServer.class); - private Set members = new HashSet<>(); private FrameHandler negotiate(Negotiation negotiation) @@ -77,7 +73,7 @@ public class ChatWebSocketServer { members.add(this); callback.succeeded(); - }, x -> callback.failed(x))); + }, callback::failed)); } @Override diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java index 36d460f3d06..8a4260cad67 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.client; @@ -24,10 +24,8 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler.CoreSession; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.TestFrameHandler; import org.eclipse.jetty.websocket.core.WebSocketServer; @@ -35,6 +33,8 @@ import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -45,7 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class WebSocketClientServerTest { - private static Logger LOG = Log.getLogger(WebSocketClientServerTest.class); + private static Logger LOG = LoggerFactory.getLogger(WebSocketClientServerTest.class); private WebSocketServer server; private TestFrameHandler serverHandler; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/AbstractExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/AbstractExtensionTest.java index 9ae85a0e924..754f49134d0 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/AbstractExtensionTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/AbstractExtensionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/DeflateFrameExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/DeflateFrameExtensionTest.java deleted file mode 100644 index 0d7476a78f6..00000000000 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/DeflateFrameExtensionTest.java +++ /dev/null @@ -1,423 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.core.extensions; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.zip.Deflater; -import java.util.zip.Inflater; - -import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.toolchain.test.ByteBufferAssert; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.Behavior; -import org.eclipse.jetty.websocket.core.CapturedHexPayloads; -import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.IncomingFramesCapture; -import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.OutgoingNetworkBytesCapture; -import org.eclipse.jetty.websocket.core.TestMessageHandler; -import org.eclipse.jetty.websocket.core.internal.ExtensionStack; -import org.eclipse.jetty.websocket.core.internal.Generator; -import org.eclipse.jetty.websocket.core.internal.Negotiated; -import org.eclipse.jetty.websocket.core.internal.Parser; -import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; -import org.eclipse.jetty.websocket.core.internal.compress.DeflateFrameExtension; -import org.junit.jupiter.api.Test; - -import static org.eclipse.jetty.websocket.core.OpCode.TEXT; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -public class DeflateFrameExtensionTest extends AbstractExtensionTest -{ - private static final Logger LOG = Log.getLogger(DeflateFrameExtensionTest.class); - - private void assertIncoming(byte[] raw, String... expectedTextDatas) - { - DeflateFrameExtension ext = new DeflateFrameExtension(); - init(ext); - - // Setup capture of incoming frames - IncomingFramesCapture capture = new IncomingFramesCapture(); - - // Wire up stack - ext.setNextIncomingFrames(capture); - - Parser parser = new Parser(components.getBufferPool()); - ByteBuffer buffer = ByteBuffer.wrap(raw); - while (BufferUtil.hasContent(buffer)) - { - Frame frame = parser.parse(buffer); - if (frame == null) - break; - ext.onFrame(frame, Callback.NOOP); - } - - int len = expectedTextDatas.length; - assertThat("Incoming Frame Count", capture.frames.size(), is(len)); - - int i = 0; - for (Frame actual : capture.frames) - { - String prefix = "Frame[" + i + "]"; - assertThat(prefix + ".opcode", actual.getOpCode(), is(OpCode.TEXT)); - assertThat(prefix + ".fin", actual.isFin(), is(true)); - assertThat(prefix + ".rsv1", actual.isRsv1(), is(false)); // RSV1 should be unset at this point - assertThat(prefix + ".rsv2", actual.isRsv2(), is(false)); - assertThat(prefix + ".rsv3", actual.isRsv3(), is(false)); - - ByteBuffer expected = BufferUtil.toBuffer(expectedTextDatas[i], StandardCharsets.UTF_8); - assertThat(prefix + ".payloadLength", actual.getPayloadLength(), is(expected.remaining())); - ByteBufferAssert.assertEquals(prefix + ".payload", expected, actual.getPayload().slice()); - i++; - } - } - - private void assertOutgoing(String text, String expectedHex) throws IOException - { - DeflateFrameExtension ext = new DeflateFrameExtension(); - init(ext); - - Generator generator = new Generator(components.getBufferPool()); - - OutgoingNetworkBytesCapture capture = new OutgoingNetworkBytesCapture(generator); - ext.setNextOutgoingFrames(capture); - - Frame frame = new Frame(OpCode.TEXT).setPayload(text); - ext.sendFrame(frame, null, false); - - capture.assertBytes(0, expectedHex); - } - - @Test - public void testJettyWebSocketClient_HelloThere() - { - ExtensionTool.Tester tester = serverExtensions.newTester("deflate-frame"); - - tester.assertNegotiated("deflate-frame"); - - tester.parseIncomingHex(// Captured from Jetty WebSocketClient - "Hello" then "There" via unit test - "c18700000000f248cdc9c90700", // "Hello" - "c187000000000ac9482d4a0500" // "There" - ); - - tester.assertHasFrames("Hello", "There"); - } - - @Test - public void testChrome20_Hello() - { - ExtensionTool.Tester tester = serverExtensions.newTester("deflate-frame"); - - tester.assertNegotiated("deflate-frame"); - - tester.parseIncomingHex(// Captured from Chrome 20.x - "Hello" (sent from browser) - "c187832b5c11716391d84a2c5c" // "Hello" - ); - - tester.assertHasFrames("Hello"); - } - - @Test - public void testChrome20_HelloThere() - { - ExtensionTool.Tester tester = serverExtensions.newTester("deflate-frame"); - - tester.assertNegotiated("deflate-frame"); - - tester.parseIncomingHex(// Captured from Chrome 20.x - "Hello" then "There" (sent from browser) - "c1877b1971db8951bc12b21e71", // "Hello" - "c18759edc8f4532480d913e8c8" // There - ); - - tester.assertHasFrames("Hello", "There"); - } - - @Test - public void testChrome20_Info() - { - ExtensionTool.Tester tester = serverExtensions.newTester("deflate-frame"); - - tester.assertNegotiated("deflate-frame"); - - tester.parseIncomingHex(// Captured from Chrome 20.x - "info:" (sent from browser) - "c187ca4def7f0081a4b47d4fef" // example payload - ); - - tester.assertHasFrames("info:"); - } - - @Test - public void testChrome20_TimeTime() - { - ExtensionTool.Tester tester = serverExtensions.newTester("deflate-frame"); - - tester.assertNegotiated("deflate-frame"); - - tester.parseIncomingHex(// Captured from Chrome 20.x - "time:" then "time:" once more (sent from browser) - "c18782467424a88fb869374474", // "time:" - "c1853cfda17f16fcb07f3c" // "time:" - ); - - tester.assertHasFrames("time:", "time:"); - } - - @Test - public void testPyWebSocket_TimeTimeTime() - { - ExtensionTool.Tester tester = serverExtensions.newTester("deflate-frame"); - - tester.assertNegotiated("deflate-frame"); - - tester.parseIncomingHex(// Captured from Pywebsocket (r781) - "time:" sent 3 times. - "c1876b100104" + "41d9cd49de1201", // "time:" - "c1852ae3ff01" + "00e2ee012a", // "time:" - "c18435558caa" + "37468caa" // "time:" - ); - - tester.assertHasFrames("time:", "time:", "time:"); - } - - @Test - public void testCompress_TimeTimeTime() - { - // What pywebsocket produces for "time:", "time:", "time:" - String[] expected = new String[] - {"2AC9CC4DB50200", "2A01110000", "02130000"}; - - // Lets see what we produce - CapturedHexPayloads capture = new CapturedHexPayloads(); - DeflateFrameExtension ext = new DeflateFrameExtension(); - init(ext); - ext.setNextOutgoingFrames(capture); - - ext.sendFrame(new Frame(TEXT).setPayload("time:"), null, false); - ext.sendFrame(new Frame(TEXT).setPayload("time:"), null, false); - ext.sendFrame(new Frame(TEXT).setPayload("time:"), null, false); - - List actual = capture.getCaptured(); - - assertThat("Compressed Payloads", actual, contains(expected)); - } - - private void init(DeflateFrameExtension ext) - { - ext.setWebSocketCoreSession(sessionWithMaxMessageSize(20 * 1024 * 1024)); - ext.init(new ExtensionConfig(ext.getName()), components); - } - - @Test - public void testDeflateBasics() throws Exception - { - // Setup deflater basics - Deflater compressor = new Deflater(Deflater.BEST_COMPRESSION, true); - compressor.setStrategy(Deflater.DEFAULT_STRATEGY); - - // Text to compress - String text = "info:"; - byte[] uncompressed = StringUtil.getUtf8Bytes(text); - - // Prime the compressor - compressor.reset(); - compressor.setInput(uncompressed, 0, uncompressed.length); - compressor.finish(); - - // Perform compression - ByteBuffer outbuf = ByteBuffer.allocate(64); - BufferUtil.clearToFill(outbuf); - - while (!compressor.finished()) - { - byte[] out = new byte[64]; - int len = compressor.deflate(out, 0, out.length, Deflater.SYNC_FLUSH); - if (len > 0) - { - outbuf.put(out, 0, len); - } - } - compressor.end(); - - BufferUtil.flipToFlush(outbuf, 0); - byte[] compressed = BufferUtil.toArray(outbuf); - // Clear the BFINAL bit that has been set by the compressor.end() call. - // In the real implementation we never end() the compressor. - compressed[0] &= 0xFE; - - String actual = TypeUtil.toHexString(compressed); - String expected = "CaCc4bCbB70200"; // what pywebsocket produces - - assertThat("Compressed data", actual, is(expected)); - } - - @Test - public void testGeneratedTwoFrames() throws IOException - { - DeflateFrameExtension ext = new DeflateFrameExtension(); - init(ext); - - Generator generator = new Generator(components.getBufferPool()); - - OutgoingNetworkBytesCapture capture = new OutgoingNetworkBytesCapture(generator); - ext.setNextOutgoingFrames(capture); - - ext.sendFrame(new Frame(TEXT).setPayload("Hello"), null, false); - ext.sendFrame(new Frame(TEXT).setPayload("There"), null, false); - - capture.assertBytes(0, "c107f248cdc9c90700"); - } - - @Test - public void testInflateBasics() throws Exception - { - // should result in "info:" text if properly inflated - byte[] rawbuf = TypeUtil.fromHexString("CaCc4bCbB70200"); // what pywebsocket produces - // byte[] rawbuf = TypeUtil.fromHexString("CbCc4bCbB70200"); // what java produces - - Inflater inflater = new Inflater(true); - inflater.reset(); - inflater.setInput(rawbuf, 0, rawbuf.length); - - byte[] outbuf = new byte[64]; - int len = inflater.inflate(outbuf); - inflater.end(); - assertThat("Inflated length", len, greaterThan(4)); - - String actual = StringUtil.toUTF8String(outbuf, 0, len); - assertThat("Inflated text", actual, is("info:")); - } - - @Test - public void testPyWebSocketServer_Hello() - { - // Captured from PyWebSocket - "Hello" (echo from server) - byte[] rawbuf = TypeUtil.fromHexString("c107f248cdc9c90700"); - assertIncoming(rawbuf, "Hello"); - } - - @Test - public void testPyWebSocketServer_Long() - { - // Captured from PyWebSocket - Long Text (echo from server) - byte[] rawbuf = TypeUtil.fromHexString("c1421cca410a80300c44d1abccce9df7" + "f018298634d05631138ab7b7b8fdef1f" + "dc0282e2061d575a45f6f2686bab25e1" - + "3fb7296fa02b5885eb3b0379c394f461" + "98cafd03"); - assertIncoming(rawbuf, "It's a big enough umbrella but it's always me that ends up getting wet."); - } - - @Test - public void testPyWebSocketServer_Medium() - { - // Captured from PyWebSocket - "stackoverflow" (echo from server) - byte[] rawbuf = TypeUtil.fromHexString("c10f2a2e494ccece2f4b2d4acbc92f0700"); - assertIncoming(rawbuf, "stackoverflow"); - } - - /** - * Make sure that the server generated compressed form for "Hello" is consistent with what PyWebSocket creates. - * - * @throws IOException on test failure - */ - @Test - public void testServerGeneratedHello() throws IOException - { - assertOutgoing("Hello", "c107f248cdc9c90700"); - } - - /** - * Make sure that the server generated compressed form for "There" is consistent with what PyWebSocket creates. - * - * @throws IOException on test failure - */ - @Test - public void testServerGeneratedThere() throws IOException - { - assertOutgoing("There", "c1070ac9482d4a0500"); - } - - @Test - public void testCompressAndDecompressBigPayload() throws Exception - { - byte[] input = new byte[1024 * 1024]; - // Make them not compressible. - new Random().nextBytes(input); - - int maxMessageSize = (1024 * 1024) + 8192; - - DeflateFrameExtension clientExtension = new DeflateFrameExtension(); - init(clientExtension); - clientExtension.setWebSocketCoreSession(sessionWithMaxMessageSize(maxMessageSize)); - - final DeflateFrameExtension serverExtension = new DeflateFrameExtension(); - init(serverExtension); - serverExtension.setWebSocketCoreSession(sessionWithMaxMessageSize(maxMessageSize)); - - // Chain the next element to decompress. - clientExtension.setNextOutgoingFrames((frame, callback, batch) -> - { - LOG.debug("outgoingFrame({})", frame); - serverExtension.onFrame(frame, callback); - callback.succeeded(); - }); - - final ByteArrayOutputStream result = new ByteArrayOutputStream(input.length); - serverExtension.setNextIncomingFrames((frame, callback) -> - { - LOG.debug("incomingFrame({})", frame); - try - { - result.write(BufferUtil.toArray(frame.getPayload())); - } - catch (IOException x) - { - throw new RuntimeIOException(x); - } - }); - - Frame frame = new Frame(OpCode.BINARY); - frame.setPayload(input); - frame.setFin(true); - clientExtension.sendFrame(frame, null, false); - - assertArrayEquals(input, result.toByteArray()); - } - - private WebSocketCoreSession sessionWithMaxMessageSize(int maxMessageSize) - { - ExtensionStack exStack = new ExtensionStack(components, Behavior.SERVER); - exStack.negotiate(new LinkedList<>(), new LinkedList<>()); - - WebSocketCoreSession coreSession = new WebSocketCoreSession(new TestMessageHandler(), Behavior.SERVER, Negotiated.from(exStack)); - coreSession.setMaxFrameSize(maxMessageSize); - return coreSession; - } -} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java index 20bbac1a2f3..ce44f4e962b 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; @@ -26,8 +26,10 @@ import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; public class ExtensionConfigTest { @@ -108,7 +110,7 @@ public class ExtensionConfigTest } @Test - public void testParseSimple_BasicParameters() + public void testParseSimpleBasicParameters() { ExtensionConfig cfg = ExtensionConfig.parse("bar; baz=2"); Map expectedParams = new HashMap<>(); @@ -117,7 +119,7 @@ public class ExtensionConfigTest } @Test - public void testParseSimple_NoParameters() + public void testParseSimpleNoParameters() { ExtensionConfig cfg = ExtensionConfig.parse("foo"); Map expectedParams = new HashMap<>(); @@ -125,7 +127,7 @@ public class ExtensionConfigTest } @Test - public void testParseList_Simple() + public void testParseListSimple() { String[] rawHeaders = new String[]{ "permessage-compress; client_max_window_bits", @@ -145,7 +147,7 @@ public class ExtensionConfigTest * where they include multiple extensions in 1 header. */ @Test - public void testParseList_Unsplit() + public void testParseListUnsplit() { String[] rawHeaders = new String[]{ "permessage-compress; client_max_window_bits, identity", @@ -158,4 +160,28 @@ public class ExtensionConfigTest assertThat("Configs[1]", configs.get(1).getName(), is("identity")); assertThat("Configs[2]", configs.get(2).getName(), is("capture")); } + + @Test + public void testParseNoExtensions() + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> ExtensionConfig.parse("=params")); + assertThat(error.getMessage(), containsString("contains no ExtensionConfigs")); + } + + @Test + public void testParseMultipleExtensions() + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> ExtensionConfig.parse("ext1;param1, ext2;param2")); + assertThat(error.getMessage(), containsString("contains multiple ExtensionConfigs")); + } + + @Test + public void testParseMultipleExtensionsSameName() + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> ExtensionConfig.parse("ext1;paramOption1, ext1;paramOption2")); + assertThat(error.getMessage(), containsString("contains multiple ExtensionConfigs")); + } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java index e50008ec0a3..2039144db03 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; @@ -21,8 +21,6 @@ package org.eclipse.jetty.websocket.core.extensions; import java.util.ArrayList; import java.util.List; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Extension; import org.eclipse.jetty.websocket.core.ExtensionConfig; @@ -35,6 +33,8 @@ import org.eclipse.jetty.websocket.core.internal.ExtensionStack; import org.eclipse.jetty.websocket.core.internal.IdentityExtension; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -42,7 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class ExtensionStackTest { - private static final Logger LOG = Log.getLogger(ExtensionStackTest.class); + private static final Logger LOG = LoggerFactory.getLogger(ExtensionStackTest.class); private static ExtensionStack stack; @BeforeAll diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionTool.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionTool.java index 2fbbc0cd998..c8d080b0a13 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionTool.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionTool.java @@ -1,31 +1,32 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; import java.nio.ByteBuffer; import java.util.LinkedList; +import java.util.concurrent.ExecutionException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.ByteBufferAssert; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Extension; @@ -76,7 +77,7 @@ public class ExtensionTool { this.ext = components.getExtensionRegistry().newInstance(extConfig, components); this.ext.setNextIncomingFrames(capture); - this.ext.setWebSocketCoreSession(newWebSocketCoreSession()); + this.ext.setCoreSession(newWebSocketCoreSession()); } public void parseIncomingHex(String... rawhex) @@ -95,9 +96,23 @@ public class ExtensionTool Frame frame = parser.parse(buffer); if (frame == null) break; - ext.onFrame(frame, Callback.from(() -> + + FutureCallback callback = new FutureCallback(); + ext.onFrame(frame, callback); + + // Throw if callback fails. + try { - }, Assertions::fail)); + callback.get(); + } + catch (ExecutionException e) + { + throw new RuntimeException(e.getCause()); + } + catch (Throwable t) + { + Assertions.fail(t); + } } } } @@ -151,7 +166,7 @@ public class ExtensionTool { ExtensionStack exStack = new ExtensionStack(components, Behavior.SERVER); exStack.negotiate(new LinkedList<>(), new LinkedList<>()); - WebSocketCoreSession coreSession = new WebSocketCoreSession(new TestMessageHandler(), Behavior.SERVER, Negotiated.from(exStack)); + WebSocketCoreSession coreSession = new WebSocketCoreSession(new TestMessageHandler(), Behavior.SERVER, Negotiated.from(exStack), components); return coreSession; } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/FragmentExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/FragmentExtensionTest.java index 3f0ed25ba42..c796d7e260a 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/FragmentExtensionTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/FragmentExtensionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/IdentityExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/IdentityExtensionTest.java index 3483622face..6e78dd862ad 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/IdentityExtensionTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/IdentityExtensionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflateExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflateExtensionTest.java index e9e0e499368..50c814d6a1c 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflateExtensionTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflateExtensionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; @@ -22,6 +22,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -29,14 +30,19 @@ import org.eclipse.jetty.toolchain.test.ByteBufferAssert; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.websocket.core.Behavior; +import org.eclipse.jetty.websocket.core.Configuration.ConfigurationCustomizer; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.IncomingFramesCapture; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.OutgoingFramesCapture; -import org.eclipse.jetty.websocket.core.ProtocolException; -import org.eclipse.jetty.websocket.core.internal.compress.CompressExtension; -import org.eclipse.jetty.websocket.core.internal.compress.PerMessageDeflateExtension; +import org.eclipse.jetty.websocket.core.TestMessageHandler; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.internal.ExtensionStack; +import org.eclipse.jetty.websocket.core.internal.Negotiated; +import org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -59,7 +65,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest private void assertEndsWithTail(String hexStr, boolean expectedResult) { ByteBuffer buf = ByteBuffer.wrap(TypeUtil.fromHexString(hexStr)); - assertThat("endsWithTail([" + hexStr + "])", CompressExtension.endsWithTail(buf), is(expectedResult)); + assertThat("endsWithTail([" + hexStr + "])", PerMessageDeflateExtension.endsWithTail(buf), is(expectedResult)); } @Test @@ -79,7 +85,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.1: A message compressed using 1 compressed DEFLATE block */ @Test - public void testDraft21_Hello_UnCompressedBlock() + public void testDraft21HelloUnCompressedBlock() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -100,7 +106,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.1: A message compressed using 1 compressed DEFLATE block (with fragmentation) */ @Test - public void testDraft21_Hello_UnCompressedBlock_Fragmented() + public void testDraft21HelloUnCompressedBlockFragmented() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -123,13 +129,13 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.2: Sharing LZ77 Sliding Window */ @Test - public void testDraft21_SharingL77SlidingWindow_ContextTakeover() + public void testDraft21SharingL77SlidingWindowContextTakeover() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); tester.assertNegotiated("permessage-deflate"); - tester.parseIncomingHex( // context takeover (2 messages) + tester.parseIncomingHex(// context takeover (2 messages) // message 1 "0xc1 0x07", // (HEADER added for this test) "0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00", @@ -146,7 +152,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.2: Sharing LZ77 Sliding Window */ @Test - public void testDraft21_SharingL77SlidingWindow_NoContextTakeover() + public void testDraft21SharingL77SlidingWindowNoContextTakeover() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -170,7 +176,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.3: Using a DEFLATE Block with No Compression */ @Test - public void testDraft21_DeflateBlockWithNoCompression() + public void testDraft21DeflateBlockWithNoCompression() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -189,7 +195,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.4: Using a DEFLATE Block with BFINAL Set to 1 */ @Test - public void testDraft21_DeflateBlockWithBFinal1() + public void testDraft21DeflateBlockWithBFinal1() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -209,7 +215,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Section 8.2.3.5: Two DEFLATE Blocks in 1 Message */ @Test - public void testDraft21_TwoDeflateBlocksOneMessage() + public void testDraft21TwoDeflateBlocksOneMessage() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -227,7 +233,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest * Decode fragmented message (3 parts: TEXT, CONTINUATION, CONTINUATION) */ @Test - public void testParseFragmentedMessage_Good() + public void testParseFragmentedMessageGood() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -256,7 +262,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest *

      */ @Test - public void testParseFragmentedMessage_BadRsv1() + public void testParseFragmentedMessageBadRsv1() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate"); @@ -311,41 +317,6 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest ByteBufferAssert.assertEquals("Frame.payload", expected, actual.getPayload().slice()); } - /** - * Incoming Text Message fragmented into 3 pieces. - */ - @Test - public void testIncomingFragmented() - { - PerMessageDeflateExtension ext = new PerMessageDeflateExtension(); - ExtensionConfig config = ExtensionConfig.parse("permessage-deflate"); - ext.init(config, components); - - // Setup capture of incoming frames - IncomingFramesCapture capture = new IncomingFramesCapture(); - - // Wire up stack - ext.setNextIncomingFrames(capture); - - String payload = "Are you there?"; - Frame ping = new Frame(OpCode.PING).setPayload(payload); - ext.onFrame(ping, Callback.NOOP); - - capture.assertFrameCount(1); - capture.assertHasOpCount(OpCode.PING, 1); - Frame actual = capture.frames.poll(); - - assertThat("Frame.opcode", actual.getOpCode(), is(OpCode.PING)); - assertThat("Frame.fin", actual.isFin(), is(true)); - assertThat("Frame.rsv1", actual.isRsv1(), is(false)); - assertThat("Frame.rsv2", actual.isRsv2(), is(false)); - assertThat("Frame.rsv3", actual.isRsv3(), is(false)); - - ByteBuffer expected = BufferUtil.toBuffer(payload, StandardCharsets.UTF_8); - assertThat("Frame.payloadLength", actual.getPayloadLength(), is(expected.remaining())); - ByteBufferAssert.assertEquals("Frame.payload", expected, actual.getPayload().slice()); - } - /** * Verify that incoming uncompressed frames are properly passed through */ @@ -399,6 +370,37 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest } } + @Test + public void testIncomingFrameNoPayload() + { + PerMessageDeflateExtension ext = new PerMessageDeflateExtension(); + ExtensionConfig config = ExtensionConfig.parse("permessage-deflate"); + ext.init(config, components); + ext.setCoreSession(newSession()); + + // Setup capture of incoming frames + IncomingFramesCapture capture = new IncomingFramesCapture(); + + // Wire up stack + ext.setNextIncomingFrames(capture); + + Frame ping = new Frame(OpCode.TEXT); + ping.setRsv1(true); + ext.onFrame(ping, Callback.NOOP); + + capture.assertFrameCount(1); + Frame actual = capture.frames.poll(); + + assertThat("Frame.opcode", actual.getOpCode(), is(OpCode.TEXT)); + assertThat("Frame.fin", actual.isFin(), is(true)); + assertThat("Frame.rsv1", actual.isRsv1(), is(false)); + assertThat("Frame.rsv2", actual.isRsv2(), is(false)); + assertThat("Frame.rsv3", actual.isRsv3(), is(false)); + + assertThat("Frame.payloadLength", actual.getPayloadLength(), is(0)); + assertThat("Frame.payload", actual.getPayload(), is(BufferUtil.EMPTY_BUFFER)); + } + /** * Outgoing PING (Control Frame) should pass through extension unmodified * @@ -448,6 +450,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest { PerMessageDeflateExtension ext = new PerMessageDeflateExtension(); ext.init(ExtensionConfig.parse("permessage-deflate"), components); + ext.setCoreSession(newSession()); // Setup capture of outgoing frames OutgoingFramesCapture capture = new OutgoingFramesCapture(); @@ -489,7 +492,37 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest } @Test - public void testPyWebSocket_Client_NoContextTakeover_ThreeOra() + public void testOutgoingFrameNoPayload() + { + PerMessageDeflateExtension ext = new PerMessageDeflateExtension(); + ExtensionConfig config = ExtensionConfig.parse("permessage-deflate"); + ext.init(config, components); + ext.setCoreSession(newSession()); + + // Setup capture of incoming frames + OutgoingFramesCapture capture = new OutgoingFramesCapture(); + + // Wire up stack + ext.setNextOutgoingFrames(capture); + + Frame frame = new Frame(OpCode.TEXT); + ext.sendFrame(frame, Callback.NOOP, false); + + capture.assertFrameCount(1); + Frame actual = capture.frames.poll(); + + assertThat("Frame.opcode", actual.getOpCode(), is(OpCode.TEXT)); + assertThat("Frame.fin", actual.isFin(), is(true)); + assertThat("Frame.rsv1", actual.isRsv1(), is(true)); + assertThat("Frame.rsv2", actual.isRsv2(), is(false)); + assertThat("Frame.rsv3", actual.isRsv3(), is(false)); + + assertThat("Frame.payloadLength", actual.getPayloadLength(), is(1)); + //assertThat("Frame.payload", actual.getPayload(), is(BufferUtil.EMPTY_BUFFER)); + } + + @Test + public void testPyWebSocketClientNoContextTakeoverThreeOra() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate; client_max_window_bits; client_no_context_takeover"); @@ -497,7 +530,8 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest // Captured from Pywebsocket (r790) - 3 messages with similar parts. - tester.parseIncomingHex( // context takeover (3 messages) + tester.parseIncomingHex( + // context takeover (3 messages) "c1 09 0a c9 2f 4a 0c 01 62 00 00", // ToraTora "c1 0b 72 2c c9 2f 4a 74 cb 01 12 00 00", // AtoraFlora "c1 0b 0a c8 c8 c9 2f 4a 0c 01 62 00 00" // PhloraTora @@ -507,7 +541,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest } @Test - public void testPyWebSocket_Client_ToraToraTora() + public void testPyWebSocketClientToraToraTora() { ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate; client_max_window_bits"); @@ -515,7 +549,8 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest // Captured from Pywebsocket (r790) - "tora" sent 3 times. - tester.parseIncomingHex( // context takeover (3 messages) + tester.parseIncomingHex( + // context takeover (3 messages) "c1 06 2a c9 2f 4a 04 00", // tora 1 "c1 05 2a 01 62 00 00", // tora 2 "c1 04 02 61 00 00" // tora 3 @@ -525,7 +560,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest } @Test - public void testPyWebSocket_Server_NoContextTakeover_ThreeOra() + public void testPyWebSocketServerNoContextTakeoverThreeOra() { ExtensionTool.Tester tester = serverExtensions.newTester("permessage-deflate; client_max_window_bits; client_no_context_takeover"); @@ -533,7 +568,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest // Captured from Pywebsocket (r790) - 3 messages with similar parts. - tester.parseIncomingHex( // context takeover (3 messages) + tester.parseIncomingHex(// context takeover (3 messages) "c1 89 88 bc 1b b1 82 75 34 fb 84 bd 79 b1 88", // ToraTora "c1 8b 50 86 88 b2 22 aa 41 9d 1a f2 43 b3 42 86 88", // AtoraFlora "c1 8b e2 3e 05 53 e8 f6 cd 9a cd 74 09 52 80 3e 05" // PhloraTora @@ -543,7 +578,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest } @Test - public void testPyWebSocket_Server_ToraToraTora() + public void testPyWebSocketServerToraToraTora() { ExtensionTool.Tester tester = serverExtensions.newTester("permessage-deflate; client_max_window_bits"); @@ -551,7 +586,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest // Captured from Pywebsocket (r790) - "tora" sent 3 times. - tester.parseIncomingHex( // context takeover (3 messages) + tester.parseIncomingHex(// context takeover (3 messages) "c1 86 69 39 fe 91 43 f0 d1 db 6d 39", // tora 1 "c1 85 2d f3 eb 96 07 f2 89 96 2d", // tora 2 "c1 84 53 ad a5 34 51 cc a5 34" // tora 3 @@ -559,4 +594,19 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest tester.assertHasFrames("tora", "tora", "tora"); } + + private WebSocketCoreSession newSession() + { + return newSessionFromConfig(new ConfigurationCustomizer()); + } + + private WebSocketCoreSession newSessionFromConfig(ConfigurationCustomizer configuration) + { + ExtensionStack exStack = new ExtensionStack(components, Behavior.SERVER); + exStack.negotiate(new LinkedList<>(), new LinkedList<>()); + + WebSocketCoreSession coreSession = new WebSocketCoreSession(new TestMessageHandler(), Behavior.SERVER, Negotiated.from(exStack), components); + configuration.customize(configuration); + return coreSession; + } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflaterBufferSizeTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflaterBufferSizeTest.java new file mode 100644 index 00000000000..8d3a40bae68 --- /dev/null +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflaterBufferSizeTest.java @@ -0,0 +1,318 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.core.extensions; + +import java.io.IOException; +import java.net.URI; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.ExtensionConfig; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.TestFrameHandler; +import org.eclipse.jetty.websocket.core.WebSocketServer; +import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; +import org.eclipse.jetty.websocket.core.client.UpgradeListener; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.core.server.Negotiation; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class PerMessageDeflaterBufferSizeTest +{ + private WebSocketServer server; + private TestFrameHandler serverHandler = new TestFrameHandler(); + private TestNegotiator testNegotiator = new TestNegotiator(); + private URI serverUri; + + private WebSocketCoreClient client; + + public class TestNegotiator extends WebSocketNegotiator.AbstractNegotiator + { + int deflateBufferSize = -1; + int inflateBufferSize = -1; + + @Override + public FrameHandler negotiate(Negotiation negotiation) throws IOException + { + for (ExtensionConfig extensionConfig : negotiation.getOfferedExtensions()) + { + assertFalse(extensionConfig.getName().startsWith("@")); + } + + for (ExtensionConfig extensionConfig : negotiation.getNegotiatedExtensions()) + { + if ("permessage-deflate".equals(extensionConfig.getName())) + { + if (deflateBufferSize != -1) + extensionConfig.setParameter("@deflate_buffer_size", deflateBufferSize); + if (inflateBufferSize != -1) + extensionConfig.setParameter("@inflate_buffer_size", inflateBufferSize); + } + } + + return serverHandler; + } + } + + @BeforeEach + public void setup() throws Exception + { + server = new WebSocketServer(testNegotiator); + server.start(); + serverUri = new URI("ws://localhost:" + server.getLocalPort()); + + client = new WebSocketCoreClient(); + client.start(); + } + + @Test + public void testClientDeflateBufferSize() throws Exception + { + int deflateBufferSize = 6; + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate; @deflate_buffer_size=" + deflateBufferSize); + + CompletableFuture futureRequestHeaders = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeRequest(HttpRequest request) + { + futureRequestHeaders.complete(request.getHeaders()); + } + }); + + // Connect to the server. + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Make sure the internal parameter was not sent to the server. + HttpFields requestHeaders = futureRequestHeaders.get(); + assertThat(requestHeaders.getFields(HttpHeader.SEC_WEBSOCKET_EXTENSIONS).size(), is(1)); + assertThat(requestHeaders.get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS), is("permessage-deflate")); + + // We should now only be able to send this message in multiple frames as it exceeds deflate_buffer_size. + String message = "0123456789"; + clientHandler.sendText(message); + + // Verify the frame has been fragmented into multiple parts. + int numFrames = 0; + StringBuilder receivedMessage = new StringBuilder(); + while (true) + { + Frame frame = Objects.requireNonNull(serverHandler.getFrames().poll(5, TimeUnit.SECONDS)); + receivedMessage.append(frame.getPayloadAsUTF8()); + numFrames++; + if (frame.isFin()) + break; + } + + // Check we got the message and it was split into multiple frames. + assertThat(numFrames, greaterThan(1)); + assertThat(receivedMessage.toString(), Matchers.equalTo(message)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(serverHandler.getError()); + assertNull(clientHandler.getError()); + } + + @Test + public void testClientInflateBufferSize() throws Exception + { + int inflateBufferSize = 6; + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate; @inflate_buffer_size=" + inflateBufferSize); + + CompletableFuture futureRequestHeaders = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeRequest(HttpRequest request) + { + futureRequestHeaders.complete(request.getHeaders()); + } + }); + + // Connect to the server. + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Make sure the internal parameter was not sent to the server. + HttpFields requestHeaders = futureRequestHeaders.get(); + assertThat(requestHeaders.getFields(HttpHeader.SEC_WEBSOCKET_EXTENSIONS).size(), is(1)); + assertThat(requestHeaders.get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS), is("permessage-deflate")); + + // We should now only be able to send this message in multiple frames as it exceeds deflate_buffer_size. + String message = "0123456789"; + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.sendText(message); + + // Verify the frame has been fragmented into multiple parts. + int numFrames = 0; + StringBuilder receivedMessage = new StringBuilder(); + while (true) + { + Frame frame = Objects.requireNonNull(clientHandler.getFrames().poll(5, TimeUnit.SECONDS)); + receivedMessage.append(frame.getPayloadAsUTF8()); + numFrames++; + if (frame.isFin()) + break; + } + + // Check we got the message and it was split into multiple frames. + assertThat(numFrames, greaterThan(1)); + assertThat(receivedMessage.toString(), Matchers.equalTo(message)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(serverHandler.getError()); + assertNull(clientHandler.getError()); + } + + @Test + public void testServerDeflateBufferSize() throws Exception + { + testNegotiator.deflateBufferSize = 6; + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate"); + + CompletableFuture futureResponseHeaders = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + futureResponseHeaders.complete(request.getHeaders()); + } + }); + + // Connect to the server. + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Make sure the internal parameter was not sent from the server. + HttpFields responseHeaders = futureResponseHeaders.get(); + assertThat(responseHeaders.getFields(HttpHeader.SEC_WEBSOCKET_EXTENSIONS).size(), is(1)); + assertThat(responseHeaders.get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS), is("permessage-deflate")); + + // We should now only be able to send this message in multiple frames as it exceeds deflate_buffer_size. + String message = "0123456789"; + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.sendText(message); + + // Verify the frame has been fragmented into multiple parts. + int numFrames = 0; + StringBuilder receivedMessage = new StringBuilder(); + while (true) + { + Frame frame = Objects.requireNonNull(clientHandler.getFrames().poll(5, TimeUnit.SECONDS)); + receivedMessage.append(frame.getPayloadAsUTF8()); + numFrames++; + if (frame.isFin()) + break; + } + + // Check we got the message and it was split into multiple frames. + assertThat(numFrames, greaterThan(1)); + assertThat(receivedMessage.toString(), Matchers.equalTo(message)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(serverHandler.getError()); + assertNull(clientHandler.getError()); + } + + @Test + public void testServerInflateBufferSize() throws Exception + { + testNegotiator.inflateBufferSize = 6; + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, serverUri, clientHandler); + upgradeRequest.addExtensions("permessage-deflate"); + + CompletableFuture futureResponseHeaders = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + futureResponseHeaders.complete(request.getHeaders()); + } + }); + + // Connect to the server. + CompletableFuture connect = client.connect(upgradeRequest); + connect.get(5, TimeUnit.SECONDS); + + // Make sure the internal parameter was not sent from the server. + HttpFields responseHeaders = futureResponseHeaders.get(); + assertThat(responseHeaders.getFields(HttpHeader.SEC_WEBSOCKET_EXTENSIONS).size(), is(1)); + assertThat(responseHeaders.get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS), is("permessage-deflate")); + + // We should now only be able to send this message in multiple frames as it exceeds deflate_buffer_size. + String message = "0123456789"; + clientHandler.sendText(message); + + // Verify the frame has been fragmented into multiple parts. + int numFrames = 0; + StringBuilder receivedMessage = new StringBuilder(); + while (true) + { + Frame frame = Objects.requireNonNull(serverHandler.getFrames().poll(5, TimeUnit.SECONDS)); + receivedMessage.append(frame.getPayloadAsUTF8()); + numFrames++; + if (frame.isFin()) + break; + } + + // Check we got the message and it was split into multiple frames. + assertThat(numFrames, greaterThan(1)); + assertThat(receivedMessage.toString(), Matchers.equalTo(message)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(serverHandler.getError()); + assertNull(clientHandler.getError()); + } +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java index ee65299e348..50e79eacfb7 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.extensions; @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; @@ -88,7 +89,7 @@ public class ValidationExtensionTest extends WebSocketTester Frame frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); assertNotNull(frame); assertThat(frame.getOpCode(), is(OpCode.BINARY)); - assertThat(frame.getPayload().array(), is(nonUtf8Payload)); + assertThat(BufferUtil.toArray(frame.getPayload()), is(nonUtf8Payload)); //close normally client.getOutputStream().write(RawFrameBuilder.buildClose(CloseStatus.NORMAL_STATUS, true)); @@ -113,13 +114,13 @@ public class ValidationExtensionTest extends WebSocketTester Frame frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); assertNotNull(frame); assertThat(frame.getOpCode(), is(OpCode.TEXT)); - assertThat(frame.getPayload().array(), is(initialPayload)); + assertThat(BufferUtil.toArray(frame.getPayload()), is(initialPayload)); client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.CONTINUATION, continuationPayload, true)); frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); assertNotNull(frame); assertThat(frame.getOpCode(), is(OpCode.CONTINUATION)); - assertThat(frame.getPayload().array(), is(continuationPayload)); + assertThat(BufferUtil.toArray(frame.getPayload()), is(continuationPayload)); //close normally client.getOutputStream().write(RawFrameBuilder.buildClose(CloseStatus.NORMAL_STATUS, true)); @@ -144,7 +145,7 @@ public class ValidationExtensionTest extends WebSocketTester Frame frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); assertNotNull(frame); assertThat(frame.getOpCode(), is(OpCode.TEXT)); - assertThat(frame.getPayload().array(), is(initialPayload)); + assertThat(BufferUtil.toArray(frame.getPayload()), is(initialPayload)); client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.CONTINUATION, incompleteContinuationPayload, true)); frame = receiveFrame(client.getInputStream()); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java index 56379ce94a8..2e376571e18 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -35,18 +35,18 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.WebSocketConstants; -import org.eclipse.jetty.websocket.core.WebSocketWriteTimeoutException; +import org.eclipse.jetty.websocket.core.exception.WebSocketWriteTimeoutException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.MatcherAssert.assertThat; @@ -79,7 +79,7 @@ public class FrameFlusherTest @Test public void testPostCloseFrameCallbacks() throws ExecutionException, InterruptedException, TimeoutException { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); CapturingEndPoint endPoint = new CapturingEndPoint(bufferPool); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; int maxGather = 1; @@ -110,7 +110,7 @@ public class FrameFlusherTest @Test public void testLargeSmallText() throws ExecutionException, InterruptedException { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); CapturingEndPoint endPoint = new CapturingEndPoint(bufferPool); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; int maxGather = 8; @@ -161,7 +161,7 @@ public class FrameFlusherTest @Test public void testWriteTimeout() throws Exception { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); BlockingEndpoint endPoint = new BlockingEndpoint(bufferPool); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; int maxGather = 8; @@ -193,7 +193,7 @@ public class FrameFlusherTest @Test public void testErrorClose() throws Exception { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); BlockingEndpoint endPoint = new BlockingEndpoint(bufferPool); endPoint.setBlockTime(100); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; @@ -276,7 +276,7 @@ public class FrameFlusherTest public static class BlockingEndpoint extends CapturingEndPoint { - private static final Logger LOG = Log.getLogger(BlockingEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(BlockingEndpoint.class); private long blockTime = 0; public CountDownLatch closeLatch = new CountDownLatch(1); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/MockEndpoint.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/MockEndpoint.java index 76b1e6866b1..052c67e4d28 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/MockEndpoint.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/MockEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.internal; @@ -164,12 +164,6 @@ public class MockEndpoint implements EndPoint throw new UnsupportedOperationException(NOT_SUPPORTED); } - @Override - public boolean isOptimizedForDirectBuffers() - { - throw new UnsupportedOperationException(NOT_SUPPORTED); - } - @Override public void upgrade(Connection newConnection) { diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxy.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxy.java index 1d011d3daa2..5d6944e0bdc 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxy.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxy.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.proxy; @@ -26,17 +26,18 @@ import java.util.concurrent.CountDownLatch; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class WebSocketProxy { - protected static final Logger LOG = Log.getLogger(WebSocketProxy.class); + protected static final Logger LOG = LoggerFactory.getLogger(WebSocketProxy.class); enum State { @@ -188,7 +189,7 @@ class WebSocketProxy // the callback is saved until a close response comes in sendFrame from Server2Proxy // if the callback was completed here then core would send its own close response closeCallback = callback; - sendCallback = Callback.from(()->{}, callback::failed); + sendCallback = Callback.from(() -> {}, callback::failed); } break; @@ -383,7 +384,7 @@ class WebSocketProxy try { state = State.CONNECTING; - client.connect(this, serverUri).whenComplete((s,t)-> + client.connect(this, serverUri).whenComplete((s,t) -> { if (t != null) onConnectFailure(t, callback); @@ -526,7 +527,7 @@ class WebSocketProxy { state = State.ISHUT; closeCallback = callback; - sendCallback = Callback.from(()->{}, callback::failed); + sendCallback = Callback.from(() -> {}, callback::failed); } break; @@ -627,6 +628,7 @@ class WebSocketProxy state = State.FAILED; Callback doubleCallback = Callback.from(callback, closeCallback); sendCallback = Callback.from(doubleCallback, failure); + break; default: state = State.FAILED; @@ -686,4 +688,4 @@ class WebSocketProxy return "Server2Proxy:" + getState(); } } -} \ No newline at end of file +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxyTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxyTest.java index 56111ae6c25..ea7a478f93f 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxyTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxyTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.proxy; @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -37,12 +38,11 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.EchoFrameHandler; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.FrameHandler.CoreSession; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.TestAsyncFrameHandler; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; @@ -64,12 +64,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class WebSocketProxyTest { + // Port chosen to (hopefully) not conflict with existing servers on your test machine. + // So don't choose ports like 8080, 9090, 8888, etc. + private static final int PROXY_PORT = 49999; private Server _server; private WebSocketCoreClient _client; private WebSocketProxy proxy; private EchoFrameHandler serverFrameHandler; private TestHandler testHandler; - FrameHandler.ConfigurationCustomizer defaultCustomizer; + Configuration.ConfigurationCustomizer defaultCustomizer; private class TestHandler extends AbstractHandler { @@ -99,14 +102,14 @@ public class WebSocketProxyTest { _server = new Server(); ServerConnector connector = new ServerConnector(_server); - connector.setPort(8080); + connector.setPort(PROXY_PORT); _server.addConnector(connector); HandlerList handlers = new HandlerList(); testHandler = new TestHandler(); handlers.addHandler(testHandler); - defaultCustomizer = new FrameHandler.ConfigurationCustomizer(); + defaultCustomizer = new Configuration.ConfigurationCustomizer(); defaultCustomizer.setIdleTimeout(Duration.ofSeconds(3)); ContextHandler serverContext = new ContextHandler("/server"); @@ -118,7 +121,7 @@ public class WebSocketProxyTest _client = new WebSocketCoreClient(); _client.start(); - URI uri = new URI("ws://localhost:8080/server/"); + URI uri = new URI("ws://localhost:" + PROXY_PORT + "/server/"); ContextHandler proxyContext = new ContextHandler("/proxy"); proxy = new WebSocketProxy(_client, uri); @@ -158,7 +161,7 @@ public class WebSocketProxyTest WebSocketProxy.Client2Proxy proxyClientSide = proxy.client2Proxy; WebSocketProxy.Server2Proxy proxyServerSide = proxy.server2Proxy; - ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:8080/proxy/"), clientFrameHandler); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:" + PROXY_PORT + "/proxy/"), clientFrameHandler); upgradeRequest.setConfiguration(defaultCustomizer); CompletableFuture response = _client.connect(upgradeRequest); @@ -198,7 +201,7 @@ public class WebSocketProxyTest TestAsyncFrameHandler clientFrameHandler = new TestAsyncFrameHandler("CLIENT"); try (StacklessLogging stacklessLogging = new StacklessLogging(WebSocketCoreSession.class)) { - ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:8080/proxy/"), clientFrameHandler); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:" + PROXY_PORT + "/proxy/"), clientFrameHandler); upgradeRequest.setConfiguration(defaultCustomizer); CompletableFuture response = _client.connect(upgradeRequest); response.get(5, TimeUnit.SECONDS); @@ -218,10 +221,9 @@ public class WebSocketProxyTest CloseStatus closeStatus = CloseStatus.getCloseStatus(clientFrameHandler.receivedFrames.poll()); assertThat(closeStatus.getCode(), is(CloseStatus.SERVER_ERROR)); - assertThat(closeStatus.getReason(), containsString("Failed to upgrade to websocket: Unexpected HTTP Response Status Code:")); + assertThat(closeStatus.getReason(), containsString("Failed to upgrade to websocket: Unexpected HTTP Response")); } - @Test public void testClientError() throws Exception { @@ -238,10 +240,10 @@ public class WebSocketProxyTest try (StacklessLogging stacklessLogging = new StacklessLogging(WebSocketCoreSession.class)) { - ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:8080/proxy/"), clientFrameHandler); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:" + PROXY_PORT + "/proxy/"), clientFrameHandler); upgradeRequest.setConfiguration(defaultCustomizer); CompletableFuture response = _client.connect(upgradeRequest); - Exception e = assertThrows(ExecutionException.class, ()->response.get(5, TimeUnit.SECONDS)); + Exception e = assertThrows(ExecutionException.class, () -> response.get(5, TimeUnit.SECONDS)); assertThat(e.getMessage(), containsString("simulated client onOpen error")); assertTrue(clientFrameHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertTrue(serverFrameHandler.closeLatch.await(5, TimeUnit.SECONDS)); @@ -269,7 +271,7 @@ public class WebSocketProxyTest WebSocketProxy.Server2Proxy proxyServerSide = proxy.server2Proxy; TestAsyncFrameHandler clientFrameHandler = new TestAsyncFrameHandler("CLIENT"); - ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:8080/proxy/"), clientFrameHandler); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:" + PROXY_PORT + "/proxy/"), clientFrameHandler); upgradeRequest.setConfiguration(defaultCustomizer); CompletableFuture response = _client.connect(upgradeRequest); @@ -333,7 +335,7 @@ public class WebSocketProxyTest } }; - ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:8080/proxy/"), clientFrameHandler); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(_client, new URI("ws://localhost:" + PROXY_PORT + "/proxy/"), clientFrameHandler); upgradeRequest.setConfiguration(defaultCustomizer); CompletableFuture response = _client.connect(upgradeRequest); response.get(5, TimeUnit.SECONDS); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java index 1f69e9810db..66f235de234 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.core.server; @@ -24,13 +24,11 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.RawFrameBuilder; @@ -40,11 +38,11 @@ import org.eclipse.jetty.websocket.core.WebSocketTester; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.sameInstance; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -55,7 +53,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class WebSocketServerTest extends WebSocketTester { - private static Logger LOG = Log.getLogger(WebSocketServerTest.class); + private static Logger LOG = LoggerFactory.getLogger(WebSocketServerTest.class); private WebSocketServer server; @@ -207,29 +205,6 @@ public class WebSocketServerTest extends WebSocketTester } assertThat(serverHandler.receivedFrames.size(), is(5)); assertThat(receivedCallbacks.size(), is(5)); - - byte[] first = serverHandler.receivedFrames.poll().getPayload().array(); - assertThat(serverHandler.receivedFrames.poll().getPayload().array(), sameInstance(first)); - assertThat(serverHandler.receivedFrames.poll().getPayload().array(), sameInstance(first)); - byte[] second = serverHandler.receivedFrames.poll().getPayload().array(); - assertThat(serverHandler.receivedFrames.poll().getPayload().array(), sameInstance(second)); - assertThat(first, not(sameInstance(second))); - - ByteBufferPool pool = server.getServer().getConnectors()[0].getByteBufferPool(); - - assertThat(pool.acquire(first.length, false).array(), not(sameInstance(first))); - receivedCallbacks.poll().succeeded(); - assertThat(pool.acquire(first.length, false).array(), not(sameInstance(first))); - receivedCallbacks.poll().succeeded(); - assertThat(pool.acquire(first.length, false).array(), not(sameInstance(first))); - receivedCallbacks.poll().succeeded(); - assertThat(pool.acquire(first.length, false).array(), sameInstance(first)); - - assertThat(pool.acquire(second.length, false).array(), not(sameInstance(second))); - receivedCallbacks.poll().succeeded(); - assertThat(pool.acquire(second.length, false).array(), not(sameInstance(second))); - receivedCallbacks.poll().succeeded(); - assertThat(pool.acquire(second.length, false).array(), sameInstance(second)); } } diff --git a/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties index 039b5a51133..c08968b68e5 100644 --- a/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties @@ -1,24 +1,8 @@ -# -# ======================================================================== -# Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. -# ------------------------------------------------------------------------ -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# and Apache License v2.0 which accompanies this distribution. -# -# The Eclipse Public License is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# The Apache License v2.0 is available at -# http://www.opensource.org/licenses/apache2.0.php -# -# You may elect to redistribute this code under either of these licenses. -# ======================================================================== -# -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG # org.eclipse.jetty.io.LEVEL=DEBUG # org.eclipse.jetty.websocket.core.LEVEL=DEBUG +# org.eclipse.jetty.websocket.core.TestFrameHandler.LEVEL=DEBUG # org.eclipse.jetty.util.log.stderr.LONG=true # org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG # org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG @@ -29,5 +13,3 @@ org.eclipse.jetty.LEVEL=WARN # org.eclipse.jetty.websocket.LEVEL=DEBUG # org.eclipse.jetty.websocket.LEVEL=INFO # org.eclipse.jetty.websocket.core.LEVEL=DEBUG -### Showing any unintended (ignored) errors from CompletionCallback -# org.eclipse.jetty.websocket.core.CompletionCallback.LEVEL=ALL diff --git a/jetty-websocket/websocket-core/src/test/resources/keystore.jks b/jetty-websocket/websocket-core/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/jetty-websocket/websocket-core/src/test/resources/keystore.jks and /dev/null differ diff --git a/jetty-websocket/websocket-core/src/test/resources/keystore.p12 b/jetty-websocket/websocket-core/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..2edd267623f Binary files /dev/null and b/jetty-websocket/websocket-core/src/test/resources/keystore.p12 differ diff --git a/jetty-websocket/javax-websocket-client/pom.xml b/jetty-websocket/websocket-javax-client/pom.xml similarity index 84% rename from jetty-websocket/javax-websocket-client/pom.xml rename to jetty-websocket/websocket-javax-client/pom.xml index c4a74057925..b2fa1cd48aa 100644 --- a/jetty-websocket/javax-websocket-client/pom.xml +++ b/jetty-websocket/websocket-javax-client/pom.xml @@ -7,17 +7,22 @@ 4.0.0 - javax-websocket-client - Jetty :: Websocket :: javax.websocket :: Client Implementation + websocket-javax-client + Jetty :: Websocket :: javax.websocket :: Client - ${project.groupId}.javax.websocket.client + ${project.groupId}.javax.client org.eclipse.jetty.websocket - javax-websocket-common + websocket-util + ${project.version} + + + org.eclipse.jetty.websocket + websocket-javax-common ${project.version} @@ -29,6 +34,12 @@ org.eclipse.jetty.toolchain jetty-javax-websocket-api + + org.eclipse.jetty + jetty-xml + ${project.version} + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-websocket/websocket-javax-client/src/main/java/module-info.java b/jetty-websocket/websocket-javax-client/src/main/java/module-info.java new file mode 100644 index 00000000000..eb58cdef38e --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/main/java/module-info.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +import javax.websocket.ContainerProvider; + +import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainerProvider; + +module org.eclipse.jetty.websocket.javax.client +{ + exports org.eclipse.jetty.websocket.javax.client; + exports org.eclipse.jetty.websocket.javax.client.internal to org.eclipse.jetty.websocket.javax.server; + + requires transitive jetty.websocket.api; + requires transitive org.eclipse.jetty.client; + requires org.eclipse.jetty.websocket.javax.common; + + provides ContainerProvider with JavaxWebSocketClientContainerProvider; +} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java similarity index 74% rename from jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java rename to jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java index f19476e08cb..6e619ce2f81 100644 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.client; @@ -23,6 +23,7 @@ import javax.websocket.WebSocketContainer; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.thread.ShutdownThread; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; /** * Client {@link ContainerProvider} implementation. diff --git a/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/AnnotatedClientEndpointConfig.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/AnnotatedClientEndpointConfig.java new file mode 100644 index 00000000000..6a207d9223c --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/AnnotatedClientEndpointConfig.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.client.internal; + +import java.util.Collections; +import java.util.List; +import javax.websocket.ClientEndpoint; +import javax.websocket.ClientEndpointConfig; + +import org.eclipse.jetty.websocket.javax.common.ClientEndpointConfigWrapper; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; + +public class AnnotatedClientEndpointConfig extends ClientEndpointConfigWrapper +{ + public AnnotatedClientEndpointConfig(ClientEndpoint anno) + { + Configurator configurator; + try + { + configurator = anno.configurator().getDeclaredConstructor().newInstance(); + } + catch (Exception e) + { + StringBuilder err = new StringBuilder(); + err.append("Unable to instantiate ClientEndpoint.configurator() of "); + err.append(anno.configurator().getName()); + err.append(" defined as annotation in "); + err.append(anno.getClass().getName()); + throw new InvalidWebSocketException(err.toString(), e); + } + + ClientEndpointConfig build = Builder.create() + .encoders(List.of(anno.encoders())) + .decoders(List.of(anno.decoders())) + .preferredSubprotocols(List.of(anno.subprotocols())) + .extensions(Collections.emptyList()) + .configurator(configurator) + .build(); + + init(build); + } +} diff --git a/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/BasicClientEndpointConfig.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/BasicClientEndpointConfig.java new file mode 100644 index 00000000000..21456f05e3f --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/BasicClientEndpointConfig.java @@ -0,0 +1,29 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.client.internal; + +import org.eclipse.jetty.websocket.javax.common.ClientEndpointConfigWrapper; + +public class BasicClientEndpointConfig extends ClientEndpointConfigWrapper +{ + public BasicClientEndpointConfig() + { + init(Builder.create().configurator(EmptyConfigurator.INSTANCE).build()); + } +} diff --git a/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/EmptyConfigurator.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/EmptyConfigurator.java new file mode 100644 index 00000000000..c05d66796b8 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/EmptyConfigurator.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.client.internal; + +import java.util.List; +import java.util.Map; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.HandshakeResponse; + +public class EmptyConfigurator extends ClientEndpointConfig.Configurator +{ + public static final EmptyConfigurator INSTANCE = new EmptyConfigurator(); + + @Override + public void afterResponse(HandshakeResponse hr) + { + // do nothing + } + + @Override + public void beforeRequest(Map> headers) + { + // do nothing + } +} diff --git a/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxClientUpgradeRequest.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxClientUpgradeRequest.java new file mode 100644 index 00000000000..b2fd4d5ae52 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxClientUpgradeRequest.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.client.internal; + +import java.net.URI; +import java.security.Principal; + +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; +import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; + +public class JavaxClientUpgradeRequest extends ClientUpgradeRequest implements UpgradeRequest +{ + private final JavaxWebSocketFrameHandler frameHandler; + + public JavaxClientUpgradeRequest(JavaxWebSocketClientContainer clientContainer, WebSocketCoreClient coreClient, URI requestURI, Object websocketPojo) + { + super(coreClient, requestURI); + frameHandler = clientContainer.newFrameHandler(websocketPojo, this); + } + + @Override + public void upgrade(HttpResponse response, EndPoint endPoint) + { + frameHandler.setUpgradeRequest(this); + super.upgrade(response, endPoint); + } + + @Override + public FrameHandler getFrameHandler() + { + return frameHandler; + } + + @Override + public Principal getUserPrincipal() + { + // User Principal not available from Client API + return null; + } + + @Override + public URI getRequestURI() + { + return getURI(); + } +} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainer.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java similarity index 67% rename from jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainer.java rename to jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java index b807b4749f6..bdf93ba6dcd 100644 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainer.java +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.client; +package org.eclipse.jetty.websocket.javax.client.internal; import java.io.IOException; import java.net.URI; @@ -27,7 +27,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.Supplier; +import java.util.function.Function; import javax.websocket.ClientEndpoint; import javax.websocket.ClientEndpointConfig; import javax.websocket.DeploymentException; @@ -41,7 +41,6 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; import org.eclipse.jetty.websocket.javax.common.ConfiguredEndpoint; -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketExtensionConfig; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; @@ -56,7 +55,7 @@ import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactor public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer implements javax.websocket.WebSocketContainer { protected WebSocketCoreClient coreClient; - protected Supplier coreClientFactory; + protected Function coreClientFactory; private final JavaxWebSocketClientFrameHandlerFactory frameHandlerFactory; public JavaxWebSocketClientContainer() @@ -64,17 +63,34 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple this(new WebSocketComponents()); } - public JavaxWebSocketClientContainer(WebSocketComponents components) + /** + * Create a {@link javax.websocket.WebSocketContainer} using the supplied + * {@link HttpClient} for environments where you want to configure + * SSL/TLS or Proxy behaviors. + * + * @param httpClient the HttpClient instance to use + */ + public JavaxWebSocketClientContainer(final HttpClient httpClient) { - this(components, () -> + this(new WebSocketComponents(), (wsComponents) -> { - WebSocketCoreClient coreClient = new WebSocketCoreClient(components); + WebSocketCoreClient coreClient = new WebSocketCoreClient(httpClient, wsComponents); coreClient.getHttpClient().setName("Javax-WebSocketClient@" + Integer.toHexString(coreClient.getHttpClient().hashCode())); return coreClient; }); } - public JavaxWebSocketClientContainer(WebSocketComponents components, Supplier coreClientFactory) + public JavaxWebSocketClientContainer(WebSocketComponents components) + { + this(components, (wsComponents) -> + { + WebSocketCoreClient coreClient = new WebSocketCoreClient(wsComponents); + coreClient.getHttpClient().setName("Javax-WebSocketClient@" + Integer.toHexString(coreClient.getHttpClient().hashCode())); + return coreClient; + }); + } + + public JavaxWebSocketClientContainer(WebSocketComponents components, Function coreClientFactory) { super(components); this.coreClientFactory = coreClientFactory; @@ -90,7 +106,7 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple { if (coreClient == null) { - coreClient = coreClientFactory.get(); + coreClient = coreClientFactory.apply(components); addManaged(coreClient); } @@ -183,40 +199,33 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple } @Override - public Session connectToServer(final Class endpointClass, final ClientEndpointConfig config, URI path) throws IOException + public Session connectToServer(final Class endpointClass, final ClientEndpointConfig providedConfig, URI path) throws DeploymentException, IOException { - ClientEndpointConfig clientEndpointConfig = config; - if (clientEndpointConfig == null) - { - clientEndpointConfig = new EmptyClientEndpointConfig(); - } - ConfiguredEndpoint instance = newConfiguredEndpoint(endpointClass, clientEndpointConfig); - return connect(instance, path); + return connectToServer(newEndpoint(endpointClass), providedConfig, path); } @Override - public Session connectToServer(final Class annotatedEndpointClass, final URI path) throws IOException + public Session connectToServer(final Class annotatedEndpointClass, final URI path) throws DeploymentException, IOException { - ConfiguredEndpoint instance = newConfiguredEndpoint(annotatedEndpointClass, new EmptyClientEndpointConfig()); - return connect(instance, path); + return connectToServer(newEndpoint(annotatedEndpointClass), path); } @Override - public Session connectToServer(final Endpoint endpoint, final ClientEndpointConfig config, final URI path) throws DeploymentException, IOException + public Session connectToServer(final Endpoint endpoint, final ClientEndpointConfig providedConfig, final URI path) throws DeploymentException, IOException { - ClientEndpointConfig clientEndpointConfig = config; - if (clientEndpointConfig == null) - { - clientEndpointConfig = new EmptyClientEndpointConfig(); - } - ConfiguredEndpoint instance = newConfiguredEndpoint(endpoint, clientEndpointConfig); + ClientEndpointConfig config = providedConfig; + if (config == null) + config = new BasicClientEndpointConfig(); + + ConfiguredEndpoint instance = new ConfiguredEndpoint(endpoint, config); return connect(instance, path); } @Override public Session connectToServer(Object endpoint, URI path) throws DeploymentException, IOException { - ConfiguredEndpoint instance = newConfiguredEndpoint(endpoint, new EmptyClientEndpointConfig()); + ClientEndpointConfig config = getAnnotatedConfig(endpoint); + ConfiguredEndpoint instance = new ConfiguredEndpoint(endpoint, config); return connect(instance, path); } @@ -232,46 +241,24 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple return getHttpClient().getExecutor(); } - private ConfiguredEndpoint newConfiguredEndpoint(Class endpointClass, EndpointConfig config) + private T newEndpoint(Class endpointClass) throws DeploymentException { try { - return newConfiguredEndpoint(endpointClass.getConstructor().newInstance(), config); + return endpointClass.getConstructor().newInstance(); } catch (Throwable e) { - throw new InvalidWebSocketException("Unable to instantiate websocket: " + endpointClass.getName()); + throw new DeploymentException("Unable to instantiate websocket: " + endpointClass.getName()); } } - public ConfiguredEndpoint newConfiguredEndpoint(Object endpoint, EndpointConfig providedConfig) throws DeploymentException - { - EndpointConfig config = providedConfig; - - if (config == null) - { - config = newEmptyConfig(endpoint); - } - - config = readAnnotatedConfig(endpoint, config); - - return new ConfiguredEndpoint(endpoint, config); - } - - protected EndpointConfig newEmptyConfig(Object endpoint) - { - return new EmptyClientEndpointConfig(); - } - - protected EndpointConfig readAnnotatedConfig(Object endpoint, EndpointConfig config) throws DeploymentException + private ClientEndpointConfig getAnnotatedConfig(Object endpoint) throws DeploymentException { ClientEndpoint anno = endpoint.getClass().getAnnotation(ClientEndpoint.class); - if (anno != null) - { - // Overwrite Config from Annotation - // TODO: should we merge with provided config? - return new AnnotatedClientEndpointConfig(anno); - } - return config; + if (anno == null) + throw new DeploymentException("Could not get ClientEndpoint annotation for " + endpoint.getClass().getName()); + + return new AnnotatedClientEndpointConfig(anno); } } diff --git a/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientFrameHandlerFactory.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientFrameHandlerFactory.java new file mode 100644 index 00000000000..39f3221b877 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientFrameHandlerFactory.java @@ -0,0 +1,64 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.client.internal; + +import javax.websocket.ClientEndpoint; +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; + +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerMetadata; +import org.eclipse.jetty.websocket.util.InvokerUtils; + +public class JavaxWebSocketClientFrameHandlerFactory extends JavaxWebSocketFrameHandlerFactory +{ + public JavaxWebSocketClientFrameHandlerFactory(JavaxWebSocketContainer container, InvokerUtils.ParamIdentifier paramIdentifier) + { + super(container, paramIdentifier); + } + + public JavaxWebSocketClientFrameHandlerFactory(JavaxWebSocketContainer container) + { + super(container, InvokerUtils.PARAM_IDENTITY); + } + + @Override + public EndpointConfig newDefaultEndpointConfig(Class endpointClass, String path) + { + return new BasicClientEndpointConfig(); + } + + @Override + public JavaxWebSocketFrameHandlerMetadata getMetadata(Class endpointClass, EndpointConfig endpointConfig) + { + if (javax.websocket.Endpoint.class.isAssignableFrom(endpointClass)) + { + return createEndpointMetadata((Class)endpointClass, endpointConfig); + } + + if (endpointClass.getAnnotation(ClientEndpoint.class) == null) + { + return null; + } + + JavaxWebSocketFrameHandlerMetadata metadata = new JavaxWebSocketFrameHandlerMetadata(endpointConfig); + return discoverJavaxFrameHandlerMetadata(endpointClass, metadata); + } +} diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JsrUpgradeListener.java b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JsrUpgradeListener.java similarity index 72% rename from jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JsrUpgradeListener.java rename to jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JsrUpgradeListener.java index 1df98227209..8ce0df47cdb 100644 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JsrUpgradeListener.java +++ b/jetty-websocket/websocket-javax-client/src/main/java/org/eclipse/jetty/websocket/javax/client/internal/JsrUpgradeListener.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.client; +package org.eclipse.jetty.websocket.javax.client.internal; import java.util.ArrayList; import java.util.HashMap; diff --git a/jetty-websocket/javax-websocket-client/src/main/resources/META-INF/services/javax.websocket.ContainerProvider b/jetty-websocket/websocket-javax-client/src/main/resources/META-INF/services/javax.websocket.ContainerProvider similarity index 100% rename from jetty-websocket/javax-websocket-client/src/main/resources/META-INF/services/javax.websocket.ContainerProvider rename to jetty-websocket/websocket-javax-client/src/main/resources/META-INF/services/javax.websocket.ContainerProvider diff --git a/jetty-websocket/websocket-javax-client/src/test/java/examples/EchoEndpoint.java b/jetty-websocket/websocket-javax-client/src/test/java/examples/EchoEndpoint.java new file mode 100644 index 00000000000..a373d6b09e4 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/test/java/examples/EchoEndpoint.java @@ -0,0 +1,90 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package examples; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +/** + * Basic Echo Client Endpoint + */ +public class EchoEndpoint extends Endpoint implements MessageHandler.Whole +{ + private final CountDownLatch closeLatch = new CountDownLatch(1); + private Session session; + + public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException + { + return this.closeLatch.await(duration, unit); + } + + @Override + public void onClose(Session session, CloseReason closeReason) + { + System.out.printf("Connection closed: Session.id=%s - %s%n", session.getId(), closeReason); + this.session = null; + this.closeLatch.countDown(); // trigger latch + } + + @Override + public void onOpen(Session session, EndpointConfig config) + { + System.out.printf("Got open: Session.id=%s%n", session.getId()); + this.session = session; + this.session.addMessageHandler(this); + try + { + session.getBasicRemote().sendText("Hello"); + session.getBasicRemote().sendText("Thanks for the conversation."); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + @Override + public void onMessage(String msg) + { + System.out.printf("Got msg: \"%s\"%n", msg); + if (msg.contains("Thanks")) + { + try + { + session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "I'm done")); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + @Override + public void onError(Session session, Throwable cause) + { + cause.printStackTrace(); + } +} diff --git a/jetty-websocket/websocket-javax-client/src/test/java/examples/OriginServerConfigurator.java b/jetty-websocket/websocket-javax-client/src/test/java/examples/OriginServerConfigurator.java new file mode 100644 index 00000000000..44c6c705c90 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/test/java/examples/OriginServerConfigurator.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package examples; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.websocket.ClientEndpointConfig; + +/** + * Provide a means to set the `Origin` header for outgoing WebSocket upgrade requests + */ +public class OriginServerConfigurator extends ClientEndpointConfig.Configurator +{ + private final String originServer; + + public OriginServerConfigurator(String originServer) + { + this.originServer = originServer; + } + + @Override + public void beforeRequest(Map> headers) + { + headers.put("Origin", Collections.singletonList(originServer)); + super.beforeRequest(headers); + } +} diff --git a/jetty-websocket/websocket-javax-client/src/test/java/examples/SecureClientContainerExample.java b/jetty-websocket/websocket-javax-client/src/test/java/examples/SecureClientContainerExample.java new file mode 100644 index 00000000000..b41d66e1336 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/test/java/examples/SecureClientContainerExample.java @@ -0,0 +1,89 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package examples; + +import java.net.URI; +import java.util.concurrent.TimeUnit; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.WebSocketContainer; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; + +public class SecureClientContainerExample +{ + public static void main(String[] args) + { + WebSocketContainer client = null; + try + { + URI echoUri = URI.create("wss://echo.websocket.org"); + client = getConfiguredWebSocketContainer(); + + ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create() + .configurator(new OriginServerConfigurator("https://websocket.org")) + .build(); + EchoEndpoint echoEndpoint = new EchoEndpoint(); + client.connectToServer(echoEndpoint, clientEndpointConfig, echoUri); + System.out.printf("Connecting to : %s%n", echoUri); + + // wait for closed socket connection. + echoEndpoint.awaitClose(5, TimeUnit.SECONDS); + } + catch (Throwable t) + { + t.printStackTrace(); + } + finally + { + /* Since javax.websocket clients have no defined LifeCycle we + * want to either close/stop the client, or exit the JVM + * via a System.exit(), otherwise the threads this client keeps + * open will prevent the JVM from terminating naturally. + * @see https://github.com/eclipse-ee4j/websocket-api/issues/212 + */ + LifeCycle.stop(client); + } + } + + /** + * Since javax.websocket does not have an API for configuring SSL, each implementation + * of javax.websocket has to come up with their own SSL configuration mechanism. + * + * @return the client WebSocketContainer + * @see javax.websocket issue #210 + */ + public static WebSocketContainer getConfiguredWebSocketContainer() throws Exception + { + SslContextFactory.Client ssl = new SslContextFactory.Client(); + ssl.setExcludeCipherSuites(); // echo.websocket.org use WEAK cipher suites + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSslContextFactory(ssl); + + HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); + JavaxWebSocketClientContainer clientContainer = new JavaxWebSocketClientContainer(httpClient); + clientContainer.addManaged(httpClient); // allow clientContainer to own httpClient (for start/stop lifecycle) + clientContainer.start(); + return clientContainer; + } +} diff --git a/jetty-websocket/websocket-javax-client/src/test/java/examples/SecureWebSocketContainerExample.java b/jetty-websocket/websocket-javax-client/src/test/java/examples/SecureWebSocketContainerExample.java new file mode 100644 index 00000000000..85680ae634a --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/test/java/examples/SecureWebSocketContainerExample.java @@ -0,0 +1,93 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package examples; + +import java.io.FileNotFoundException; +import java.net.URI; +import java.net.URL; +import java.util.concurrent.TimeUnit; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.ContainerProvider; +import javax.websocket.WebSocketContainer; + +import org.eclipse.jetty.util.component.LifeCycle; + +public class SecureWebSocketContainerExample +{ + public static void main(String[] args) + { + WebSocketContainer client = null; + try + { + URI echoUri = URI.create("wss://echo.websocket.org"); + client = getConfiguredWebSocketContainer(); + ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create() + .configurator(new OriginServerConfigurator("https://websocket.org")) + .build(); + EchoEndpoint echoEndpoint = new EchoEndpoint(); + client.connectToServer(echoEndpoint, clientEndpointConfig, echoUri); + System.out.printf("Connecting to : %s%n", echoUri); + + // wait for closed socket connection. + echoEndpoint.awaitClose(5, TimeUnit.SECONDS); + } + catch (Throwable t) + { + t.printStackTrace(); + } + finally + { + /* Since javax.websocket clients have no defined LifeCycle we + * want to either close/stop the client, or exit the JVM + * via a System.exit(), otherwise the threads this client keeps + * open will prevent the JVM from terminating naturally. + * @see https://github.com/eclipse-ee4j/websocket-api/issues/212 + */ + LifeCycle.stop(client); + } + } + + /** + * Since javax.websocket does not have an API for configuring SSL, each implementation + * of javax.websocket has to come up with their own SSL configuration mechanism. + *

      + * When the {@link WebSocketContainer} is used it will need to create and start a Jetty WebSocket Client. + * The {@code WebSocketClient} must use a Jetty {@code HttpClient} which can be configured for SSL, this + * configuration needs to be passed into the Jetty {@code HttpClient} at initialization. + *

      + *

      + * How Jetty makes this available, is via the {@code jetty-websocket-httpclient.xml} classloader resource + * along with the jetty-xml artifact. + *

      + * @return the client WebSocketContainer + * @see javax.websocket issue #210 + */ + public static WebSocketContainer getConfiguredWebSocketContainer() throws Exception + { + URL jettyHttpClientConfigUrl = Thread.currentThread().getContextClassLoader() + .getResource("jetty-websocket-httpclient.xml"); + + if (jettyHttpClientConfigUrl == null) + { + throw new FileNotFoundException("Unable to find Jetty HttpClient configuration XML"); + } + + return ContainerProvider.getWebSocketContainer(); + } +} diff --git a/jetty-websocket/websocket-javax-client/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-javax-client/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..a67f4bd5675 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/test/resources/jetty-logging.properties @@ -0,0 +1,9 @@ +# Jetty Logging using jetty-slf4j-impl +org.eclipse.jetty.LEVEL=INFO +# org.eclipse.jetty.websocket.LEVEL=DEBUG +# org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG +# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG +# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG +# org.eclipse.jetty.client.LEVEL=DEBUG +# org.eclipse.jetty.io.LEVEL=DEBUG +# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO diff --git a/jetty-websocket/websocket-javax-client/src/test/resources/jetty-websocket-httpclient.xml b/jetty-websocket/websocket-javax-client/src/test/resources/jetty-websocket-httpclient.xml new file mode 100644 index 00000000000..f2bab081984 --- /dev/null +++ b/jetty-websocket/websocket-javax-client/src/test/resources/jetty-websocket-httpclient.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-common/pom.xml b/jetty-websocket/websocket-javax-common/pom.xml similarity index 86% rename from jetty-websocket/javax-websocket-common/pom.xml rename to jetty-websocket/websocket-javax-common/pom.xml index 9fd8f573acd..d606965d46c 100644 --- a/jetty-websocket/javax-websocket-common/pom.xml +++ b/jetty-websocket/websocket-javax-common/pom.xml @@ -7,11 +7,11 @@ 4.0.0 - javax-websocket-common - Jetty :: Websocket :: javax.websocket :: Common Impl + websocket-javax-common + Jetty :: Websocket :: javax.websocket :: Common - ${project.groupId}.javax.websocket.common + ${project.groupId}.javax.common @@ -71,21 +71,22 @@ websocket-core ${project.version}
      + + org.eclipse.jetty.websocket + websocket-util + ${project.version} + org.eclipse.jetty.toolchain jetty-javax-websocket-api - - org.eclipse.jetty - jetty-client - ${project.version} - test + org.slf4j + slf4j-api org.eclipse.jetty - jetty-server - ${project.version} + jetty-slf4j-impl test diff --git a/jetty-websocket/websocket-javax-common/src/main/java/module-info.java b/jetty-websocket/websocket-javax-common/src/main/java/module-info.java new file mode 100644 index 00000000000..08b85dda862 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/module-info.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +module org.eclipse.jetty.websocket.javax.common +{ + exports org.eclipse.jetty.websocket.javax.common; + exports org.eclipse.jetty.websocket.javax.common.decoders; + exports org.eclipse.jetty.websocket.javax.common.encoders; + exports org.eclipse.jetty.websocket.javax.common.messages; + + requires transitive jetty.websocket.api; + requires transitive org.eclipse.jetty.http; + requires transitive org.eclipse.jetty.io; + requires transitive org.eclipse.jetty.websocket.core; + requires transitive org.eclipse.jetty.websocket.util; + requires org.slf4j; +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ClientEndpointConfigWrapper.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ClientEndpointConfigWrapper.java new file mode 100644 index 00000000000..dac3b9bed89 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ClientEndpointConfigWrapper.java @@ -0,0 +1,61 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.util.List; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.Extension; + +public class ClientEndpointConfigWrapper extends EndpointConfigWrapper implements ClientEndpointConfig +{ + private ClientEndpointConfig _endpointConfig; + + public ClientEndpointConfigWrapper() + { + } + + public ClientEndpointConfigWrapper(ClientEndpointConfig endpointConfig) + { + init(endpointConfig); + } + + public void init(ClientEndpointConfig endpointConfig) + { + _endpointConfig = endpointConfig; + super.init(endpointConfig); + } + + @Override + public List getPreferredSubprotocols() + { + return _endpointConfig.getPreferredSubprotocols(); + } + + @Override + public List getExtensions() + { + return _endpointConfig.getExtensions(); + } + + @Override + public Configurator getConfigurator() + { + return _endpointConfig.getConfigurator(); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ConfiguredEndpoint.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ConfiguredEndpoint.java similarity index 51% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ConfiguredEndpoint.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ConfiguredEndpoint.java index 0b18489c941..bd4770e241a 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ConfiguredEndpoint.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ConfiguredEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/EndpointConfigWrapper.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/EndpointConfigWrapper.java new file mode 100644 index 00000000000..665b3873e89 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/EndpointConfigWrapper.java @@ -0,0 +1,75 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.websocket.Decoder; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public abstract class EndpointConfigWrapper implements EndpointConfig, PathParamProvider +{ + private EndpointConfig _endpointConfig; + private Map _pathParameters; + + public EndpointConfigWrapper() + { + } + + public EndpointConfigWrapper(EndpointConfig endpointConfig) + { + init(endpointConfig); + } + + public void init(EndpointConfig endpointConfig) + { + _endpointConfig = endpointConfig; + + if (endpointConfig instanceof PathParamProvider) + _pathParameters = ((PathParamProvider)endpointConfig).getPathParams(); + else + _pathParameters = Collections.emptyMap(); + } + + @Override + public List> getEncoders() + { + return _endpointConfig.getEncoders(); + } + + @Override + public List> getDecoders() + { + return _endpointConfig.getDecoders(); + } + + @Override + public Map getUserProperties() + { + return _endpointConfig.getUserProperties(); + } + + @Override + public Map getPathParams() + { + return _pathParameters; + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InitException.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InitException.java new file mode 100644 index 00000000000..80f12bdfce4 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/InitException.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +/** + * Exception during initialization of the Endpoint + */ +public class InitException extends IllegalStateException +{ + private static final long serialVersionUID = -4691138423037387558L; + + public InitException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketAsyncRemote.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketAsyncRemote.java similarity index 81% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketAsyncRemote.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketAsyncRemote.java index 5a969df1b52..ab86f54b4bd 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketAsyncRemote.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketAsyncRemote.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -28,20 +28,20 @@ import javax.websocket.SendResult; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.common.messages.MessageOutputStream; -import org.eclipse.jetty.websocket.javax.common.messages.MessageWriter; -import org.eclipse.jetty.websocket.javax.common.util.TextUtil; +import org.eclipse.jetty.websocket.util.TextUtil; +import org.eclipse.jetty.websocket.util.messages.MessageOutputStream; +import org.eclipse.jetty.websocket.util.messages.MessageWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JavaxWebSocketAsyncRemote extends JavaxWebSocketRemoteEndpoint implements javax.websocket.RemoteEndpoint.Async { - static final Logger LOG = Log.getLogger(JavaxWebSocketAsyncRemote.class); + static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketAsyncRemote.class); - protected JavaxWebSocketAsyncRemote(JavaxWebSocketSession session, FrameHandler.CoreSession coreSession) + protected JavaxWebSocketAsyncRemote(JavaxWebSocketSession session, CoreSession coreSession) { super(session, coreSession); } diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketBasicRemote.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketBasicRemote.java new file mode 100644 index 00000000000..a119ebf1f9c --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketBasicRemote.java @@ -0,0 +1,166 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; +import javax.websocket.EncodeException; +import javax.websocket.RemoteEndpoint; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.util.TextUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.nio.charset.StandardCharsets.UTF_8; + +public class JavaxWebSocketBasicRemote extends JavaxWebSocketRemoteEndpoint implements RemoteEndpoint.Basic +{ + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketBasicRemote.class); + + protected JavaxWebSocketBasicRemote(JavaxWebSocketSession session, CoreSession coreSession) + { + super(session, coreSession); + } + + @Override + public OutputStream getSendStream() throws IOException + { + return newMessageOutputStream(); + } + + @Override + public Writer getSendWriter() throws IOException + { + return newMessageWriter(); + } + + @Override + public void sendBinary(ByteBuffer data) throws IOException + { + assertMessageNotNull(data); + if (LOG.isDebugEnabled()) + { + LOG.debug("sendBinary({})", BufferUtil.toDetailString(data)); + } + + FutureCallback b = new FutureCallback(); + sendFrame(new Frame(OpCode.BINARY).setPayload(data), b, false); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); + } + + @Override + public void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException + { + assertMessageNotNull(partialByte); + if (LOG.isDebugEnabled()) + { + LOG.debug("sendBinary({},{})", BufferUtil.toDetailString(partialByte), isLast); + } + + Frame frame; + switch (messageType) + { + case -1: + // New message! + frame = new Frame(OpCode.BINARY); + break; + case OpCode.TEXT: + throw new IllegalStateException("Cannot send a partial BINARY message: TEXT message in progress"); + case OpCode.BINARY: + frame = new Frame(OpCode.CONTINUATION); + break; + default: + throw new IllegalStateException("Cannot send a partial BINARY message: unrecognized active message type " + OpCode.name(messageType)); + } + + frame.setPayload(partialByte); + frame.setFin(isLast); + FutureCallback b = new FutureCallback(); + sendFrame(frame, b, false); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); + } + + @Override + public void sendObject(Object data) throws IOException, EncodeException + { + FutureCallback b = new FutureCallback(); + super.sendObject(data, b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); + } + + @Override + public void sendText(String text) throws IOException + { + assertMessageNotNull(text); + if (LOG.isDebugEnabled()) + { + LOG.debug("sendText({})", TextUtil.hint(text)); + } + + FutureCallback b = new FutureCallback(); + sendFrame(new Frame(OpCode.TEXT).setPayload(text), b, false); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); + } + + @Override + public void sendText(String partialMessage, boolean isLast) throws IOException + { + assertMessageNotNull(partialMessage); + if (LOG.isDebugEnabled()) + { + LOG.debug("sendText({},{})", TextUtil.hint(partialMessage), isLast); + } + + Frame frame; + switch (messageType) + { + case -1: + // New message! + frame = new Frame(OpCode.TEXT); + break; + case OpCode.TEXT: + frame = new Frame(OpCode.CONTINUATION); + break; + case OpCode.BINARY: + throw new IllegalStateException("Cannot send a partial TEXT message: BINARY message in progress"); + default: + throw new IllegalStateException("Cannot send a partial TEXT message: unrecognized active message type " + OpCode.name(messageType)); + } + + frame.setPayload(BufferUtil.toBuffer(partialMessage, UTF_8)); + frame.setFin(isLast); + FutureCallback b = new FutureCallback(); + sendFrame(frame, b, false); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); + } + + private long getBlockingTimeout() + { + long idleTimeout = getIdleTimeout(); + return (idleTimeout > 0) ? idleTimeout + 1000 : idleTimeout; + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java similarity index 79% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java index 991eaa2fb28..44c07a2815b 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -31,19 +31,19 @@ import javax.websocket.WebSocketContainer; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class JavaxWebSocketContainer extends ContainerLifeCycle implements javax.websocket.WebSocketContainer { - private static final Logger LOG = Log.getLogger(JavaxWebSocketContainer.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketContainer.class); private final SessionTracker sessionTracker = new SessionTracker(); - private List sessionListeners = new ArrayList<>(); - protected FrameHandler.ConfigurationCustomizer defaultCustomizer = new FrameHandler.ConfigurationCustomizer(); - private WebSocketComponents components; + private final List sessionListeners = new ArrayList<>(); + protected final Configuration.ConfigurationCustomizer defaultCustomizer = new Configuration.ConfigurationCustomizer(); + protected final WebSocketComponents components; public JavaxWebSocketContainer(WebSocketComponents components) { diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtension.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtension.java similarity index 77% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtension.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtension.java index 64cb1970871..cf62895ac0c 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtension.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtension.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtensionConfig.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtensionConfig.java new file mode 100644 index 00000000000..814f150e47a --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketExtensionConfig.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import javax.websocket.Extension; + +import org.eclipse.jetty.websocket.core.ExtensionConfig; + +public class JavaxWebSocketExtensionConfig extends ExtensionConfig +{ + public JavaxWebSocketExtensionConfig(Extension ext) + { + super(ext.getName()); + for (Extension.Parameter param : ext.getParameters()) + { + this.setParameter(param.getName(), param.getValue()); + } + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java similarity index 81% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java index 033cc270aa2..1ee1797dc86 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -22,43 +22,49 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.nio.ByteBuffer; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; +import javax.websocket.ClientEndpointConfig; import javax.websocket.CloseReason; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.PongMessage; +import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; -import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; import org.eclipse.jetty.websocket.javax.common.messages.DecodedBinaryMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedBinaryStreamMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedTextMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedTextStreamMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.PartialByteArrayMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.PartialByteBufferMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.PartialStringMessageSink; -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.messages.MessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialByteArrayMessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialStringMessageSink; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JavaxWebSocketFrameHandler implements FrameHandler { private final Logger logger; private final JavaxWebSocketContainer container; private final Object endpointInstance; + private final AtomicBoolean closeNotified = new AtomicBoolean(); + /** * List of configured named variables in the uri-template. *

      @@ -91,18 +97,16 @@ public class JavaxWebSocketFrameHandler implements FrameHandler private MethodHandle errorHandle; private JavaxWebSocketFrameHandlerMetadata.MessageMetadata textMetadata; private JavaxWebSocketFrameHandlerMetadata.MessageMetadata binaryMetadata; - // TODO: need pingHandle ? private MethodHandle pongHandle; private UpgradeRequest upgradeRequest; - private UpgradeResponse upgradeResponse; - private final EndpointConfig endpointConfig; + private EndpointConfig endpointConfig; + private final Map messageHandlerMap = new HashMap<>(); private MessageSink textSink; private MessageSink binarySink; private MessageSink activeMessageSink; private JavaxWebSocketSession session; - private Map messageHandlerMap; private CoreSession coreSession; protected byte dataType = OpCode.UNDEFINED; @@ -115,13 +119,13 @@ public class JavaxWebSocketFrameHandler implements FrameHandler MethodHandle pongHandle, EndpointConfig endpointConfig) { - this.logger = Log.getLogger(endpointInstance.getClass()); + this.logger = LoggerFactory.getLogger(endpointInstance.getClass()); this.container = container; if (endpointInstance instanceof ConfiguredEndpoint) { RuntimeException oops = new RuntimeException("ConfiguredEndpoint needs to be unwrapped"); - logger.warn(oops); + logger.warn("Unexpected ConfiguredEndpoint", oops); throw oops; } this.endpointInstance = endpointInstance; @@ -134,7 +138,6 @@ public class JavaxWebSocketFrameHandler implements FrameHandler this.pongHandle = pongHandle; this.endpointConfig = endpointConfig; - this.messageHandlerMap = new HashMap<>(); } public Object getEndpoint() @@ -155,20 +158,19 @@ public class JavaxWebSocketFrameHandler implements FrameHandler @Override public void onOpen(CoreSession coreSession, Callback callback) { + this.coreSession = coreSession; + try { - this.coreSession = coreSession; + // Rewire EndpointConfig to call CoreSession setters if Jetty specific properties are set. + endpointConfig = getWrappedEndpointConfig(); session = new JavaxWebSocketSession(container, coreSession, this, endpointConfig); - openHandle = InvokerUtils.bindTo(openHandle, session, endpointConfig); closeHandle = InvokerUtils.bindTo(closeHandle, session); errorHandle = InvokerUtils.bindTo(errorHandle, session); - - JavaxWebSocketFrameHandlerMetadata.MessageMetadata actualTextMetadata = JavaxWebSocketFrameHandlerMetadata.MessageMetadata.copyOf(textMetadata); - JavaxWebSocketFrameHandlerMetadata.MessageMetadata actualBinaryMetadata = JavaxWebSocketFrameHandlerMetadata.MessageMetadata.copyOf(binaryMetadata); - pongHandle = InvokerUtils.bindTo(pongHandle, session); + JavaxWebSocketFrameHandlerMetadata.MessageMetadata actualTextMetadata = JavaxWebSocketFrameHandlerMetadata.MessageMetadata.copyOf(textMetadata); if (actualTextMetadata != null) { if (actualTextMetadata.isMaxMessageSizeSet()) @@ -177,10 +179,10 @@ public class JavaxWebSocketFrameHandler implements FrameHandler actualTextMetadata.handle = InvokerUtils.bindTo(actualTextMetadata.handle, endpointInstance, endpointConfig, session); actualTextMetadata.handle = JavaxWebSocketFrameHandlerFactory.wrapNonVoidReturnType(actualTextMetadata.handle, session); textSink = JavaxWebSocketFrameHandlerFactory.createMessageSink(session, actualTextMetadata); - textMetadata = actualTextMetadata; } + JavaxWebSocketFrameHandlerMetadata.MessageMetadata actualBinaryMetadata = JavaxWebSocketFrameHandlerMetadata.MessageMetadata.copyOf(binaryMetadata); if (actualBinaryMetadata != null) { if (actualBinaryMetadata.isMaxMessageSizeSet()) @@ -189,7 +191,6 @@ public class JavaxWebSocketFrameHandler implements FrameHandler actualBinaryMetadata.handle = InvokerUtils.bindTo(actualBinaryMetadata.handle, endpointInstance, endpointConfig, session); actualBinaryMetadata.handle = JavaxWebSocketFrameHandlerFactory.wrapNonVoidReturnType(actualBinaryMetadata.handle, session); binarySink = JavaxWebSocketFrameHandlerFactory.createMessageSink(session, actualBinaryMetadata); - binaryMetadata = actualBinaryMetadata; } @@ -206,6 +207,48 @@ public class JavaxWebSocketFrameHandler implements FrameHandler } } + private EndpointConfig getWrappedEndpointConfig() + { + final Map listenerMap = new PutListenerMap(this.endpointConfig.getUserProperties(), this::configListener); + + EndpointConfig wrappedConfig; + if (endpointConfig instanceof ServerEndpointConfig) + { + wrappedConfig = new ServerEndpointConfigWrapper((ServerEndpointConfig)endpointConfig) + { + @Override + public Map getUserProperties() + { + return listenerMap; + } + }; + } + else if (endpointConfig instanceof ClientEndpointConfig) + { + wrappedConfig = new ClientEndpointConfigWrapper((ClientEndpointConfig)endpointConfig) + { + @Override + public Map getUserProperties() + { + return listenerMap; + } + }; + } + else + { + wrappedConfig = new EndpointConfigWrapper(endpointConfig) + { + @Override + public Map getUserProperties() + { + return listenerMap; + } + }; + } + + return wrappedConfig; + } + @Override public void onFrame(Frame frame, Callback callback) { @@ -239,9 +282,27 @@ public class JavaxWebSocketFrameHandler implements FrameHandler dataType = OpCode.UNDEFINED; } + public void onClose(Frame frame, Callback callback) + { + notifyOnClose(CloseStatus.getCloseStatus(frame), callback); + } + @Override public void onClosed(CloseStatus closeStatus, Callback callback) { + notifyOnClose(closeStatus, callback); + container.notifySessionListeners((listener) -> listener.onJavaxWebSocketSessionClosed(session)); + } + + private void notifyOnClose(CloseStatus closeStatus, Callback callback) + { + // Make sure onClose is only notified once. + if (!closeNotified.compareAndSet(false, true)) + { + callback.succeeded(); + return; + } + try { if (closeHandle != null) @@ -249,14 +310,13 @@ public class JavaxWebSocketFrameHandler implements FrameHandler CloseReason closeReason = new CloseReason(CloseReason.CloseCodes.getCloseCode(closeStatus.getCode()), closeStatus.getReason()); closeHandle.invoke(closeReason); } + callback.succeeded(); } catch (Throwable cause) { callback.failed(new WebSocketException(endpointInstance.getClass().getSimpleName() + " CLOSE method error: " + cause.getMessage(), cause)); } - - container.notifySessionListeners((listener) -> listener.onJavaxWebSocketSessionClosed(session)); } @Override @@ -280,14 +340,9 @@ public class JavaxWebSocketFrameHandler implements FrameHandler public Set getMessageHandlers() { - if (messageHandlerMap.isEmpty()) - { - return Collections.emptySet(); - } - - return Collections.unmodifiableSet(messageHandlerMap.values().stream() - .map((rh) -> rh.getMessageHandler()) - .collect(Collectors.toSet())); + return messageHandlerMap.values().stream() + .map(RegisteredMessageHandler::getMessageHandler) + .collect(Collectors.toUnmodifiableSet()); } public Map getMessageHandlerMap() @@ -318,17 +373,16 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { try { - // TODO: move methodhandle lookup to container? - MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + MethodHandles.Lookup lookup = JavaxWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); MethodHandle partialMessageHandler = lookup - .findVirtual(MessageHandler.Partial.class, "onMessage", MethodType.methodType(Void.TYPE, Object.class, Boolean.TYPE)); + .findVirtual(MessageHandler.Partial.class, "onMessage", MethodType.methodType(void.class, Object.class, boolean.class)); partialMessageHandler = partialMessageHandler.bindTo(handler); // MessageHandler.Partial has no decoder support! if (byte[].class.isAssignableFrom(clazz)) { assertBasicTypeNotRegistered(OpCode.BINARY, this.binaryMetadata, handler.getClass().getName()); - MessageSink messageSink = new PartialByteArrayMessageSink(session, partialMessageHandler); + MessageSink messageSink = new PartialByteArrayMessageSink(coreSession, partialMessageHandler); this.binarySink = registerMessageHandler(OpCode.BINARY, clazz, handler, messageSink); JavaxWebSocketFrameHandlerMetadata.MessageMetadata metadata = new JavaxWebSocketFrameHandlerMetadata.MessageMetadata(); metadata.handle = partialMessageHandler; @@ -338,7 +392,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler else if (ByteBuffer.class.isAssignableFrom(clazz)) { assertBasicTypeNotRegistered(OpCode.BINARY, this.binaryMetadata, handler.getClass().getName()); - MessageSink messageSink = new PartialByteBufferMessageSink(session, partialMessageHandler); + MessageSink messageSink = new PartialByteBufferMessageSink(coreSession, partialMessageHandler); this.binarySink = registerMessageHandler(OpCode.BINARY, clazz, handler, messageSink); JavaxWebSocketFrameHandlerMetadata.MessageMetadata metadata = new JavaxWebSocketFrameHandlerMetadata.MessageMetadata(); metadata.handle = partialMessageHandler; @@ -348,7 +402,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler else if (String.class.isAssignableFrom(clazz)) { assertBasicTypeNotRegistered(OpCode.TEXT, this.textMetadata, handler.getClass().getName()); - MessageSink messageSink = new PartialStringMessageSink(session, partialMessageHandler); + MessageSink messageSink = new PartialStringMessageSink(coreSession, partialMessageHandler); this.textSink = registerMessageHandler(OpCode.TEXT, clazz, handler, messageSink); JavaxWebSocketFrameHandlerMetadata.MessageMetadata metadata = new JavaxWebSocketFrameHandlerMetadata.MessageMetadata(); metadata.handle = partialMessageHandler; @@ -376,9 +430,8 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { try { - // TODO: move methodhandle lookup to container? - MethodHandles.Lookup lookup = MethodHandles.publicLookup(); - MethodHandle wholeMsgMethodHandle = lookup.findVirtual(MessageHandler.Whole.class, "onMessage", MethodType.methodType(Void.TYPE, Object.class)); + MethodHandles.Lookup lookup = JavaxWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); + MethodHandle wholeMsgMethodHandle = lookup.findVirtual(MessageHandler.Whole.class, "onMessage", MethodType.methodType(void.class, Object.class)); wholeMsgMethodHandle = wholeMsgMethodHandle.bindTo(handler); if (PongMessage.class.isAssignableFrom(clazz)) @@ -405,7 +458,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { assertBasicTypeNotRegistered(OpCode.BINARY, this.binaryMetadata, handler.getClass().getName()); Decoder.Binary decoder = availableDecoders.getInstanceOf(registeredDecoder); - MessageSink messageSink = new DecodedBinaryMessageSink(session, decoder, wholeMsgMethodHandle); + MessageSink messageSink = new DecodedBinaryMessageSink(coreSession, decoder, wholeMsgMethodHandle); metadata.sinkClass = messageSink.getClass(); this.binarySink = registerMessageHandler(OpCode.BINARY, clazz, handler, messageSink); this.binaryMetadata = metadata; @@ -414,7 +467,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { assertBasicTypeNotRegistered(OpCode.BINARY, this.binaryMetadata, handler.getClass().getName()); Decoder.BinaryStream decoder = availableDecoders.getInstanceOf(registeredDecoder); - MessageSink messageSink = new DecodedBinaryStreamMessageSink(session, decoder, wholeMsgMethodHandle); + MessageSink messageSink = new DecodedBinaryStreamMessageSink(coreSession, decoder, wholeMsgMethodHandle); metadata.sinkClass = messageSink.getClass(); this.binarySink = registerMessageHandler(OpCode.BINARY, clazz, handler, messageSink); this.binaryMetadata = metadata; @@ -423,7 +476,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { assertBasicTypeNotRegistered(OpCode.TEXT, this.textMetadata, handler.getClass().getName()); Decoder.Text decoder = availableDecoders.getInstanceOf(registeredDecoder); - MessageSink messageSink = new DecodedTextMessageSink(session, decoder, wholeMsgMethodHandle); + MessageSink messageSink = new DecodedTextMessageSink(coreSession, decoder, wholeMsgMethodHandle); metadata.sinkClass = messageSink.getClass(); this.textSink = registerMessageHandler(OpCode.TEXT, clazz, handler, messageSink); this.textMetadata = metadata; @@ -432,7 +485,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler { assertBasicTypeNotRegistered(OpCode.TEXT, this.textMetadata, handler.getClass().getName()); Decoder.TextStream decoder = availableDecoders.getInstanceOf(registeredDecoder); - MessageSink messageSink = new DecodedTextStreamMessageSink(session, decoder, wholeMsgMethodHandle); + MessageSink messageSink = new DecodedTextStreamMessageSink(coreSession, decoder, wholeMsgMethodHandle); metadata.sinkClass = messageSink.getClass(); this.textSink = registerMessageHandler(OpCode.TEXT, clazz, handler, messageSink); this.textMetadata = metadata; @@ -538,20 +591,9 @@ public class JavaxWebSocketFrameHandler implements FrameHandler activeMessageSink = null; } - public void onClose(Frame frame, Callback callback) - { - callback.succeeded(); - } - public void onPing(Frame frame, Callback callback) { - ByteBuffer payload = BufferUtil.EMPTY_BUFFER; - - if (frame.hasPayload()) - { - payload = ByteBuffer.allocate(frame.getPayloadLength()); - BufferUtil.put(frame.getPayload(), payload); - } + ByteBuffer payload = BufferUtil.copy(frame.getPayload()); coreSession.sendFrame(new Frame(OpCode.PONG).setPayload(payload), Callback.NOOP, false); callback.succeeded(); } @@ -615,18 +657,33 @@ public class JavaxWebSocketFrameHandler implements FrameHandler this.upgradeRequest = upgradeRequest; } - public void setUpgradeResponse(UpgradeResponse upgradeResponse) - { - this.upgradeResponse = upgradeResponse; - } - public UpgradeRequest getUpgradeRequest() { return upgradeRequest; } - public UpgradeResponse getUpgradeResponse() + private void configListener(String key, Object value) { - return upgradeResponse; + if (!key.startsWith("org.eclipse.jetty.websocket.")) + return; + + switch (key) + { + case "org.eclipse.jetty.websocket.autoFragment": + coreSession.setAutoFragment((Boolean)value); + break; + + case "org.eclipse.jetty.websocket.maxFrameSize": + coreSession.setMaxFrameSize((Long)value); + break; + + case "org.eclipse.jetty.websocket.outputBufferSize": + coreSession.setOutputBufferSize((Integer)value); + break; + + case "org.eclipse.jetty.websocket.inputBufferSize": + coreSession.setInputBufferSize((Integer)value); + break; + } } } diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerFactory.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerFactory.java similarity index 51% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerFactory.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerFactory.java index 53b7c5f0846..5eeea251808 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerFactory.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -31,7 +31,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import javax.websocket.CloseReason; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; @@ -43,23 +43,26 @@ import javax.websocket.PongMessage; import javax.websocket.Session; import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; -import org.eclipse.jetty.websocket.javax.common.messages.ByteArrayMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.ByteBufferMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedBinaryMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedBinaryStreamMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedTextMessageSink; import org.eclipse.jetty.websocket.javax.common.messages.DecodedTextStreamMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.InputStreamMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.PartialByteArrayMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.PartialByteBufferMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.PartialStringMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.ReaderMessageSink; -import org.eclipse.jetty.websocket.javax.common.messages.StringMessageSink; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils; -import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.messages.ByteArrayMessageSink; +import org.eclipse.jetty.websocket.util.messages.ByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.InputStreamMessageSink; +import org.eclipse.jetty.websocket.util.messages.MessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialByteArrayMessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialStringMessageSink; +import org.eclipse.jetty.websocket.util.messages.ReaderMessageSink; +import org.eclipse.jetty.websocket.util.messages.StringMessageSink; import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerMetadata.MessageMetadata; @@ -68,12 +71,61 @@ public abstract class JavaxWebSocketFrameHandlerFactory { private static final MethodHandle FILTER_RETURN_TYPE_METHOD; + // The different kind of @OnMessage method parameter signatures expected. + private static final InvokerUtils.Arg[] textCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(String.class).required() + }; + + private static final InvokerUtils.Arg[] textPartialCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(String.class).required(), + new InvokerUtils.Arg(boolean.class).required() + }; + + private static final InvokerUtils.Arg[] binaryBufferCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(ByteBuffer.class).required() + }; + + private static final InvokerUtils.Arg[] binaryPartialBufferCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(ByteBuffer.class).required(), + new InvokerUtils.Arg(boolean.class).required() + }; + + private static final InvokerUtils.Arg[] binaryArrayCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(byte[].class).required() + }; + + private static final InvokerUtils.Arg[] binaryPartialArrayCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(byte[].class).required(), + new InvokerUtils.Arg(boolean.class).required() + }; + + private static final InvokerUtils.Arg[] inputStreamCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(InputStream.class).required() + }; + + private static final InvokerUtils.Arg[] readerCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(Reader.class).required() + }; + + private static final InvokerUtils.Arg[] pongCallingArgs = new InvokerUtils.Arg[]{ + new InvokerUtils.Arg(Session.class), + new InvokerUtils.Arg(PongMessage.class).required() + }; + static { try { - FILTER_RETURN_TYPE_METHOD = MethodHandles.lookup() - .findVirtual(JavaxWebSocketSession.class, "filterReturnType", MethodType.methodType(Void.TYPE, Object.class)); + FILTER_RETURN_TYPE_METHOD = getServerMethodHandleLookup() + .findVirtual(JavaxWebSocketSession.class, "filterReturnType", MethodType.methodType(void.class, Object.class)); } catch (Throwable e) { @@ -83,7 +135,6 @@ public abstract class JavaxWebSocketFrameHandlerFactory protected final JavaxWebSocketContainer container; protected final InvokerUtils.ParamIdentifier paramIdentifier; - private Map, JavaxWebSocketFrameHandlerMetadata> metadataMap = new ConcurrentHashMap<>(); public JavaxWebSocketFrameHandlerFactory(JavaxWebSocketContainer container, InvokerUtils.ParamIdentifier paramIdentifier) { @@ -91,20 +142,9 @@ public abstract class JavaxWebSocketFrameHandlerFactory this.paramIdentifier = paramIdentifier == null ? InvokerUtils.PARAM_IDENTITY : paramIdentifier; } - public JavaxWebSocketFrameHandlerMetadata getMetadata(Class endpointClass, EndpointConfig endpointConfig) - { - JavaxWebSocketFrameHandlerMetadata metadata = metadataMap.get(endpointClass); + public abstract JavaxWebSocketFrameHandlerMetadata getMetadata(Class endpointClass, EndpointConfig endpointConfig); - if (metadata == null) - { - metadata = createMetadata(endpointClass, endpointConfig); - metadataMap.put(endpointClass, metadata); - } - - return metadata; - } - - public abstract JavaxWebSocketFrameHandlerMetadata createMetadata(Class endpointClass, EndpointConfig endpointConfig); + public abstract EndpointConfig newDefaultEndpointConfig(Class endpointClass, String path); public JavaxWebSocketFrameHandler newJavaxWebSocketFrameHandler(Object endpointInstance, UpgradeRequest upgradeRequest) { @@ -120,7 +160,8 @@ public abstract class JavaxWebSocketFrameHandlerFactory else { endpoint = endpointInstance; - config = new BasicEndpointConfig(); + String path = (upgradeRequest.getRequestURI() == null) ? null : upgradeRequest.getRequestURI().getPath(); + config = newDefaultEndpointConfig(endpoint.getClass(), path); } JavaxWebSocketFrameHandlerMetadata metadata = getMetadata(endpoint.getClass(), config); @@ -158,15 +199,13 @@ public abstract class JavaxWebSocketFrameHandlerFactory errorHandle = InvokerUtils.bindTo(errorHandle, endpoint); pongHandle = InvokerUtils.bindTo(pongHandle, endpoint); - JavaxWebSocketFrameHandler frameHandler = new JavaxWebSocketFrameHandler( + return new JavaxWebSocketFrameHandler( container, endpoint, openHandle, closeHandle, errorHandle, textMetadata, binaryMetadata, pongHandle, config); - - return frameHandler; } /** @@ -283,18 +322,19 @@ public abstract class JavaxWebSocketFrameHandlerFactory try { + MethodHandles.Lookup lookup = getServerMethodHandleLookup(); if (DecodedMessageSink.class.isAssignableFrom(msgMetadata.sinkClass)) { - MethodHandle ctorHandle = MethodHandles.lookup().findConstructor(msgMetadata.sinkClass, - MethodType.methodType(void.class, JavaxWebSocketSession.class, msgMetadata.registeredDecoder.interfaceType, MethodHandle.class)); + MethodHandle ctorHandle = lookup.findConstructor(msgMetadata.sinkClass, + MethodType.methodType(void.class, CoreSession.class, msgMetadata.registeredDecoder.interfaceType, MethodHandle.class)); Decoder decoder = session.getDecoders().getInstanceOf(msgMetadata.registeredDecoder); - return (MessageSink)ctorHandle.invoke(session, decoder, msgMetadata.handle); + return (MessageSink)ctorHandle.invoke(session.getCoreSession(), decoder, msgMetadata.handle); } else { - MethodHandle ctorHandle = MethodHandles.lookup().findConstructor(msgMetadata.sinkClass, - MethodType.methodType(void.class, JavaxWebSocketSession.class, MethodHandle.class)); - return (MessageSink)ctorHandle.invoke(session, msgMetadata.handle); + MethodHandle ctorHandle = lookup.findConstructor(msgMetadata.sinkClass, + MethodType.methodType(void.class, CoreSession.class, MethodHandle.class)); + return (MessageSink)ctorHandle.invoke(session.getCoreSession(), msgMetadata.handle); } } catch (NoSuchMethodException e) @@ -315,7 +355,7 @@ public abstract class JavaxWebSocketFrameHandlerFactory } } - public static MethodHandle wrapNonVoidReturnType(MethodHandle handle, JavaxWebSocketSession session) throws NoSuchMethodException, IllegalAccessException + public static MethodHandle wrapNonVoidReturnType(MethodHandle handle, JavaxWebSocketSession session) { if (handle == null) return null; @@ -349,8 +389,7 @@ public abstract class JavaxWebSocketFrameHandlerFactory protected JavaxWebSocketFrameHandlerMetadata createEndpointMetadata(Class endpointClass, EndpointConfig endpointConfig) { JavaxWebSocketFrameHandlerMetadata metadata = new JavaxWebSocketFrameHandlerMetadata(endpointConfig); - - MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandles.Lookup lookup = getApplicationMethodHandleLookup(endpointClass); Method openMethod = ReflectUtils.findMethod(endpointClass, "onOpen", javax.websocket.Session.class, javax.websocket.EndpointConfig.class); @@ -372,6 +411,7 @@ public abstract class JavaxWebSocketFrameHandlerFactory protected JavaxWebSocketFrameHandlerMetadata discoverJavaxFrameHandlerMetadata(Class endpointClass, JavaxWebSocketFrameHandlerMetadata metadata) { + MethodHandles.Lookup lookup = getApplicationMethodHandleLookup(endpointClass); Method onmethod; // OnOpen [0..1] @@ -382,7 +422,7 @@ public abstract class JavaxWebSocketFrameHandlerFactory final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class); final InvokerUtils.Arg ENDPOINT_CONFIG = new InvokerUtils.Arg(EndpointConfig.class); MethodHandle methodHandle = InvokerUtils - .mutatedInvoker(endpointClass, onmethod, paramIdentifier, metadata.getNamedTemplateVariables(), SESSION, ENDPOINT_CONFIG); + .mutatedInvoker(lookup, endpointClass, onmethod, paramIdentifier, metadata.getNamedTemplateVariables(), SESSION, ENDPOINT_CONFIG); metadata.setOpenHandler(methodHandle, onmethod); } @@ -394,9 +434,10 @@ public abstract class JavaxWebSocketFrameHandlerFactory final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class); final InvokerUtils.Arg CLOSE_REASON = new InvokerUtils.Arg(CloseReason.class); MethodHandle methodHandle = InvokerUtils - .mutatedInvoker(endpointClass, onmethod, paramIdentifier, metadata.getNamedTemplateVariables(), SESSION, CLOSE_REASON); + .mutatedInvoker(lookup, endpointClass, onmethod, paramIdentifier, metadata.getNamedTemplateVariables(), SESSION, CLOSE_REASON); metadata.setCloseHandler(methodHandle, onmethod); } + // OnError [0..1] onmethod = ReflectUtils.findAnnotatedMethod(endpointClass, OnError.class); if (onmethod != null) @@ -405,7 +446,7 @@ public abstract class JavaxWebSocketFrameHandlerFactory final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class); final InvokerUtils.Arg CAUSE = new InvokerUtils.Arg(Throwable.class).required(); MethodHandle methodHandle = InvokerUtils - .mutatedInvoker(endpointClass, onmethod, paramIdentifier, metadata.getNamedTemplateVariables(), SESSION, CAUSE); + .mutatedInvoker(lookup, endpointClass, onmethod, paramIdentifier, metadata.getNamedTemplateVariables(), SESSION, CAUSE); metadata.setErrorHandler(methodHandle, onmethod); } @@ -413,293 +454,32 @@ public abstract class JavaxWebSocketFrameHandlerFactory Method[] onMessages = ReflectUtils.findAnnotatedMethods(endpointClass, OnMessage.class); if (onMessages != null && onMessages.length > 0) { - // The different kind of @OnMessage method parameter signatures expected - InvokerUtils.Arg[] textCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(String.class).required() - }; - - InvokerUtils.Arg[] textPartialCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(String.class).required(), - new InvokerUtils.Arg(boolean.class).required() - }; - - InvokerUtils.Arg[] binaryBufferCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(ByteBuffer.class).required() - }; - - InvokerUtils.Arg[] binaryPartialBufferCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(ByteBuffer.class).required(), - new InvokerUtils.Arg(boolean.class).required() - }; - - InvokerUtils.Arg[] binaryArrayCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(byte[].class).required() - }; - - InvokerUtils.Arg[] binaryPartialArrayCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(byte[].class).required(), - new InvokerUtils.Arg(boolean.class).required() - }; - - InvokerUtils.Arg[] inputStreamCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(InputStream.class).required() - }; - - InvokerUtils.Arg[] readerCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(Reader.class).required() - }; - - InvokerUtils.Arg[] pongCallingArgs = new InvokerUtils.Arg[]{ - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(PongMessage.class).required() - }; - - List decodedTextCallingArgs = new ArrayList<>(); - List decodedTextStreamCallingArgs = new ArrayList<>(); - List decodedBinaryCallingArgs = new ArrayList<>(); - List decodedBinaryStreamCallingArgs = new ArrayList<>(); - - for (AvailableDecoders.RegisteredDecoder decoder : metadata.getAvailableDecoders()) - { - if (decoder.implementsInterface(Decoder.Text.class)) - { - decodedTextCallingArgs.add( - new DecodedArgs(decoder, - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(decoder.objectType).required() - )); - } - - if (decoder.implementsInterface(Decoder.TextStream.class)) - { - decodedTextStreamCallingArgs.add( - new DecodedArgs(decoder, - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(decoder.objectType).required() - )); - } - - if (decoder.implementsInterface(Decoder.Binary.class)) - { - decodedBinaryCallingArgs.add( - new DecodedArgs(decoder, - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(decoder.objectType).required() - )); - } - - if (decoder.implementsInterface(Decoder.BinaryStream.class)) - { - decodedBinaryStreamCallingArgs.add( - new DecodedArgs(decoder, - new InvokerUtils.Arg(Session.class), - new InvokerUtils.Arg(decoder.objectType).required() - )); - } - } - - onmessageloop: for (Method onMsg : onMessages) { assertSignatureValid(endpointClass, onMsg, OnMessage.class); - OnMessage onMessageAnno = onMsg.getAnnotation(OnMessage.class); MessageMetadata msgMetadata = new MessageMetadata(); + OnMessage onMessageAnno = onMsg.getAnnotation(OnMessage.class); if (onMessageAnno.maxMessageSize() > Integer.MAX_VALUE) { - throw new InvalidWebSocketException( - String.format("Value too large: %s#%s - @OnMessage.maxMessageSize=%,d > Integer.MAX_VALUE", + throw new InvalidWebSocketException(String.format("Value too large: %s#%s - @OnMessage.maxMessageSize=%,d > Integer.MAX_VALUE", endpointClass.getName(), onMsg.getName(), onMessageAnno.maxMessageSize())); } msgMetadata.maxMessageSize = (int)onMessageAnno.maxMessageSize(); - MethodHandle methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), textCallingArgs); - if (methodHandle != null) - { - // Whole Text Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = StringMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setTextMetadata(msgMetadata, onMsg); - continue onmessageloop; - } + // Function to search for matching MethodHandle for the endpointClass given a signature. + Function getMethodHandle = (signature) -> + InvokerUtils.optionalMutatedInvoker(lookup, endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), signature); - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), textPartialCallingArgs); - if (methodHandle != null) - { - // Partial Text Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = PartialStringMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setTextMetadata(msgMetadata, onMsg); - continue onmessageloop; - } + // Try to match from available decoders. + if (matchDecoders(onMsg, metadata, msgMetadata, getMethodHandle)) + continue; - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), binaryBufferCallingArgs); - if (methodHandle != null) - { - // Whole ByteBuffer Binary Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = ByteBufferMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } + // No decoders matched try basic signatures to call onMessage directly. + if (matchOnMessage(onMsg, metadata, msgMetadata, getMethodHandle)) + continue; - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), binaryPartialBufferCallingArgs); - if (methodHandle != null) - { - // Partial ByteBuffer Binary Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = PartialByteBufferMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), binaryArrayCallingArgs); - if (methodHandle != null) - { - // Whole byte[] Binary Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = ByteArrayMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), binaryPartialArrayCallingArgs); - if (methodHandle != null) - { - // Partial byte[] Binary Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = PartialByteArrayMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), inputStreamCallingArgs); - if (methodHandle != null) - { - // InputStream Binary Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = InputStreamMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), readerCallingArgs); - if (methodHandle != null) - { - // Reader Text Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = ReaderMessageSink.class; - msgMetadata.handle = methodHandle; - metadata.setTextMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - - // == Decoders == - - // Decoder.Text - for (DecodedArgs decodedArgs : decodedTextCallingArgs) - { - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), decodedArgs.args); - if (methodHandle != null) - { - // Decoded Text Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = DecodedTextMessageSink.class; - msgMetadata.handle = methodHandle; - msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; - metadata.setTextMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - } - - // Decoder.Binary - for (DecodedArgs decodedArgs : decodedBinaryCallingArgs) - { - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), decodedArgs.args); - if (methodHandle != null) - { - // Decoded Binary Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = DecodedBinaryMessageSink.class; - msgMetadata.handle = methodHandle; - msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - } - - // Decoder.TextStream - for (DecodedArgs decodedArgs : decodedTextStreamCallingArgs) - { - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), decodedArgs.args); - if (methodHandle != null) - { - // Decoded Text Stream - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = DecodedTextStreamMessageSink.class; - msgMetadata.handle = methodHandle; - msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; - metadata.setTextMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - } - - // Decoder.BinaryStream - for (DecodedArgs decodedArgs : decodedBinaryStreamCallingArgs) - { - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), decodedArgs.args); - if (methodHandle != null) - { - // Decoded Binary Stream - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - msgMetadata.sinkClass = DecodedBinaryStreamMessageSink.class; - msgMetadata.handle = methodHandle; - msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; - metadata.setBinaryMetadata(msgMetadata, onMsg); - continue onmessageloop; - } - } - - // == Pong == - - methodHandle = InvokerUtils - .optionalMutatedInvoker(endpointClass, onMsg, paramIdentifier, metadata.getNamedTemplateVariables(), pongCallingArgs); - if (methodHandle != null) - { - // Pong Message - assertSignatureValid(endpointClass, onMsg, OnMessage.class); - metadata.setPongHandle(methodHandle, onMsg); - continue onmessageloop; - } - - // Not a valid @OnMessage declaration signature + // Not a valid @OnMessage declaration signature. throw InvalidSignatureException.build(endpointClass, OnMessage.class, onMsg); } } @@ -707,6 +487,184 @@ public abstract class JavaxWebSocketFrameHandlerFactory return metadata; } + private boolean matchOnMessage(Method onMsg, JavaxWebSocketFrameHandlerMetadata metadata, MessageMetadata msgMetadata, + Function getMethodHandle) + { + // Whole Text Message. + MethodHandle methodHandle = getMethodHandle.apply(textCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = StringMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setTextMetadata(msgMetadata, onMsg); + return true; + } + + // Partial Text Message. + methodHandle = getMethodHandle.apply(textPartialCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = PartialStringMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setTextMetadata(msgMetadata, onMsg); + return true; + } + + // Whole ByteBuffer Binary Message. + methodHandle = getMethodHandle.apply(binaryBufferCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = ByteBufferMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + + // Partial ByteBuffer Binary Message. + methodHandle = getMethodHandle.apply(binaryPartialBufferCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = PartialByteBufferMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + + // Whole byte[] Binary Message. + methodHandle = getMethodHandle.apply(binaryArrayCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = ByteArrayMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + + // Partial byte[] Binary Message. + methodHandle = getMethodHandle.apply(binaryPartialArrayCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = PartialByteArrayMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + + // InputStream Binary Message. + methodHandle = getMethodHandle.apply(inputStreamCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = InputStreamMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + + // Reader Text Message. + methodHandle = getMethodHandle.apply(readerCallingArgs); + if (methodHandle != null) + { + msgMetadata.sinkClass = ReaderMessageSink.class; + msgMetadata.handle = methodHandle; + metadata.setTextMetadata(msgMetadata, onMsg); + return true; + } + + // Pong Message. + MethodHandle pongHandle = getMethodHandle.apply(pongCallingArgs); + if (pongHandle != null) + { + metadata.setPongHandle(pongHandle, onMsg); + return true; + } + + return false; + } + + private boolean matchDecoders(Method onMsg, JavaxWebSocketFrameHandlerMetadata metadata, MessageMetadata msgMetadata, + Function getMethodHandle) + { + // TODO: we should be able to get this information directly from the AvailableDecoders in the metadata. + List decodedTextCallingArgs = new ArrayList<>(); + List decodedTextStreamCallingArgs = new ArrayList<>(); + List decodedBinaryCallingArgs = new ArrayList<>(); + List decodedBinaryStreamCallingArgs = new ArrayList<>(); + for (AvailableDecoders.RegisteredDecoder decoder : metadata.getAvailableDecoders()) + { + InvokerUtils.Arg[] args = {new InvokerUtils.Arg(Session.class), new InvokerUtils.Arg(decoder.objectType).required()}; + DecodedArgs decodedArgs = new DecodedArgs(decoder, args); + + if (decoder.implementsInterface(Decoder.Text.class)) + decodedTextCallingArgs.add(decodedArgs); + if (decoder.implementsInterface(Decoder.TextStream.class)) + decodedTextStreamCallingArgs.add(decodedArgs); + if (decoder.implementsInterface(Decoder.Binary.class)) + decodedBinaryCallingArgs.add(decodedArgs); + if (decoder.implementsInterface(Decoder.BinaryStream.class)) + decodedBinaryStreamCallingArgs.add(decodedArgs); + } + + MethodHandle methodHandle; + + // Decoder.Text + for (DecodedArgs decodedArgs : decodedTextCallingArgs) + { + methodHandle = getMethodHandle.apply(decodedArgs.args); + if (methodHandle != null) + { + msgMetadata.sinkClass = DecodedTextMessageSink.class; + msgMetadata.handle = methodHandle; + msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; + metadata.setTextMetadata(msgMetadata, onMsg); + return true; + } + } + + // Decoder.Binary + for (DecodedArgs decodedArgs : decodedBinaryCallingArgs) + { + methodHandle = getMethodHandle.apply(decodedArgs.args); + if (methodHandle != null) + { + msgMetadata.sinkClass = DecodedBinaryMessageSink.class; + msgMetadata.handle = methodHandle; + msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + } + + // Try to match Text Stream decoders. + for (DecodedArgs decodedArgs : decodedTextStreamCallingArgs) + { + methodHandle = getMethodHandle.apply(decodedArgs.args); + if (methodHandle != null) + { + msgMetadata.sinkClass = DecodedTextStreamMessageSink.class; + msgMetadata.handle = methodHandle; + msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; + metadata.setTextMetadata(msgMetadata, onMsg); + return true; + } + } + + // Decoder.BinaryStream + for (DecodedArgs decodedArgs : decodedBinaryStreamCallingArgs) + { + methodHandle = getMethodHandle.apply(decodedArgs.args); + if (methodHandle != null) + { + msgMetadata.sinkClass = DecodedBinaryStreamMessageSink.class; + msgMetadata.handle = methodHandle; + msgMetadata.registeredDecoder = decodedArgs.registeredDecoder; + metadata.setBinaryMetadata(msgMetadata, onMsg); + return true; + } + } + + return false; + } + private void assertSignatureValid(Class endpointClass, Method method, Class annotationClass) { // Test modifiers @@ -747,6 +705,55 @@ public abstract class JavaxWebSocketFrameHandlerFactory } } + /** + *

      + * Gives a {@link MethodHandles.Lookup} instance to be used to find methods in server classes. + * For lookups on application classes use {@link #getApplicationMethodHandleLookup(Class)} instead. + *

      + *

      + * This uses the caller sensitive {@link MethodHandles#lookup()}, this will allow MethodHandle access + * to server classes we need to use and will give access permissions to private methods as well. + *

      + * + * @return a lookup object to be used to find methods on server classes. + */ + public static MethodHandles.Lookup getServerMethodHandleLookup() + { + return MethodHandles.lookup(); + } + + /** + *

      + * Gives a {@link MethodHandles.Lookup} instance to be used to find public methods in application classes. + * For lookups on server classes use {@link #getServerMethodHandleLookup()} instead. + *

      + *

      + * This uses {@link MethodHandles#publicLookup()} as we only need access to public method of the lookupClass. + * To look up a method on the lookupClass, it must be public and the class must be accessible from this + * module, so if the lookupClass is in a JPMS module it must be exported so that the public methods + * of the lookupClass are accessible outside of the module. + *

      + *

      + * The {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} allows us to search specifically + * in the endpoint Class to avoid any potential linkage errors which could occur if the same + * class is present in multiple web apps. Unlike using {@link MethodHandles#publicLookup()} + * using {@link MethodHandles#lookup()} with {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} + * will cause the lookup to lose its public access to the lookup class if they are in different modules. + *

      + *

      + * {@link MethodHandles#privateLookupIn(Class, MethodHandles.Lookup)} is also unsuitable because it + * requires the caller module to read the target module, and the target module to open reflective + * access to the lookupClasses private methods. This is possible but requires extra configuration + * to provide private access which is not necessary for the purpose of accessing the public methods. + *

      + * @param lookupClass the desired lookup class for the new lookup object. + * @return a lookup object to be used to find methods on the lookupClass. + */ + public static MethodHandles.Lookup getApplicationMethodHandleLookup(Class lookupClass) + { + return MethodHandles.publicLookup().in(lookupClass); + } + private static class DecodedArgs { public final AvailableDecoders.RegisteredDecoder registeredDecoder; diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java similarity index 85% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java index 528e5be5407..b5db28e9969 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerMetadata.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -26,17 +26,11 @@ import javax.websocket.EndpointConfig; import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; +import org.eclipse.jetty.websocket.util.messages.MessageSink; public class JavaxWebSocketFrameHandlerMetadata { - /** - * Constant for "unset" @OnMessage annotation values. - *

      - * (-2 means unset/undeclared, -1 means whatever that value means, such as: no idletimeout, or no maximum message size limit) - *

      - */ - public static final int UNSET = -2; - private static final String[] NO_VARIABLES = new String[0]; // EndpointConfig entries @@ -228,6 +222,8 @@ public class JavaxWebSocketFrameHandlerMetadata public static class MessageMetadata { + private static final int UNSET = -1; + public MethodHandle handle; public Class sinkClass; public AvailableDecoders.RegisteredDecoder registeredDecoder; @@ -249,7 +245,7 @@ public class JavaxWebSocketFrameHandlerMetadata public boolean isMaxMessageSizeSet() { - return (maxMessageSize != UNSET) && (maxMessageSize != 0); + return maxMessageSize != UNSET; } } } diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketPongMessage.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketPongMessage.java new file mode 100644 index 00000000000..a0d85b7129c --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketPongMessage.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.nio.ByteBuffer; +import javax.websocket.PongMessage; + +import org.eclipse.jetty.util.BufferUtil; + +public class JavaxWebSocketPongMessage implements PongMessage +{ + private final ByteBuffer data; + + public JavaxWebSocketPongMessage(ByteBuffer buf) + { + this.data = buf; + } + + @Override + public ByteBuffer getApplicationData() + { + if (data == null) + { + return BufferUtil.EMPTY_BUFFER; + } + return data.slice(); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketRemoteEndpoint.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketRemoteEndpoint.java similarity index 73% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketRemoteEndpoint.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketRemoteEndpoint.java index d02b27459fa..82c23d3bb3e 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketRemoteEndpoint.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketRemoteEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -21,33 +21,34 @@ package org.eclipse.jetty.websocket.javax.common; import java.io.IOException; import java.nio.ByteBuffer; import java.time.Duration; +import java.util.concurrent.TimeUnit; import javax.websocket.EncodeException; import javax.websocket.Encoder; import javax.websocket.SendHandler; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.OutgoingFrames; -import org.eclipse.jetty.websocket.core.WebSocketException; -import org.eclipse.jetty.websocket.javax.common.messages.MessageOutputStream; -import org.eclipse.jetty.websocket.javax.common.messages.MessageWriter; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.eclipse.jetty.websocket.util.messages.MessageOutputStream; +import org.eclipse.jetty.websocket.util.messages.MessageWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JavaxWebSocketRemoteEndpoint implements javax.websocket.RemoteEndpoint, OutgoingFrames { - private static final Logger LOG = Log.getLogger(JavaxWebSocketRemoteEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketRemoteEndpoint.class); protected final JavaxWebSocketSession session; - private final FrameHandler.CoreSession coreSession; + private final CoreSession coreSession; protected boolean batch = false; protected byte messageType = -1; - protected JavaxWebSocketRemoteEndpoint(JavaxWebSocketSession session, FrameHandler.CoreSession coreSession) + protected JavaxWebSocketRemoteEndpoint(JavaxWebSocketSession session, CoreSession coreSession) { this.session = session; this.coreSession = coreSession; @@ -55,21 +56,20 @@ public class JavaxWebSocketRemoteEndpoint implements javax.websocket.RemoteEndpo protected MessageWriter newMessageWriter() { - return new MessageWriter(coreSession, coreSession.getOutputBufferSize()); + return new MessageWriter(coreSession, session.getContainerImpl().getBufferPool()); } protected MessageOutputStream newMessageOutputStream() { - return new MessageOutputStream(coreSession, coreSession.getOutputBufferSize(), session.getContainerImpl().getBufferPool()); + return new MessageOutputStream(coreSession, session.getContainerImpl().getBufferPool()); } @Override public void flushBatch() throws IOException { - try (SharedBlockingCallback.Blocker blocker = session.getBlocking().acquire()) - { - coreSession.flush(blocker); - } + FutureCallback b = new FutureCallback(); + coreSession.flush(b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } @Override @@ -227,24 +227,22 @@ public class JavaxWebSocketRemoteEndpoint implements javax.websocket.RemoteEndpo public void sendPing(ByteBuffer data) throws IOException, IllegalArgumentException { if (LOG.isDebugEnabled()) - { LOG.debug("sendPing({})", BufferUtil.toDetailString(data)); - } - // TODO: is this supposed to be a blocking call? - // TODO: what to do on excessively large payloads (error and close connection per RFC6455, or truncate?) - sendFrame(new Frame(OpCode.PING).setPayload(data), Callback.NOOP, batch); + + FutureCallback b = new FutureCallback(); + sendFrame(new Frame(OpCode.PING).setPayload(data), b, batch); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } @Override public void sendPong(ByteBuffer data) throws IOException, IllegalArgumentException { if (LOG.isDebugEnabled()) - { LOG.debug("sendPong({})", BufferUtil.toDetailString(data)); - } - // TODO: is this supposed to be a blocking call? - // TODO: what to do on excessively large payloads (error and close connection per RFC6455, or truncate?) - sendFrame(new Frame(OpCode.PONG).setPayload(data), Callback.NOOP, batch); + + FutureCallback b = new FutureCallback(); + sendFrame(new Frame(OpCode.PONG).setPayload(data), b, batch); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } protected void assertMessageNotNull(Object data) @@ -262,4 +260,10 @@ public class JavaxWebSocketRemoteEndpoint implements javax.websocket.RemoteEndpo throw new IllegalArgumentException("SendHandler cannot be null"); } } + + private long getBlockingTimeout() + { + long idleTimeout = getIdleTimeout(); + return (idleTimeout > 0) ? idleTimeout + 1000 : idleTimeout; + } } diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java similarity index 83% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java index af9aa1a6bc9..9cbe7d6056d 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import javax.websocket.CloseReason; import javax.websocket.EndpointConfig; @@ -38,28 +39,24 @@ import javax.websocket.RemoteEndpoint.Basic; import javax.websocket.Session; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders; -import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Client Session for the JSR. */ -public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.websocket.Session +public class JavaxWebSocketSession implements javax.websocket.Session { - private static final Logger LOG = Log.getLogger(JavaxWebSocketSession.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketSession.class); - protected final SharedBlockingCallback blocking = new SharedBlockingCallback(); private final JavaxWebSocketContainer container; - private final FrameHandler.CoreSession coreSession; + private final CoreSession coreSession; private final JavaxWebSocketFrameHandler frameHandler; private final EndpointConfig config; private final AvailableDecoders availableDecoders; @@ -72,15 +69,14 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we private JavaxWebSocketBasicRemote basicRemote; public JavaxWebSocketSession(JavaxWebSocketContainer container, - FrameHandler.CoreSession coreSession, + CoreSession coreSession, JavaxWebSocketFrameHandler frameHandler, EndpointConfig endpointConfig) { this.container = container; this.coreSession = coreSession; this.frameHandler = frameHandler; - - this.config = endpointConfig == null ? new BasicEndpointConfig() : endpointConfig; + this.config = Objects.requireNonNull(endpointConfig); this.availableDecoders = new AvailableDecoders(this.config); this.availableEncoders = new AvailableEncoders(this.config); @@ -95,7 +91,12 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we this.pathParameters = Collections.emptyMap(); } - this.userProperties = new HashMap<>(this.config.getUserProperties()); + this.userProperties = this.config.getUserProperties(); + } + + public CoreSession getCoreSession() + { + return coreSession; } /** @@ -176,12 +177,9 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we * @since JSR356 v1.0 */ @Override - public void close() throws IOException + public void close() { - try (SharedBlockingCallback.Blocker blocker = blocking.acquire()) - { - coreSession.close(blocker); - } + close(new CloseReason(CloseReason.CloseCodes.NO_STATUS_CODE, null)); } /** @@ -191,12 +189,24 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we * @since JSR356 v1.0 */ @Override - public void close(CloseReason closeReason) throws IOException + public void close(CloseReason closeReason) { - try (SharedBlockingCallback.Blocker blocker = blocking.acquire()) + try { - coreSession.close(closeReason.getCloseCode().getCode(), closeReason.getReasonPhrase(), blocker); + FutureCallback b = new FutureCallback(); + coreSession.close(closeReason.getCloseCode().getCode(), closeReason.getReasonPhrase(), b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } + catch (IOException e) + { + LOG.trace("IGNORED", e); + } + } + + private long getBlockingTimeout() + { + long idleTimeout = getMaxIdleTimeout(); + return (idleTimeout > 0) ? idleTimeout + 1000 : idleTimeout; } /** @@ -291,6 +301,11 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we return frameHandler; } + public void abort() + { + coreSession.abort(); + } + /** * {@inheritDoc} * @@ -547,25 +562,6 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we return coreSession.isSecure(); } - @Override - protected void doStop() - { - coreSession.close(CloseStatus.SHUTDOWN, "Container being shut down", new Callback() - { - @Override - public void succeeded() - { - coreSession.abort(); - } - - @Override - public void failed(Throwable x) - { - coreSession.abort(); - } - }); - } - @Override public synchronized void removeMessageHandler(MessageHandler handler) { @@ -578,9 +574,4 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we return String.format("%s@%x[%s,%s]", this.getClass().getSimpleName(), this.hashCode(), coreSession.getBehavior(), frameHandler); } - - protected SharedBlockingCallback getBlocking() - { - return blocking; - } } diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSessionListener.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSessionListener.java new file mode 100644 index 00000000000..6538fcd5a60 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSessionListener.java @@ -0,0 +1,26 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +public interface JavaxWebSocketSessionListener +{ + void onJavaxWebSocketSessionOpened(JavaxWebSocketSession session); + + void onJavaxWebSocketSessionClosed(JavaxWebSocketSession session); +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PathParamProvider.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PathParamProvider.java new file mode 100644 index 00000000000..cdda746079b --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PathParamProvider.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.util.Map; + +/** + * Optional interface for custom {@link javax.websocket.EndpointConfig} implementations + * in Jetty to expose Path Param values used during the {@link JavaxWebSocketFrameHandler} + * resolution of methods. + *

      + * Mostly a feature of the JSR356 Server implementation and its {@code @javax.websocket.server.PathParam} annotation. + *

      + */ +public interface PathParamProvider +{ + Map getPathParams(); +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PutListenerMap.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PutListenerMap.java new file mode 100644 index 00000000000..54c2bb2ddcb --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/PutListenerMap.java @@ -0,0 +1,118 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; + +public class PutListenerMap implements Map +{ + private Map map; + private BiConsumer listener; + + public PutListenerMap(Map map, BiConsumer listener) + { + this.map = map; + this.listener = listener; + + // Notify listener for any existing entries in the Map. + for (Map.Entry entry : map.entrySet()) + { + listener.accept(entry.getKey(), entry.getValue()); + } + } + + @Override + public int size() + { + return map.size(); + } + + @Override + public boolean isEmpty() + { + return map.isEmpty(); + } + + @Override + public boolean containsKey(Object key) + { + return map.containsKey(key); + } + + @Override + public boolean containsValue(Object value) + { + return map.containsValue(value); + } + + @Override + public Object get(Object key) + { + return map.get(key); + } + + @Override + public Object put(String key, Object value) + { + listener.accept(key, value); + return map.put(key, value); + } + + @Override + public Object remove(Object key) + { + return map.remove(key); + } + + @Override + public void putAll(Map m) + { + for (Map.Entry entry : map.entrySet()) + { + put(entry.getKey(), entry.getValue()); + } + } + + @Override + public void clear() + { + map.clear(); + } + + @Override + public Set keySet() + { + return map.keySet(); + } + + @Override + public Collection values() + { + return map.values(); + } + + @Override + public Set> entrySet() + { + return map.entrySet(); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/RegisteredMessageHandler.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/RegisteredMessageHandler.java similarity index 50% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/RegisteredMessageHandler.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/RegisteredMessageHandler.java index 33a34304760..467473cf197 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/RegisteredMessageHandler.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/RegisteredMessageHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SendHandlerCallback.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SendHandlerCallback.java new file mode 100644 index 00000000000..b5572392002 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SendHandlerCallback.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import javax.websocket.SendHandler; +import javax.websocket.SendResult; + +import org.eclipse.jetty.util.Callback; + +/** + * Wrapper of user provided {@link SendHandler} to Jetty internal {@link Callback} + */ +public class SendHandlerCallback implements Callback +{ + private final SendHandler sendHandler; + + public SendHandlerCallback(SendHandler sendHandler) + { + this.sendHandler = sendHandler; + } + + @Override + public void failed(Throwable x) + { + sendHandler.onResult(new SendResult(x)); + } + + @Override + public void succeeded() + { + sendHandler.onResult(new SendResult()); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ServerEndpointConfigWrapper.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ServerEndpointConfigWrapper.java new file mode 100644 index 00000000000..66ef7a2ba53 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/ServerEndpointConfigWrapper.java @@ -0,0 +1,73 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.util.List; +import javax.websocket.Extension; +import javax.websocket.server.ServerEndpointConfig; + +public class ServerEndpointConfigWrapper extends EndpointConfigWrapper implements ServerEndpointConfig +{ + private ServerEndpointConfig _endpointConfig; + + public ServerEndpointConfigWrapper() + { + } + + public ServerEndpointConfigWrapper(ServerEndpointConfig endpointConfig) + { + init(endpointConfig); + } + + public void init(ServerEndpointConfig endpointConfig) + { + _endpointConfig = endpointConfig; + super.init(endpointConfig); + } + + @Override + public Class getEndpointClass() + { + return _endpointConfig.getEndpointClass(); + } + + @Override + public String getPath() + { + return _endpointConfig.getPath(); + } + + @Override + public List getSubprotocols() + { + return _endpointConfig.getSubprotocols(); + } + + @Override + public List getExtensions() + { + return _endpointConfig.getExtensions(); + } + + @Override + public Configurator getConfigurator() + { + return _endpointConfig.getConfigurator(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java new file mode 100644 index 00000000000..6010f9bae72 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java @@ -0,0 +1,73 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import javax.websocket.CloseReason; +import javax.websocket.Session; + +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SessionTracker extends AbstractLifeCycle implements JavaxWebSocketSessionListener +{ + private static final Logger LOG = LoggerFactory.getLogger(SessionTracker.class); + + private CopyOnWriteArraySet sessions = new CopyOnWriteArraySet<>(); + + public Set getSessions() + { + return Collections.unmodifiableSet(sessions); + } + + @Override + public void onJavaxWebSocketSessionOpened(JavaxWebSocketSession session) + { + sessions.add(session); + } + + @Override + public void onJavaxWebSocketSessionClosed(JavaxWebSocketSession session) + { + sessions.remove(session); + } + + @Override + protected void doStop() throws Exception + { + for (Session session : sessions) + { + try + { + // GOING_AWAY is abnormal close status so it will hard close connection after sent. + session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "Container being shut down")); + } + catch (IOException e) + { + LOG.trace("IGNORED", e); + } + } + + super.doStop(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequest.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequest.java new file mode 100644 index 00000000000..90de5c9c492 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequest.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.net.URI; +import java.security.Principal; + +public interface UpgradeRequest +{ + /** + * For {@link javax.websocket.Session#getUserPrincipal()} + * + * @return the User {@link Principal} present during the Upgrade Request + */ + Principal getUserPrincipal(); + + /** + * For obtaining {@link javax.websocket.server.PathParam} values from Request URI path + * + * @return the request URI + */ + URI getRequestURI(); +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequestAdapter.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequestAdapter.java new file mode 100644 index 00000000000..4ab2345d669 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/UpgradeRequestAdapter.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.net.URI; +import java.security.Principal; + +public class UpgradeRequestAdapter implements UpgradeRequest +{ + private final URI requestURI; + + public UpgradeRequestAdapter() + { + /* anonymous, no requestURI, upgrade request */ + this(null); + } + + public UpgradeRequestAdapter(URI uri) + { + this.requestURI = uri; + } + + @Override + public Principal getUserPrincipal() + { + return null; + } + + @Override + public URI getRequestURI() + { + return requestURI; + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AbstractDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AbstractDecoder.java new file mode 100644 index 00000000000..3864b49153e --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AbstractDecoder.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +public abstract class AbstractDecoder implements Decoder +{ + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java similarity index 91% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java index 21842420af8..51703c57824 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/AvailableDecoders.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; @@ -32,9 +32,9 @@ import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import org.eclipse.jetty.websocket.javax.common.InitException; -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; -import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; +import org.eclipse.jetty.websocket.util.ReflectUtils; public class AvailableDecoders implements Iterable { diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/BooleanDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/BooleanDecoder.java new file mode 100644 index 00000000000..89e3f69ab44 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/BooleanDecoder.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; + +/** + * Default implementation of the {@link javax.websocket.Decoder.Text} Message to {@link Boolean} decoder. + *

      + * Note: delegates to {@link Boolean#parseBoolean(String)} and will only support "true" and "false" as boolean values. + */ +public class BooleanDecoder extends AbstractDecoder implements Decoder.Text +{ + public static final BooleanDecoder INSTANCE = new BooleanDecoder(); + + @Override + public Boolean decode(String s) throws DecodeException + { + return Boolean.parseBoolean(s); + } + + @Override + public boolean willDecode(String s) + { + return (s != null); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteArrayDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteArrayDecoder.java new file mode 100644 index 00000000000..d1649fe58b1 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteArrayDecoder.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import java.nio.ByteBuffer; +import javax.websocket.DecodeException; +import javax.websocket.Decoder; + +import org.eclipse.jetty.util.BufferUtil; + +public class ByteArrayDecoder extends AbstractDecoder implements Decoder.Binary +{ + public static final ByteArrayDecoder INSTANCE = new ByteArrayDecoder(); + + @Override + public byte[] decode(ByteBuffer bytes) throws DecodeException + { + return BufferUtil.toArray(bytes); + } + + @Override + public boolean willDecode(ByteBuffer bytes) + { + return true; + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteBufferDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteBufferDecoder.java new file mode 100644 index 00000000000..ca50a9ae52f --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteBufferDecoder.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import java.nio.ByteBuffer; +import javax.websocket.DecodeException; +import javax.websocket.Decoder; + +public class ByteBufferDecoder extends AbstractDecoder implements Decoder.Binary +{ + public static final ByteBufferDecoder INSTANCE = new ByteBufferDecoder(); + + @Override + public ByteBuffer decode(ByteBuffer bytes) throws DecodeException + { + return bytes; + } + + @Override + public boolean willDecode(ByteBuffer bytes) + { + return true; + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteDecoder.java similarity index 56% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteDecoder.java index 14e89e227d5..4ec72361739 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ByteDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/CharacterDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/CharacterDecoder.java similarity index 51% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/CharacterDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/CharacterDecoder.java index 580b0fe3cfe..d5a4ed201b3 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/CharacterDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/CharacterDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/DoubleDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/DoubleDecoder.java similarity index 56% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/DoubleDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/DoubleDecoder.java index fedb3626ef9..7f376a2f365 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/DoubleDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/DoubleDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/FloatDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/FloatDecoder.java similarity index 59% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/FloatDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/FloatDecoder.java index e17d85361d4..e2719c2e742 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/FloatDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/FloatDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/InputStreamDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/InputStreamDecoder.java new file mode 100644 index 00000000000..9051fcdd76a --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/InputStreamDecoder.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import java.io.IOException; +import java.io.InputStream; +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +public class InputStreamDecoder implements Decoder.BinaryStream +{ + @Override + public InputStream decode(InputStream is) throws DecodeException, IOException + { + return is; + } + + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/IntegerDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/IntegerDecoder.java similarity index 56% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/IntegerDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/IntegerDecoder.java index bd2b09784c4..f728dd7cc99 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/IntegerDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/IntegerDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/LongDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/LongDecoder.java similarity index 55% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/LongDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/LongDecoder.java index c27fc53a672..68bf205daa5 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/LongDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/LongDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/PongMessageDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/PongMessageDecoder.java similarity index 57% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/PongMessageDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/PongMessageDecoder.java index c60138087bd..f87edd84bf2 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/PongMessageDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/PongMessageDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ReaderDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ReaderDecoder.java new file mode 100644 index 00000000000..fa685f1f705 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ReaderDecoder.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import java.io.IOException; +import java.io.Reader; +import javax.websocket.DecodeException; +import javax.websocket.Decoder; +import javax.websocket.EndpointConfig; + +public class ReaderDecoder implements Decoder.TextStream +{ + @Override + public Reader decode(Reader reader) throws DecodeException, IOException + { + return reader; + } + + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ShortDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ShortDecoder.java similarity index 56% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ShortDecoder.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ShortDecoder.java index 73e68e98f47..fd7a62f22d3 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ShortDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/ShortDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.decoders; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/StringDecoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/StringDecoder.java new file mode 100644 index 00000000000..5c4a9e85ef4 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/decoders/StringDecoder.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.decoders; + +import javax.websocket.DecodeException; +import javax.websocket.Decoder; + +/** + * Default implementation of the {@link javax.websocket.Decoder.Text} Message to {@link String} decoder + */ +public class StringDecoder extends AbstractDecoder implements Decoder.Text +{ + public static final StringDecoder INSTANCE = new StringDecoder(); + + @Override + public String decode(String s) throws DecodeException + { + return s; + } + + @Override + public boolean willDecode(String s) + { + return true; + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AbstractEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AbstractEncoder.java new file mode 100644 index 00000000000..3609b946783 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AbstractEncoder.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public abstract class AbstractEncoder implements Encoder +{ + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java similarity index 89% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java index de89d73c85f..dac4741c4a9 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/AvailableEncoders.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.encoders; @@ -30,9 +30,9 @@ import javax.websocket.Encoder; import javax.websocket.EndpointConfig; import org.eclipse.jetty.websocket.javax.common.InitException; -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; -import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; +import org.eclipse.jetty.websocket.util.ReflectUtils; public class AvailableEncoders implements Predicate> { @@ -289,9 +289,6 @@ public class AvailableEncoders implements Predicate> @Override public boolean test(Class type) { - return registeredEncoders.stream() - .filter(registered -> registered.isType(type)) - .findFirst() - .isPresent(); + return registeredEncoders.stream().anyMatch(registered -> registered.isType(type)); } } diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/BooleanEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/BooleanEncoder.java new file mode 100644 index 00000000000..dd328eb7be1 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/BooleanEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Boolean} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class BooleanEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Boolean object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteArrayEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteArrayEncoder.java new file mode 100644 index 00000000000..215705cbc56 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteArrayEncoder.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import java.nio.ByteBuffer; +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class ByteArrayEncoder implements Encoder.Binary +{ + @Override + public void destroy() + { + /* do nothing */ + } + + @Override + public ByteBuffer encode(byte[] object) throws EncodeException + { + return ByteBuffer.wrap(object); + } + + @Override + public void init(EndpointConfig config) + { + /* do nothing */ + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteBufferEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteBufferEncoder.java new file mode 100644 index 00000000000..2a2208c77d6 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteBufferEncoder.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import java.nio.ByteBuffer; +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class ByteBufferEncoder implements Encoder.Binary +{ + @Override + public void destroy() + { + /* do nothing */ + } + + @Override + public ByteBuffer encode(ByteBuffer object) throws EncodeException + { + return object; + } + + @Override + public void init(EndpointConfig config) + { + /* do nothing */ + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteEncoder.java new file mode 100644 index 00000000000..095c8d5ce81 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ByteEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Byte} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class ByteEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Byte object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/CharacterEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/CharacterEncoder.java new file mode 100644 index 00000000000..9453a825517 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/CharacterEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Character} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class CharacterEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Character object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/DoubleEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/DoubleEncoder.java new file mode 100644 index 00000000000..229ed5a8c83 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/DoubleEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Double} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class DoubleEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Double object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/EncodeFailedFuture.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/EncodeFailedFuture.java similarity index 64% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/EncodeFailedFuture.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/EncodeFailedFuture.java index 9cbe7eeeb93..1a0d43b9bdf 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/EncodeFailedFuture.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/EncodeFailedFuture.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.encoders; diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/FloatEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/FloatEncoder.java new file mode 100644 index 00000000000..e0ce4c50570 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/FloatEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Float} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class FloatEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Float object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/IntegerEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/IntegerEncoder.java new file mode 100644 index 00000000000..eb6d4c0cbd0 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/IntegerEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Integer} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class IntegerEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Integer object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/LongEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/LongEncoder.java new file mode 100644 index 00000000000..1f70b208d3f --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/LongEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Long} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class LongEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Long object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ShortEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ShortEncoder.java new file mode 100644 index 00000000000..d5b50e29578 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/ShortEncoder.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link Short} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class ShortEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(Short object) throws EncodeException + { + if (object == null) + { + return null; + } + return object.toString(); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/StringEncoder.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/StringEncoder.java new file mode 100644 index 00000000000..67e9e786f15 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/encoders/StringEncoder.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.encoders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; + +/** + * Default encoder for {@link String} to {@link javax.websocket.Encoder.Text} Message encoder + */ +public class StringEncoder extends AbstractEncoder implements Encoder.Text +{ + @Override + public String encode(String object) throws EncodeException + { + return object; + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSink.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSink.java similarity index 56% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSink.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSink.java index de56031549a..7932300479a 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSink.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSink.java @@ -1,38 +1,39 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.nio.ByteBuffer; import javax.websocket.CloseReason; import javax.websocket.DecodeException; import javax.websocket.Decoder; -import org.eclipse.jetty.websocket.core.CloseException; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.MessageSink; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.exception.CloseException; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; +import org.eclipse.jetty.websocket.util.messages.ByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.MessageSink; public class DecodedBinaryMessageSink extends DecodedMessageSink> { - public DecodedBinaryMessageSink(JavaxWebSocketSession session, + public DecodedBinaryMessageSink(CoreSession session, Decoder.Binary decoder, MethodHandle methodHandle) throws NoSuchMethodException, IllegalAccessException @@ -43,13 +44,13 @@ public class DecodedBinaryMessageSink extends DecodedMessageSink extends DecodedMessageSink> { - public DecodedBinaryStreamMessageSink(JavaxWebSocketSession session, + public DecodedBinaryStreamMessageSink(CoreSession session, Decoder.BinaryStream decoder, MethodHandle methodHandle) throws NoSuchMethodException, IllegalAccessException @@ -43,13 +44,13 @@ public class DecodedBinaryStreamMessageSink extends DecodedMessageSink extends AbstractMessageSink +{ + protected final Logger logger; + private final T decoder; + private final MethodHandle rawMethodHandle; + private final MessageSink rawMessageSink; + + public DecodedMessageSink(CoreSession session, T decoder, MethodHandle methodHandle) + throws NoSuchMethodException, IllegalAccessException + { + super(session, methodHandle); + this.logger = LoggerFactory.getLogger(this.getClass()); + this.decoder = decoder; + this.rawMethodHandle = newRawMethodHandle(); + this.rawMessageSink = newRawMessageSink(session, rawMethodHandle); + } + + protected abstract MethodHandle newRawMethodHandle() + throws NoSuchMethodException, IllegalAccessException; + + protected abstract MessageSink newRawMessageSink(CoreSession session, MethodHandle rawMethodHandle); + + public T getDecoder() + { + return decoder; + } + + @Override + public void accept(Frame frame, Callback callback) + { + this.rawMessageSink.accept(frame, callback); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSink.java b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSink.java similarity index 55% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSink.java rename to jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSink.java index 07c6c6f99a3..593e48c945f 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSink.java +++ b/jetty-websocket/websocket-javax-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSink.java @@ -1,37 +1,38 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import javax.websocket.CloseReason; import javax.websocket.DecodeException; import javax.websocket.Decoder; -import org.eclipse.jetty.websocket.core.CloseException; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; -import org.eclipse.jetty.websocket.javax.common.MessageSink; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.exception.CloseException; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; +import org.eclipse.jetty.websocket.util.messages.MessageSink; +import org.eclipse.jetty.websocket.util.messages.StringMessageSink; public class DecodedTextMessageSink extends DecodedMessageSink> { - public DecodedTextMessageSink(JavaxWebSocketSession session, + public DecodedTextMessageSink(CoreSession session, Decoder.Text decoder, MethodHandle methodHandle) throws NoSuchMethodException, IllegalAccessException @@ -42,13 +43,13 @@ public class DecodedTextMessageSink extends DecodedMessageSink extends DecodedMessageSink> { - public DecodedTextStreamMessageSink(JavaxWebSocketSession session, + public DecodedTextStreamMessageSink(CoreSession session, Decoder.TextStream decoder, MethodHandle methodHandle) throws NoSuchMethodException, IllegalAccessException @@ -43,13 +44,13 @@ public class DecodedTextStreamMessageSink extends DecodedMessageSink uriParams; protected EndpointConfig endpointConfig; - protected FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty(); + protected CoreSession coreSession = new CoreSession.Empty(); public AbstractJavaxWebSocketFrameHandlerTest() { - endpointConfig = new BasicEndpointConfig(); + endpointConfig = ClientEndpointConfig.Builder.create().build(); encoders = new AvailableEncoders(endpointConfig); decoders = new AvailableDecoders(endpointConfig); uriParams = new HashMap<>(); @@ -62,12 +63,8 @@ public abstract class AbstractJavaxWebSocketFrameHandlerTest protected JavaxWebSocketFrameHandler newJavaxFrameHandler(Object websocket) { JavaxWebSocketFrameHandlerFactory factory = container.getFrameHandlerFactory(); - BasicEndpointConfig config = new BasicEndpointConfig(); - ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket, config); + ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket, endpointConfig); UpgradeRequest upgradeRequest = new UpgradeRequestAdapter(); - - JavaxWebSocketFrameHandler localEndpoint = factory.newJavaxWebSocketFrameHandler(endpoint, upgradeRequest); - - return localEndpoint; + return factory.newJavaxWebSocketFrameHandler(endpoint, upgradeRequest); } } diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java similarity index 53% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java index b7dc6d895ad..e425420c99b 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -22,7 +22,7 @@ import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.Session; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.CoreSession; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -39,9 +39,9 @@ public abstract class AbstractSessionTest Object websocketPojo = new DummyEndpoint(); UpgradeRequest upgradeRequest = new UpgradeRequestAdapter(); JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(websocketPojo, upgradeRequest); - FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty(); - session = new JavaxWebSocketSession(container, coreSession, frameHandler, null); - container.addManaged(session); + CoreSession coreSession = new CoreSession.Empty(); + session = new JavaxWebSocketSession(container, coreSession, frameHandler, container.getFrameHandlerFactory() + .newDefaultEndpointConfig(websocketPojo.getClass(), null)); } @AfterAll diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/Defaults.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/Defaults.java new file mode 100644 index 00000000000..e7e505859a9 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/Defaults.java @@ -0,0 +1,28 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import java.util.concurrent.TimeUnit; + +public final class Defaults +{ + public static final long CONNECT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); + public static final long OPEN_EVENT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); + public static final long CLOSE_EVENT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); +} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyContainer.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyContainer.java similarity index 79% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyContainer.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyContainer.java index 77d967f40a3..ab0c3ae8626 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyContainer.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyFrameHandlerFactory.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyFrameHandlerFactory.java new file mode 100644 index 00000000000..d7468d6a2d0 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/DummyFrameHandlerFactory.java @@ -0,0 +1,57 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common; + +import javax.websocket.ClientEndpoint; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; + +import org.eclipse.jetty.websocket.util.InvokerUtils; + +public class DummyFrameHandlerFactory extends JavaxWebSocketFrameHandlerFactory +{ + public DummyFrameHandlerFactory(JavaxWebSocketContainer container) + { + super(container, InvokerUtils.PARAM_IDENTITY); + } + + @Override + public EndpointConfig newDefaultEndpointConfig(Class endpointClass, String path) + { + return ClientEndpointConfig.Builder.create().build(); + } + + @Override + public JavaxWebSocketFrameHandlerMetadata getMetadata(Class endpointClass, EndpointConfig endpointConfig) + { + if (javax.websocket.Endpoint.class.isAssignableFrom(endpointClass)) + { + return createEndpointMetadata((Class)endpointClass, endpointConfig); + } + + if (endpointClass.getAnnotation(ClientEndpoint.class) == null) + { + return null; + } + + JavaxWebSocketFrameHandlerMetadata metadata = new JavaxWebSocketFrameHandlerMetadata(endpointConfig); + return discoverJavaxFrameHandlerMetadata(endpointClass, metadata); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_BadSignaturesTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerBadSignaturesTest.java similarity index 85% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_BadSignaturesTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerBadSignaturesTest.java index 032a98ed1f7..cf4b7dc9e75 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_BadSignaturesTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerBadSignaturesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -25,14 +25,14 @@ import javax.websocket.OnError; import javax.websocket.OnOpen; import javax.websocket.Session; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertThrows; -public class JavaxWebSocketFrameHandler_BadSignaturesTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerBadSignaturesTest extends AbstractJavaxWebSocketFrameHandlerTest { private void assertBadSocket(Object socket, String expectedString) throws Exception { diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnCloseTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnCloseTest.java similarity index 78% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnCloseTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnCloseTest.java index b499d6dd4f0..8abf58ad0c9 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnCloseTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -35,7 +35,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; -public class JavaxWebSocketFrameHandler_OnCloseTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnCloseTest extends AbstractJavaxWebSocketFrameHandlerTest { private static final String EXPECTED_REASON = "CloseReason[1000,Normal]"; @@ -48,12 +48,12 @@ public class JavaxWebSocketFrameHandler_OnCloseTest extends AbstractJavaxWebSock CloseStatus status = new CloseStatus(CloseStatus.NORMAL, "Normal"); Frame closeFrame = status.toFrame(); localEndpoint.onFrame(closeFrame, Callback.from(() -> - { - localEndpoint.onClosed(status, Callback.NOOP); - }, t -> - { - throw new RuntimeException(t); - })); + localEndpoint.onClosed(status, Callback.NOOP), + t -> + { + throw new RuntimeException(t); + } + )); String event = socket.events.poll(10, TimeUnit.SECONDS); assertThat("Event", event, eventMatcher); } diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnErrorTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnErrorTest.java similarity index 76% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnErrorTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnErrorTest.java index 0ec8053f695..1b97ae0423d 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnErrorTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnErrorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -32,7 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; -public class JavaxWebSocketFrameHandler_OnErrorTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnErrorTest extends AbstractJavaxWebSocketFrameHandlerTest { private static final String EXPECTED_THROWABLE = "java.lang.RuntimeException: From Testcase"; diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_BinaryStreamTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageBinaryStreamTest.java similarity index 72% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_BinaryStreamTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageBinaryStreamTest.java index 340a3107e48..dc5b33aa2ab 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_BinaryStreamTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageBinaryStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -public class JavaxWebSocketFrameHandler_OnMessage_BinaryStreamTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnMessageBinaryStreamTest extends AbstractJavaxWebSocketFrameHandlerTest { @SuppressWarnings("Duplicates") private TrackingSocket performOnMessageInvocation(TrackingSocket socket, Function func) throws Exception diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_BinaryTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageBinaryTest.java similarity index 80% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_BinaryTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageBinaryTest.java index 97d475ca27f..2d05a5b3e8e 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_BinaryTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageBinaryTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -30,7 +30,7 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.common.sockets.TrackingSocket; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; @@ -40,7 +40,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.notNullValue; import static org.junit.jupiter.api.Assertions.assertThrows; -public class JavaxWebSocketFrameHandler_OnMessage_BinaryTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnMessageBinaryTest extends AbstractJavaxWebSocketFrameHandlerTest { private void assertOnMessageInvocation(TrackingSocket socket, Matcher eventMatcher) throws Exception { diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_TextStreamTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageTextStreamTest.java similarity index 71% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_TextStreamTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageTextStreamTest.java index daa7616cf01..0c5bb1bf9a9 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_TextStreamTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageTextStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -35,7 +35,7 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -public class JavaxWebSocketFrameHandler_OnMessage_TextStreamTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnMessageTextStreamTest extends AbstractJavaxWebSocketFrameHandlerTest { @SuppressWarnings("Duplicates") private TrackingSocket performOnMessageInvocation(TrackingSocket socket, Function func) throws Exception diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_TextTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageTextTest.java similarity index 80% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_TextTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageTextTest.java index 2525a9e03e2..ccb95e2674e 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnMessage_TextTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnMessageTextTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -30,7 +30,7 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.common.sockets.TrackingSocket; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; @@ -39,7 +39,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertThrows; -public class JavaxWebSocketFrameHandler_OnMessage_TextTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnMessageTextTest extends AbstractJavaxWebSocketFrameHandlerTest { private void onText(TrackingSocket socket, String msg) throws Exception { diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnOpenTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnOpenTest.java similarity index 67% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnOpenTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnOpenTest.java index 4ae4b6fb9ae..15fe26140c3 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandler_OnOpenTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketFrameHandlerOnOpenTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common; @@ -32,7 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; -public class JavaxWebSocketFrameHandler_OnOpenTest extends AbstractJavaxWebSocketFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnOpenTest extends AbstractJavaxWebSocketFrameHandlerTest { private void assertOnOpenInvocation(TrackingSocket socket, Matcher eventMatcher) throws Exception { diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualDecoder.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualDecoder.java similarity index 77% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualDecoder.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualDecoder.java index ffe287bfaf0..131f49a6aec 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.coders.tests; diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualEncoder.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualEncoder.java similarity index 52% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualEncoder.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualEncoder.java index 89a7151a61f..f42186b27bd 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualEncoder.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/BadDualEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.coders.tests; diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/ExtDecoder.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/ExtDecoder.java new file mode 100644 index 00000000000..d8582ec1fe7 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/ExtDecoder.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.coders.tests; + +import javax.websocket.Decoder; + +/** + * Testing scenario of an extended Decoder interface + * + * @param the decoder type + */ +public interface ExtDecoder extends Decoder.Text +{ + void setId(String id); +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/Fruit.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/Fruit.java new file mode 100644 index 00000000000..516a4f9e08a --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/Fruit.java @@ -0,0 +1,25 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.coders.tests; + +public class Fruit +{ + public String name; + public String color; +} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitBinaryEncoder.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitBinaryEncoder.java similarity index 61% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitBinaryEncoder.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitBinaryEncoder.java index 33848396a21..b64f2b583e4 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitBinaryEncoder.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitBinaryEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.coders.tests; diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitDecoder.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitDecoder.java similarity index 63% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitDecoder.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitDecoder.java index dd173201768..dc7b98bb631 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitDecoder.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.coders.tests; diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitTextEncoder.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitTextEncoder.java new file mode 100644 index 00000000000..0011e46d4e5 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/coders/tests/FruitTextEncoder.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.coders.tests; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class FruitTextEncoder implements Encoder.Text +{ + @Override + public void destroy() + { + } + + @Override + public String encode(Fruit fruit) throws EncodeException + { + return String.format("%s|%s", fruit.name, fruit.color); + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/AbstractStringEndpoint.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/AbstractStringEndpoint.java similarity index 73% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/AbstractStringEndpoint.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/AbstractStringEndpoint.java index 6564f6408f1..5a24ae41dc6 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/AbstractStringEndpoint.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/AbstractStringEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.endpoints; @@ -27,12 +27,12 @@ import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.javax.common.Defaults; import org.hamcrest.Matcher; import org.hamcrest.Matchers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -42,7 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public abstract class AbstractStringEndpoint extends Endpoint implements MessageHandler.Whole { - private static final Logger LOG = Log.getLogger(AbstractStringEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractStringEndpoint.class); public CountDownLatch closeLatch = new CountDownLatch(1); public AtomicReference closeInfo = new AtomicReference<>(); protected Session session; diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/DummyEndpoint.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/DummyEndpoint.java new file mode 100644 index 00000000000..3b34830b96a --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/DummyEndpoint.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.endpoints; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.Session; + +public class DummyEndpoint extends Endpoint +{ + @Override + public void onOpen(Session session, EndpointConfig config) + { + /* do nothing */ + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/EchoStringEndpoint.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/EchoStringEndpoint.java new file mode 100644 index 00000000000..c4be71da3c3 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/endpoints/EchoStringEndpoint.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.endpoints; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +/** + * Legitimate structure for an Endpoint + */ +public class EchoStringEndpoint extends AbstractStringEndpoint +{ + public BlockingQueue messageQueue = new LinkedBlockingDeque<>(); + + @Override + public void onMessage(String message) + { + messageQueue.offer(message); + session.getAsyncRemote().sendText(message); + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/BaseMessageHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/BaseMessageHandler.java new file mode 100644 index 00000000000..770536d9ce5 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/BaseMessageHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import javax.websocket.MessageHandler; + +public class BaseMessageHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(String message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayPartialHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayPartialHandler.java new file mode 100644 index 00000000000..2685f869b27 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayPartialHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import javax.websocket.MessageHandler; + +public class ByteArrayPartialHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(byte[] partialMessage, boolean last) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayWholeHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayWholeHandler.java new file mode 100644 index 00000000000..efbd4a0b357 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteArrayWholeHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import javax.websocket.MessageHandler; + +public class ByteArrayWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(byte[] message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferPartialHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferPartialHandler.java new file mode 100644 index 00000000000..0b074b58979 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferPartialHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +public class ByteBufferPartialHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(ByteBuffer partialMessage, boolean last) + { + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferWholeHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferWholeHandler.java new file mode 100644 index 00000000000..85a2b34dcdd --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ByteBufferWholeHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +public class ByteBufferWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(ByteBuffer message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ComboMessageHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ComboMessageHandler.java new file mode 100644 index 00000000000..6f9ca6d7735 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ComboMessageHandler.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +/** + * A particularly annoying type of MessageHandler. One defining 2 implementations. + */ +public class ComboMessageHandler implements MessageHandler.Whole, MessageHandler.Partial +{ + @Override + public void onMessage(ByteBuffer partialMessage, boolean last) + { + // TODO Auto-generated method stub + } + + @Override + public void onMessage(String message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ExtendedMessageHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ExtendedMessageHandler.java new file mode 100644 index 00000000000..980c649b224 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ExtendedMessageHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +public class ExtendedMessageHandler extends BaseMessageHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(ByteBuffer partialMessage, boolean last) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/InputStreamWholeHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/InputStreamWholeHandler.java new file mode 100644 index 00000000000..79358b8933c --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/InputStreamWholeHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import java.io.InputStream; +import javax.websocket.MessageHandler; + +public class InputStreamWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(InputStream stream) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/LongMessageHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/LongMessageHandler.java new file mode 100644 index 00000000000..1038e1ae413 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/LongMessageHandler.java @@ -0,0 +1,29 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import javax.websocket.MessageHandler; + +public class LongMessageHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(Long message) + { + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ReaderWholeHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ReaderWholeHandler.java new file mode 100644 index 00000000000..18c7a194ec5 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/ReaderWholeHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import java.io.Reader; +import javax.websocket.MessageHandler; + +public class ReaderWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(Reader reader) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringPartialHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringPartialHandler.java new file mode 100644 index 00000000000..a23afd7c1d1 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringPartialHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import javax.websocket.MessageHandler; + +public class StringPartialHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(String partialMessage, boolean last) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringWholeHandler.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringWholeHandler.java new file mode 100644 index 00000000000..c1c4c010393 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/handlers/StringWholeHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.handlers; + +import javax.websocket.MessageHandler; + +public class StringWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(String message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSinkTest.java new file mode 100644 index 00000000000..2965cc662f3 --- /dev/null +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/AbstractMessageSinkTest.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.common.messages; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.util.function.Consumer; + +import org.eclipse.jetty.websocket.javax.common.AbstractSessionTest; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; + +public abstract class AbstractMessageSinkTest extends AbstractSessionTest +{ + public MethodHandle getAcceptHandle(Consumer copy, Class type) + { + try + { + Class refc = copy.getClass(); + String name = "accept"; + MethodType methodType = MethodType.methodType(void.class, type); + MethodHandle handle = JavaxWebSocketFrameHandlerFactory.getServerMethodHandleLookup().findVirtual(refc, name, methodType); + return handle.bindTo(copy); + } + catch (NoSuchMethodException | IllegalAccessException e) + { + throw new RuntimeException("Ooops, we didn't find the Consumer<" + type.getName() + "> MethodHandle", e); + } + } +} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSinkTest.java similarity index 76% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSinkTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSinkTest.java index 1d9032e077e..afa3f919c73 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSinkTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryMessageSinkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; @@ -30,10 +30,10 @@ import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.common.AbstractSessionTest; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -44,15 +44,15 @@ public class DecodedBinaryMessageSinkTest extends AbstractMessageSinkTest public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Test - public void testCalendar_1_Frame() throws Exception + public void testCalendar1Frame() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedCalendarCopy copy = new DecodedCalendarCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Calendar.class); Decoder.Binary decoder = new GmtDecoder(); - DecodedBinaryMessageSink sink = new DecodedBinaryMessageSink(AbstractSessionTest.session, decoder, copyHandle); + DecodedBinaryMessageSink sink = new DecodedBinaryMessageSink(AbstractSessionTest.session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback finCallback = new FutureCallback(); ByteBuffer data = ByteBuffer.allocate(16); data.putShort((short)1999); data.put((byte)12); @@ -67,17 +67,17 @@ public class DecodedBinaryMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testCalendar_3_Frames() throws Exception + public void testCalendar3Frames() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedCalendarCopy copy = new DecodedCalendarCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Calendar.class); Decoder.Binary decoder = new GmtDecoder(); - DecodedBinaryMessageSink sink = new DecodedBinaryMessageSink(AbstractSessionTest.session, decoder, copyHandle); + DecodedBinaryMessageSink sink = new DecodedBinaryMessageSink(AbstractSessionTest.session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); ByteBuffer data1 = ByteBuffer.allocate(16); data1.putShort((short)2000); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryStreamMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryStreamMessageSinkTest.java similarity index 78% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryStreamMessageSinkTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryStreamMessageSinkTest.java index 5fd6c024967..1fbd4cf03d3 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryStreamMessageSinkTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedBinaryStreamMessageSinkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; @@ -33,9 +33,9 @@ import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -46,15 +46,15 @@ public class DecodedBinaryStreamMessageSinkTest extends AbstractMessageSinkTest public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Test - public void testCalendar_1_Frame() throws Exception + public void testCalendar1Frame() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedCalendarCopy copy = new DecodedCalendarCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Calendar.class); Decoder.BinaryStream decoder = new GmtDecoder(); - DecodedBinaryStreamMessageSink sink = new DecodedBinaryStreamMessageSink(session, decoder, copyHandle); + DecodedBinaryStreamMessageSink sink = new DecodedBinaryStreamMessageSink(session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback finCallback = new FutureCallback(); ByteBuffer data = ByteBuffer.allocate(16); data.putShort((short)1999); data.put((byte)12); @@ -69,17 +69,17 @@ public class DecodedBinaryStreamMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testCalendar_3_Frames() throws Exception + public void testCalendar3Frames() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedCalendarCopy copy = new DecodedCalendarCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Calendar.class); Decoder.BinaryStream decoder = new GmtDecoder(); - DecodedBinaryStreamMessageSink sink = new DecodedBinaryStreamMessageSink(session, decoder, copyHandle); + DecodedBinaryStreamMessageSink sink = new DecodedBinaryStreamMessageSink(session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); ByteBuffer data1 = ByteBuffer.allocate(16); data1.putShort((short)2000); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSinkTest.java similarity index 75% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSinkTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSinkTest.java index 2b10ee7e321..f805aec78b5 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSinkTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextMessageSinkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; @@ -30,9 +30,9 @@ import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -43,15 +43,15 @@ public class DecodedTextMessageSinkTest extends AbstractMessageSinkTest public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Test - public void testDate_1_Frame() throws Exception + public void testDate1Frame() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedDateCopy copy = new DecodedDateCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Date.class); Decoder.Text decoder = new GmtDecoder(); - DecodedTextMessageSink sink = new DecodedTextMessageSink(session, decoder, copyHandle); + DecodedTextMessageSink sink = new DecodedTextMessageSink(session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.TEXT).setPayload("2018.02.13").setFin(true), finCallback); finCallback.get(1, TimeUnit.SECONDS); // wait for callback @@ -61,17 +61,17 @@ public class DecodedTextMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testDate_3_Frames() throws Exception + public void testDate3Frames() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedDateCopy copy = new DecodedDateCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Date.class); Decoder.Text decoder = new GmtDecoder(); - DecodedTextMessageSink sink = new DecodedTextMessageSink(session, decoder, copyHandle); + DecodedTextMessageSink sink = new DecodedTextMessageSink(session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.TEXT).setPayload("2023").setFin(false), callback1); sink.accept(new Frame(OpCode.CONTINUATION).setPayload(".08").setFin(false), callback2); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextStreamMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextStreamMessageSinkTest.java similarity index 75% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextStreamMessageSinkTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextStreamMessageSinkTest.java index 5f9fcd40912..d33952b6f94 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextStreamMessageSinkTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/DecodedTextStreamMessageSinkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; @@ -32,10 +32,10 @@ import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -46,15 +46,15 @@ public class DecodedTextStreamMessageSinkTest extends AbstractMessageSinkTest public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Test - public void testDate_1_Frame() throws Exception + public void testDate1Frame() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedDateCopy copy = new DecodedDateCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Date.class); Decoder.TextStream decoder = new GmtDecoder(); - DecodedTextStreamMessageSink sink = new DecodedTextStreamMessageSink(session, decoder, copyHandle); + DecodedTextStreamMessageSink sink = new DecodedTextStreamMessageSink(session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.TEXT).setPayload("2018.02.13").setFin(true), finCallback); finCallback.get(1, TimeUnit.SECONDS); // wait for callback @@ -64,17 +64,17 @@ public class DecodedTextStreamMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testDate_3_Frames() throws Exception + public void testDate3Frames() throws Exception { CompletableFuture copyFuture = new CompletableFuture<>(); DecodedDateCopy copy = new DecodedDateCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Date.class); Decoder.TextStream decoder = new GmtDecoder(); - DecodedTextStreamMessageSink sink = new DecodedTextStreamMessageSink(session, decoder, copyHandle); + DecodedTextStreamMessageSink sink = new DecodedTextStreamMessageSink(session.getCoreSession(), decoder, copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.TEXT).setPayload("2023").setFin(false), callback1); sink.accept(new Frame(OpCode.CONTINUATION).setPayload(".08").setFin(false), callback2); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSinkTest.java similarity index 72% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSinkTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSinkTest.java index 556c8b35c72..eb8a9fb32fe 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSinkTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/InputStreamMessageSinkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; @@ -31,11 +31,12 @@ import java.util.function.Consumer; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.common.AbstractSessionTest; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; +import org.eclipse.jetty.websocket.util.messages.InputStreamMessageSink; import org.junit.jupiter.api.Test; import static java.nio.charset.StandardCharsets.UTF_8; @@ -45,13 +46,13 @@ import static org.hamcrest.Matchers.is; public class InputStreamMessageSinkTest extends AbstractMessageSinkTest { @Test - public void testInputStream_1_Message_1_Frame() throws InterruptedException, ExecutionException, TimeoutException + public void testInputStream1Message1Frame() throws InterruptedException, ExecutionException, TimeoutException { InputStreamCopy copy = new InputStreamCopy(); MethodHandle copyHandle = getAcceptHandle(copy, InputStream.class); - InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session, copyHandle); + InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session.getCoreSession(), copyHandle); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback finCallback = new FutureCallback(); ByteBuffer data = BufferUtil.toBuffer("Hello World", UTF_8); sink.accept(new Frame(OpCode.BINARY).setPayload(data), finCallback); @@ -62,13 +63,13 @@ public class InputStreamMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testInputStream_2_Messages_2_Frames() throws InterruptedException, ExecutionException, TimeoutException + public void testInputStream2Messages2Frames() throws InterruptedException, ExecutionException, TimeoutException { InputStreamCopy copy = new InputStreamCopy(); MethodHandle copyHandle = getAcceptHandle(copy, InputStream.class); - InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session, copyHandle); + InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session.getCoreSession(), copyHandle); - CompletableFutureCallback fin1Callback = new CompletableFutureCallback(); + FutureCallback fin1Callback = new FutureCallback(); ByteBuffer data1 = BufferUtil.toBuffer("Hello World", UTF_8); sink.accept(new Frame(OpCode.BINARY).setPayload(data1).setFin(true), fin1Callback); @@ -77,7 +78,7 @@ public class InputStreamMessageSinkTest extends AbstractMessageSinkTest assertThat("FinCallback.done", fin1Callback.isDone(), is(true)); assertThat("Writer.contents", new String(byteStream.toByteArray(), UTF_8), is("Hello World")); - CompletableFutureCallback fin2Callback = new CompletableFutureCallback(); + FutureCallback fin2Callback = new FutureCallback(); ByteBuffer data2 = BufferUtil.toBuffer("Greetings Earthling", UTF_8); sink.accept(new Frame(OpCode.BINARY).setPayload(data2).setFin(true), fin2Callback); @@ -88,15 +89,15 @@ public class InputStreamMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testInputStream_1_Message_3_Frames() throws InterruptedException, ExecutionException, TimeoutException + public void testInputStream1Message3Frames() throws InterruptedException, ExecutionException, TimeoutException { InputStreamCopy copy = new InputStreamCopy(); MethodHandle copyHandle = getAcceptHandle(copy, InputStream.class); - InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session, copyHandle); + InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session.getCoreSession(), copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.BINARY).setPayload("Hello").setFin(false), callback1); sink.accept(new Frame(OpCode.CONTINUATION).setPayload(", ").setFin(false), callback2); @@ -112,16 +113,16 @@ public class InputStreamMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testInputStream_1_Message_4_Frames_Empty_Fin() throws InterruptedException, ExecutionException, TimeoutException + public void testInputStream1Message4FramesEmptyFin() throws InterruptedException, ExecutionException, TimeoutException { InputStreamCopy copy = new InputStreamCopy(); MethodHandle copyHandle = getAcceptHandle(copy, InputStream.class); - InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session, copyHandle); + InputStreamMessageSink sink = new InputStreamMessageSink(AbstractSessionTest.session.getCoreSession(), copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback callback3 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback callback3 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.BINARY).setPayload("Greetings").setFin(false), callback1); sink.accept(new Frame(OpCode.CONTINUATION).setPayload(", ").setFin(false), callback2); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSinkTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSinkTest.java similarity index 66% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSinkTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSinkTest.java index ed1f2ef89d8..3bab792edca 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSinkTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/ReaderMessageSinkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.messages; @@ -28,10 +28,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; +import org.eclipse.jetty.websocket.util.messages.ReaderMessageSink; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -40,14 +41,14 @@ import static org.hamcrest.Matchers.is; public class ReaderMessageSinkTest extends AbstractMessageSinkTest { @Test - public void testReader_1_Frame() throws InterruptedException, ExecutionException, TimeoutException + public void testReader1Frame() throws InterruptedException, ExecutionException, TimeoutException { CompletableFuture copyFuture = new CompletableFuture<>(); ReaderCopy copy = new ReaderCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Reader.class); - ReaderMessageSink sink = new ReaderMessageSink(session, copyHandle); + ReaderMessageSink sink = new ReaderMessageSink(session.getCoreSession(), copyHandle); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.TEXT).setPayload("Hello World"), finCallback); finCallback.get(1, TimeUnit.SECONDS); // wait for callback @@ -57,16 +58,16 @@ public class ReaderMessageSinkTest extends AbstractMessageSinkTest } @Test - public void testReader_3_Frames() throws InterruptedException, ExecutionException, TimeoutException + public void testReader3Frames() throws InterruptedException, ExecutionException, TimeoutException { CompletableFuture copyFuture = new CompletableFuture<>(); ReaderCopy copy = new ReaderCopy(copyFuture); MethodHandle copyHandle = getAcceptHandle(copy, Reader.class); - ReaderMessageSink sink = new ReaderMessageSink(session, copyHandle); + ReaderMessageSink sink = new ReaderMessageSink(session.getCoreSession(), copyHandle); - CompletableFutureCallback callback1 = new CompletableFutureCallback(); - CompletableFutureCallback callback2 = new CompletableFutureCallback(); - CompletableFutureCallback finCallback = new CompletableFutureCallback(); + FutureCallback callback1 = new FutureCallback(); + FutureCallback callback2 = new FutureCallback(); + FutureCallback finCallback = new FutureCallback(); sink.accept(new Frame(OpCode.TEXT).setPayload("Hello").setFin(false), callback1); sink.accept(new Frame(OpCode.CONTINUATION).setPayload(", ").setFin(false), callback2); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/sockets/TrackingSocket.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/sockets/TrackingSocket.java similarity index 52% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/sockets/TrackingSocket.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/sockets/TrackingSocket.java index b463a2a9869..f06a72b356e 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/sockets/TrackingSocket.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/sockets/TrackingSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.sockets; diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtils_StaticParamsTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsStaticParamsTest.java similarity index 75% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtils_StaticParamsTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsStaticParamsTest.java index 60760007d9f..d9b5b131afe 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtils_StaticParamsTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsStaticParamsTest.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.util; import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @@ -26,13 +27,14 @@ import javax.websocket.Session; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils.Arg; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -public class InvokerUtils_StaticParamsTest +public class InvokerUtilsStaticParamsTest { @SuppressWarnings("unused") public static class Foo @@ -57,9 +59,11 @@ public class InvokerUtils_StaticParamsTest return String.format("onColorMessage(%s, '%s', '%s')", color); } } + + private static MethodHandles.Lookup lookup = MethodHandles.lookup(); @Test - public void testOnlyParam_String() throws Throwable + public void testOnlyParamString() throws Throwable { Method method = ReflectUtils.findMethod(Foo.class, "onFruit", String.class); @@ -71,7 +75,7 @@ public class InvokerUtils_StaticParamsTest // Raw Calling Args - none specified // Get basic method handle (without a instance to call against) - this is what the metadata stores - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(Foo.class, method, new NameParamIdentifier(), namedVariables); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, Foo.class, method, new NameParamIdentifier(), namedVariables); // Some point later an actual instance is needed, which has static named parameters Map templateValues = new HashMap<>(); @@ -90,7 +94,7 @@ public class InvokerUtils_StaticParamsTest } @Test - public void testOnlyParam_Int() throws Throwable + public void testOnlyParamInt() throws Throwable { Method method = ReflectUtils.findMethod(Foo.class, "onCount", int.class); @@ -100,7 +104,7 @@ public class InvokerUtils_StaticParamsTest }; // Get basic method handle (without a instance to call against) - this is what the metadata stores - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(Foo.class, method, new NameParamIdentifier(), namedVariables); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, Foo.class, method, new NameParamIdentifier(), namedVariables); // Some point later an actual instance is needed, which has static named parameters Map templateValues = new HashMap<>(); @@ -119,7 +123,7 @@ public class InvokerUtils_StaticParamsTest } @Test - public void testLabeledParam_StringInt() throws Throwable + public void testLabeledParamStringInt() throws Throwable { Method method = ReflectUtils.findMethod(Foo.class, "onLabeledCount", String.class, int.class); @@ -128,10 +132,10 @@ public class InvokerUtils_StaticParamsTest "count" }; - final Arg ARG_LABEL = new Arg(String.class).required(); + final InvokerUtils.Arg ARG_LABEL = new InvokerUtils.Arg(String.class).required(); // Get basic method handle (without a instance to call against) - this is what the metadata stores - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(Foo.class, method, new NameParamIdentifier(), namedVariables, ARG_LABEL); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, Foo.class, method, new NameParamIdentifier(), namedVariables, ARG_LABEL); // Some point later an actual instance is needed, which has static named parameters Map templateValues = new HashMap<>(); diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsTest.java similarity index 81% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsTest.java index 8af8fcc8ab4..54c6e51fa7f 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtilsTest.java @@ -1,28 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.util; import java.io.File; import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import org.eclipse.jetty.util.annotation.Name; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -149,11 +152,13 @@ public class InvokerUtilsTest throw new AssertionError("Unable to find method: " + name); } + private static MethodHandles.Lookup lookup = MethodHandles.lookup(); + @Test public void testSimpleInvoker() throws Throwable { Method method = ReflectUtils.findMethod(Simple.class, "onMessage", String.class); - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(Simple.class, method, new InvokerUtils.Arg(String.class)); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, Simple.class, method, new InvokerUtils.Arg(String.class)); Simple simple = new Simple(); String result = (String)methodHandle.invoke(simple, "Hello World"); @@ -170,7 +175,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle2 = InvokerUtils.mutatedInvoker(KeyValue.class, method2, callingArgs); + MethodHandle methodHandle2 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method2, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle2.invoke(obj, "Year", 1972); @@ -187,7 +192,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, "Age", 45); @@ -195,7 +200,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_AtEnd() throws Throwable + public void testKeyValueExtraArgsAtEnd() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -205,7 +210,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(Boolean.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, "Age", 45, Boolean.TRUE); @@ -213,7 +218,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_InMiddle() throws Throwable + public void testKeyValueExtraArgsInMiddle() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -223,7 +228,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, "Year", 888888L, 2017); @@ -231,7 +236,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_AtStart() throws Throwable + public void testKeyValueExtraArgsAtStart() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -241,7 +246,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, new Simple(), "Count", 1776); @@ -249,7 +254,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_Mixed() throws Throwable + public void testKeyValueExtraArgsMixed() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -261,7 +266,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(Long.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, new Simple(), "Amount", Boolean.TRUE, 200, 9999L); @@ -269,7 +274,7 @@ public class InvokerUtilsTest } @Test - public void testNamed_AllParams() throws Throwable + public void testNamedAllParams() throws Throwable { Method method = ReflectUtils.findMethod(NamedParams.class, "onMessage", String.class, String.class, int.class); @@ -279,7 +284,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class, "cost") }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(NamedParams.class, method, new NameParamIdentifier(), null, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, NamedParams.class, method, new NameParamIdentifier(), null, callingArgs); NamedParams obj = new NamedParams(); String result = (String)methodHandle.invoke(obj, "Apple", "Red", 10); @@ -287,7 +292,7 @@ public class InvokerUtilsTest } @Test - public void testNamed_AllParams_Mixed() throws Throwable + public void testNamedAllParamsMixed() throws Throwable { Method method = ReflectUtils.findMethod(NamedParams.class, "onMessage", String.class, String.class, int.class); @@ -297,7 +302,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class, "color") }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(NamedParams.class, method, new NameParamIdentifier(), null, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, NamedParams.class, method, new NameParamIdentifier(), null, callingArgs); NamedParams obj = new NamedParams(); String result = (String)methodHandle.invoke(obj, 20, "Banana", "Yellow"); @@ -305,20 +310,20 @@ public class InvokerUtilsTest } @Test - public void testEmpty_Call_None() throws Throwable + public void testEmptyCallNone() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigEmpty"); InvokerUtils.Arg[] callingArgs = new InvokerUtils.Arg[]{}; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples); assertThat("Result", result, is("sigEmpty<>")); } @Test - public void testEmpty_Call_File() throws Throwable + public void testEmptyCallFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigEmpty"); @@ -327,13 +332,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus")); assertThat("Result", result, is("sigEmpty<>")); } @Test - public void testEmpty_Call_NullFile() throws Throwable + public void testEmptyCallNullFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigEmpty"); @@ -342,13 +347,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, null); assertThat("Result", result, is("sigEmpty<>")); } @Test - public void testString_Call_String() throws Throwable + public void testStringCallString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStr"); @@ -357,13 +362,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Hello"); assertThat("Result", result, is("sigStr")); } @Test - public void testString_Call_File_String() throws Throwable + public void testStringCallFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStr"); @@ -373,13 +378,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus"), "Hiya"); assertThat("Result", result, is("sigStr")); } @Test - public void testString_Call_String_File() throws Throwable + public void testStringCallStringFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStr"); @@ -389,13 +394,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Greetings", new File("bogus")); assertThat("Result", result, is("sigStr")); } @Test - public void testStringFile_Call_String_File() throws Throwable + public void testStringFileCallStringFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStrFile"); @@ -405,13 +410,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Name", new File("bogus1")); assertThat("Result", result, is("sigStrFile")); } @Test - public void testStringFile_Call_File_String() throws Throwable + public void testStringFileCallFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStrFile"); @@ -421,13 +426,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus2"), "Alt"); assertThat("Result", result, is("sigStrFile")); } @Test - public void testFileString_Call_String_File() throws Throwable + public void testFileStringCallStringFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStr"); @@ -437,13 +442,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Bob", new File("bogus3")); assertThat("Result", result, is("sigFileStr")); } @Test - public void testFileString_Call_File_String() throws Throwable + public void testFileStringCallFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStr"); @@ -453,13 +458,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus4"), "Dobalina"); assertThat("Result", result, is("sigFileStr")); } @Test - public void testFileStringFin_Call_File_String_BoolTag() throws Throwable + public void testFileStringFinCallFileStringBoolTag() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -470,13 +475,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(boolean.class, "fin") }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); String result = (String)methodHandle.invoke(samples, new File("foo"), "bar", true); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_File_String_Bool() throws Throwable + public void testFileStringFinCallFileStringBool() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -487,13 +492,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(boolean.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("baz"), "flem", false); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_BoolTag_File_String() throws Throwable + public void testFileStringFinCallBoolTagFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -504,13 +509,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); String result = (String)methodHandle.invoke(samples, false, new File("foo"), "bar"); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_Bool_File_String() throws Throwable + public void testFileStringFinCallBoolFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -521,13 +526,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, true, new File("foo"), "bar"); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_BoolTag_Null_String() throws Throwable + public void testFileStringFinCallBoolTagNullString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -538,7 +543,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); String result = (String)methodHandle.invoke(samples, true, null, "bar"); assertThat("Result", result, is("sigFileStrFin<,bar,true>")); } diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/NameParamIdentifier.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/NameParamIdentifier.java similarity index 54% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/NameParamIdentifier.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/NameParamIdentifier.java index e88b955ccdd..9ecb0e20cf1 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/NameParamIdentifier.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/NameParamIdentifier.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.util; @@ -22,6 +22,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.eclipse.jetty.util.annotation.Name; +import org.eclipse.jetty.websocket.util.InvokerUtils; /** * Simple {@link InvokerUtils.ParamIdentifier} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtilsTest.java b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtilsTest.java similarity index 69% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtilsTest.java rename to jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtilsTest.java index 12cad58fd44..9d7026334d9 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtilsTest.java +++ b/jetty-websocket/websocket-javax-common/src/test/java/org/eclipse/jetty/websocket/javax/common/util/ReflectUtilsTest.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.common.util; +import org.eclipse.jetty.websocket.util.ReflectUtils; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -79,49 +80,49 @@ public class ReflectUtilsTest } @Test - public void testFindGeneric_PearFruit() + public void testFindGenericPearFruit() { assertFindGenericClass(Pear.class, Fruit.class, String.class); } @Test - public void testFindGeneric_PizzaFruit() + public void testFindGenericPizzaFruit() { assertFindGenericClass(Pizza.class, Fruit.class, Integer.class); } @Test - public void testFindGeneric_KiwiFruit() + public void testFindGenericKiwiFruit() { assertFindGenericClass(Kiwi.class, Fruit.class, Character.class); } @Test - public void testFindGeneric_PearColor() + public void testFindGenericPearColor() { assertFindGenericClass(Pear.class, Color.class, Double.class); } @Test - public void testFindGeneric_GrannySmithFruit() + public void testFindGenericGrannySmithFruit() { assertFindGenericClass(GrannySmith.class, Fruit.class, Long.class); } @Test - public void testFindGeneric_CavendishFruit() + public void testFindGenericCavendishFruit() { assertFindGenericClass(Cavendish.class, Fruit.class, String.class); } @Test - public void testFindGeneric_RainierFruit() + public void testFindGenericRainierFruit() { assertFindGenericClass(Rainier.class, Fruit.class, Short.class); } @Test - public void testFindGeneric_WashingtonFruit() + public void testFindGenericWashingtonFruit() { // Washington does not have a concrete implementation // of the Fruit interface, this should return null diff --git a/jetty-websocket/javax-websocket-common/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-javax-common/src/test/resources/jetty-logging.properties similarity index 61% rename from jetty-websocket/javax-websocket-common/src/test/resources/jetty-logging.properties rename to jetty-websocket/websocket-javax-common/src/test/resources/jetty-logging.properties index 4aebf62b5f8..274e97067c1 100644 --- a/jetty-websocket/javax-websocket-common/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-javax-common/src/test/resources/jetty-logging.properties @@ -1,25 +1,5 @@ -# -# -# ======================================================================== -# Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. -# ------------------------------------------------------------------------ -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# and Apache License v2.0 which accompanies this distribution. -# -# The Eclipse Public License is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# The Apache License v2.0 is available at -# http://www.opensource.org/licenses/apache2.0.php -# -# You may elect to redistribute this code under either of these licenses. -# ======================================================================== -# -# -# org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG # org.eclipse.jetty.util.log.stderr.LONG=true # org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG # org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG diff --git a/jetty-websocket/javax-websocket-common/src/test/resources/quotes-ben.txt b/jetty-websocket/websocket-javax-common/src/test/resources/quotes-ben.txt similarity index 100% rename from jetty-websocket/javax-websocket-common/src/test/resources/quotes-ben.txt rename to jetty-websocket/websocket-javax-common/src/test/resources/quotes-ben.txt diff --git a/jetty-websocket/javax-websocket-common/src/test/resources/quotes-twain.txt b/jetty-websocket/websocket-javax-common/src/test/resources/quotes-twain.txt similarity index 100% rename from jetty-websocket/javax-websocket-common/src/test/resources/quotes-twain.txt rename to jetty-websocket/websocket-javax-common/src/test/resources/quotes-twain.txt diff --git a/jetty-websocket/javax-websocket-server/pom.xml b/jetty-websocket/websocket-javax-server/pom.xml similarity index 86% rename from jetty-websocket/javax-websocket-server/pom.xml rename to jetty-websocket/websocket-javax-server/pom.xml index c4d3ee0e98d..f33263ba474 100644 --- a/jetty-websocket/javax-websocket-server/pom.xml +++ b/jetty-websocket/websocket-javax-server/pom.xml @@ -7,17 +7,17 @@ 4.0.0 - javax-websocket-server - Jetty :: Websocket :: javax.websocket.server :: Server Implementation + websocket-javax-server + Jetty :: Websocket :: javax.websocket :: Server - ${project.groupId}.javax.websocket.server + ${project.groupId}.javax.server org.eclipse.jetty.websocket - javax-websocket-client + websocket-javax-client ${project.version} @@ -34,6 +34,15 @@ org.eclipse.jetty.toolchain jetty-javax-websocket-api + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-websocket/websocket-javax-server/src/main/config/modules/websocket-javax.mod b/jetty-websocket/websocket-javax-server/src/main/config/modules/websocket-javax.mod new file mode 100644 index 00000000000..2f0ae30c75b --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/config/modules/websocket-javax.mod @@ -0,0 +1,25 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Enable javax.websocket for deployed web applications. + +[tags] +websocket + +[depend] +client +annotations + +[lib] +lib/websocket/websocket-core-${jetty.version}.jar +lib/websocket/websocket-servlet-${jetty.version}.jar +lib/websocket/websocket-util-${jetty.version}.jar +lib/websocket/jetty-javax-websocket-api-1.1.2.jar +lib/websocket/websocket-javax-client-${jetty.version}.jar +lib/websocket/websocket-javax-common-${jetty.version}.jar +lib/websocket/websocket-javax-server-${jetty.version}.jar + +[jpms] +# The implementation needs to access method handles in +# classes that are in the web application classloader. +add-reads: org.eclipse.jetty.websocket.javax.common=ALL-UNNAMED diff --git a/jetty-websocket/websocket-javax-server/src/main/java/module-info.java b/jetty-websocket/websocket-javax-server/src/main/java/module-info.java new file mode 100644 index 00000000000..6d52f89a355 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/java/module-info.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +import javax.servlet.ServletContainerInitializer; +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.webapp.Configuration; +import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketConfiguration; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; + +module org.eclipse.jetty.websocket.javax.server +{ + exports org.eclipse.jetty.websocket.javax.server.config; + + requires transitive org.eclipse.jetty.webapp; + requires transitive org.eclipse.jetty.websocket.javax.client; + requires org.eclipse.jetty.websocket.javax.common; + requires org.eclipse.jetty.websocket.servlet; + requires org.slf4j; + + provides ServletContainerInitializer with JavaxWebSocketServletContainerInitializer; + provides ServerEndpointConfig.Configurator with ContainerDefaultConfigurator; + provides Configuration with JavaxWebSocketConfiguration; +} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/ContainerDefaultConfigurator.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/ContainerDefaultConfigurator.java similarity index 65% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/ContainerDefaultConfigurator.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/ContainerDefaultConfigurator.java index b4acdeb8b01..0c33c0ad38d 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/ContainerDefaultConfigurator.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/ContainerDefaultConfigurator.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.server; +package org.eclipse.jetty.websocket.javax.server.config; +import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; import javax.websocket.Extension; @@ -26,8 +27,8 @@ import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpointConfig; import javax.websocket.server.ServerEndpointConfig.Configurator; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The "Container Default Configurator" per the JSR-356 spec. @@ -36,7 +37,7 @@ import org.eclipse.jetty.util.log.Logger; */ public final class ContainerDefaultConfigurator extends Configurator { - private static final Logger LOG = Log.getLogger(ContainerDefaultConfigurator.class); + private static final Logger LOG = LoggerFactory.getLogger(ContainerDefaultConfigurator.class); private static final String NO_SUBPROTOCOL = ""; /** @@ -71,14 +72,25 @@ public final class ContainerDefaultConfigurator extends Configurator } catch (Exception e) { - throw new InstantiationException(String.format("%s: %s", e.getClass().getName(), e.getMessage())); + InstantiationException instantiationException = new InstantiationException(); + instantiationException.initCause(e); + throw instantiationException; } } @Override public List getNegotiatedExtensions(List installed, List requested) { - return requested; + List negotiatedExtensions = new ArrayList<>(); + for (Extension ext : requested) + { + // Only choose the first extension if multiple with the same name. + long matches = negotiatedExtensions.stream().filter(e -> e.getName().equals(ext.getName())).count(); + if (matches == 0) + negotiatedExtensions.add(ext); + } + + return negotiatedExtensions; } @Override diff --git a/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketConfiguration.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketConfiguration.java new file mode 100644 index 00000000000..4c66e39abed --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketConfiguration.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.config; + +import org.eclipse.jetty.webapp.AbstractConfiguration; +import org.eclipse.jetty.webapp.FragmentConfiguration; +import org.eclipse.jetty.webapp.MetaInfConfiguration; +import org.eclipse.jetty.webapp.WebAppConfiguration; +import org.eclipse.jetty.webapp.WebInfConfiguration; +import org.eclipse.jetty.webapp.WebXmlConfiguration; + +/** + *

      Websocket Configuration

      + *

      This configuration configures the WebAppContext server/system classes to + * be able to see the org.eclipse.jetty.websocket package. + *

      + */ +public class JavaxWebSocketConfiguration extends AbstractConfiguration +{ + public JavaxWebSocketConfiguration() + { + addDependencies(WebXmlConfiguration.class, MetaInfConfiguration.class, WebInfConfiguration.class, FragmentConfiguration.class); + addDependents("org.eclipse.jetty.annotations.AnnotationConfiguration", WebAppConfiguration.class.getName()); + protectAndExpose("org.eclipse.jetty.websocket.servlet."); // For WebSocketUpgradeFilter + protectAndExpose("org.eclipse.jetty.websocket.javax.server.config."); + protectAndExpose("org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainerProvider"); + hide("org.eclipse.jetty.websocket.javax.server.internal"); + } +} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServletContainerInitializer.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketServletContainerInitializer.java similarity index 90% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServletContainerInitializer.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketServletContainerInitializer.java index 9261f8356be..797c9c1f1a8 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServletContainerInitializer.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketServletContainerInitializer.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.server; +package org.eclipse.jetty.websocket.javax.server.config; import java.util.HashSet; import java.util.Set; @@ -35,12 +35,13 @@ import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.listener.ContainerInitializer; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ThreadClassLoaderScope; import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer; import org.eclipse.jetty.websocket.servlet.WebSocketMapping; import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @HandlesTypes({ServerApplicationConfig.class, ServerEndpoint.class, Endpoint.class}) public class JavaxWebSocketServletContainerInitializer implements ServletContainerInitializer @@ -53,7 +54,7 @@ public class JavaxWebSocketServletContainerInitializer implements ServletContain public static final String ENABLE_KEY = "org.eclipse.jetty.websocket.javax"; public static final String HTTPCLIENT_ATTRIBUTE = "org.eclipse.jetty.websocket.javax.HttpClient"; - private static final Logger LOG = Log.getLogger(JavaxWebSocketServletContainerInitializer.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketServletContainerInitializer.class); /** * Test a ServletContext for {@code init-param} or {@code attribute} at {@code keyName} for @@ -147,7 +148,7 @@ public class JavaxWebSocketServletContainerInitializer implements ServletContain * @param context the context to work with * @return the default {@link ServerContainer} for this context */ - public static JavaxWebSocketServerContainer initialize(ServletContextHandler context) + private static ServerContainer initialize(ServletContextHandler context) { JavaxWebSocketServerContainer serverContainer = JavaxWebSocketServerContainer.getContainer(context.getServletContext()); if (serverContainer == null) @@ -179,7 +180,7 @@ public class JavaxWebSocketServletContainerInitializer implements ServletContain } ServletContextHandler servletContextHandler = ServletContextHandler.getServletContextHandler(context, "Javax WebSocket SCI"); - JavaxWebSocketServerContainer container = initialize(servletContextHandler); + ServerContainer container = initialize(servletContextHandler); try (ThreadClassLoaderScope scope = new ThreadClassLoaderScope(context.getClassLoader())) { diff --git a/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/AnnotatedServerEndpointConfig.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/AnnotatedServerEndpointConfig.java new file mode 100644 index 00000000000..23af02b0575 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/AnnotatedServerEndpointConfig.java @@ -0,0 +1,138 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.internal; + +import java.util.ArrayList; +import java.util.List; +import javax.websocket.Decoder; +import javax.websocket.DeploymentException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; +import javax.websocket.server.ServerEndpoint; +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; +import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper; +import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator; + +public class AnnotatedServerEndpointConfig extends ServerEndpointConfigWrapper +{ + public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class endpointClass, ServerEndpoint anno) throws DeploymentException + { + this(containerScope, endpointClass, anno, null); + } + + public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class endpointClass, ServerEndpoint anno, EndpointConfig baseConfig) throws DeploymentException + { + // Provided Base EndpointConfig. + ServerEndpointConfig baseServerConfig = null; + if (baseConfig instanceof ServerEndpointConfig) + { + baseServerConfig = (ServerEndpointConfig)baseConfig; + } + + // Decoders (favor provided config over annotation). + List> decoders; + if (baseConfig != null && baseConfig.getDecoders() != null && baseConfig.getDecoders().size() > 0) + decoders = baseConfig.getDecoders(); + else + decoders = List.of(anno.decoders()); + + // AvailableEncoders (favor provided config over annotation). + List> encoders; + if (baseConfig != null && baseConfig.getEncoders() != null && baseConfig.getEncoders().size() > 0) + encoders = baseConfig.getEncoders(); + else + encoders = List.of(anno.encoders()); + + // Sub Protocols (favor provided config over annotation). + List subprotocols; + if (baseServerConfig != null && baseServerConfig.getSubprotocols() != null && baseServerConfig.getSubprotocols().size() > 0) + subprotocols = baseServerConfig.getSubprotocols(); + else + subprotocols = List.of(anno.subprotocols()); + + // Path (favor provided config over annotation). + String path; + if (baseServerConfig != null && baseServerConfig.getPath() != null && baseServerConfig.getPath().length() > 0) + path = baseServerConfig.getPath(); + else + path = anno.value(); + + // Make sure all Configurators obtained are decorated. + ServerEndpointConfig.Configurator rawConfigurator = getConfigurator(baseServerConfig, anno); + ServerEndpointConfig.Configurator configurator = containerScope.getObjectFactory().decorate(rawConfigurator); + + // Build a ServerEndpointConfig with the Javax API builder to wrap. + ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder.create(endpointClass, path) + .configurator(configurator) + .encoders(encoders) + .decoders(decoders) + .extensions(new ArrayList<>()) + .subprotocols(subprotocols) + .build(); + + // Set the UserProperties from annotation into the new EndpointConfig. + if (baseConfig != null && baseConfig.getUserProperties() != null && baseConfig.getUserProperties().size() > 0) + endpointConfig.getUserProperties().putAll(baseConfig.getUserProperties()); + + init(endpointConfig); + } + + private static Configurator getConfigurator(ServerEndpointConfig baseServerConfig, ServerEndpoint anno) throws DeploymentException + { + Configurator ret = null; + + // Copy from base config + if (baseServerConfig != null) + { + ret = baseServerConfig.getConfigurator(); + } + + if (anno != null) + { + // Is this using the JSR356 spec/api default? + if (anno.configurator() == ServerEndpointConfig.Configurator.class) + { + // Return the spec default impl if one wasn't provided as part of the base config + if (ret == null) + return new ContainerDefaultConfigurator(); + else + return ret; + } + + // Instantiate the provided configurator + try + { + return anno.configurator().newInstance(); + } + catch (InstantiationException | IllegalAccessException e) + { + StringBuilder err = new StringBuilder(); + err.append("Unable to instantiate ServerEndpoint.configurator() of "); + err.append(anno.configurator().getName()); + err.append(" defined as annotation in "); + err.append(anno.getClass().getName()); + throw new DeploymentException(err.toString(), e); + } + } + + return ret; + } +} diff --git a/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/BasicServerEndpointConfig.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/BasicServerEndpointConfig.java new file mode 100644 index 00000000000..1ced906e6d2 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/BasicServerEndpointConfig.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.internal; + +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper; +import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator; + +public class BasicServerEndpointConfig extends ServerEndpointConfigWrapper +{ + private final String _path; + + public BasicServerEndpointConfig(Class endpointClass, String path) + { + ServerEndpointConfig config = Builder.create(endpointClass, "/") + .configurator(new ContainerDefaultConfigurator()) + .build(); + _path = path; + init(config); + } + + @Override + public String getPath() + { + if (_path == null) + throw new RuntimeException("Path is undefined"); + + return _path; + } +} diff --git a/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxServerUpgradeRequest.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxServerUpgradeRequest.java new file mode 100644 index 00000000000..9b4d4d55939 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxServerUpgradeRequest.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.internal; + +import java.net.URI; +import java.security.Principal; + +import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; +import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; + +public class JavaxServerUpgradeRequest implements UpgradeRequest +{ + private final ServletUpgradeRequest servletRequest; + + public JavaxServerUpgradeRequest(ServletUpgradeRequest servletRequest) + { + this.servletRequest = servletRequest; + } + + @Override + public Principal getUserPrincipal() + { + return servletRequest.getUserPrincipal(); + } + + @Override + public URI getRequestURI() + { + return this.servletRequest.getRequestURI(); + } +} diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketCreator.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketCreator.java similarity index 88% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketCreator.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketCreator.java index 2a536077e30..de98982caac 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketCreator.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketCreator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.internal; @@ -31,23 +31,24 @@ import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; import org.eclipse.jetty.websocket.javax.common.ConfiguredEndpoint; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketExtension; +import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JavaxWebSocketCreator implements WebSocketCreator { public static final String PROP_REMOTE_ADDRESS = "javax.websocket.endpoint.remoteAddress"; public static final String PROP_LOCAL_ADDRESS = "javax.websocket.endpoint.localAddress"; public static final String PROP_LOCALES = "javax.websocket.upgrade.locales"; - private static final Logger LOG = Log.getLogger(JavaxWebSocketCreator.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketCreator.class); private final JavaxWebSocketContainer containerScope; private final ServerEndpointConfig baseConfig; private final WebSocketExtensionRegistry extensionRegistry; diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServerContainer.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketServerContainer.java similarity index 74% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServerContainer.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketServerContainer.java index ffe0ae7bc6b..5f7bd46f996 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServerContainer.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketServerContainer.java @@ -1,30 +1,29 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.server; +package org.eclipse.jetty.websocket.javax.server.internal; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; -import java.util.function.Supplier; +import java.util.function.Function; import javax.servlet.ServletContext; import javax.websocket.DeploymentException; -import javax.websocket.EndpointConfig; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; @@ -35,22 +34,20 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketException; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer; -import org.eclipse.jetty.websocket.javax.server.internal.AnnotatedServerEndpointConfig; -import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketCreator; -import org.eclipse.jetty.websocket.javax.server.internal.UndefinedServerEndpointConfig; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.servlet.WebSocketMapping; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ManagedObject("JSR356 Server Container") public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer implements javax.websocket.server.ServerContainer, LifeCycle.Listener { public static final String JAVAX_WEBSOCKET_CONTAINER_ATTRIBUTE = javax.websocket.server.ServerContainer.class.getName(); - private static final Logger LOG = Log.getLogger(JavaxWebSocketServerContainer.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketServerContainer.class); public static JavaxWebSocketServerContainer getContainer(ServletContext servletContext) { @@ -66,7 +63,7 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer JavaxWebSocketServerContainer container = getContainer(servletContext); if (container == null) { - Supplier coreClientSupplier = () -> + Function coreClientSupplier = (wsComponents) -> { WebSocketCoreClient coreClient = (WebSocketCoreClient)servletContext.getAttribute(WebSocketCoreClient.WEBSOCKET_CORECLIENT_ATTRIBUTE); if (coreClient == null) @@ -86,7 +83,7 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer httpClient.setExecutor(executor); // create the core client - coreClient = new WebSocketCoreClient(httpClient, WebSocketComponents.ensureWebSocketComponents(servletContext)); + coreClient = new WebSocketCoreClient(httpClient, wsComponents); coreClient.getHttpClient().setName("Javax-WebSocketClient@" + Integer.toHexString(coreClient.getHttpClient().hashCode())); if (executor != null && httpClient == null) coreClient.getHttpClient().setExecutor(executor); @@ -101,7 +98,7 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer WebSocketComponents.ensureWebSocketComponents(servletContext), coreClientSupplier); contextHandler.addManaged(container); - contextHandler.addLifeCycleListener(container); + contextHandler.addEventListener(container); } // Store a reference to the ServerContainer per - javax.websocket spec 1.0 final - section 6.4: Programmatic Server Deployment servletContext.setAttribute(JAVAX_WEBSOCKET_CONTAINER_ATTRIBUTE, container); @@ -137,7 +134,7 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer * @param components the {@link WebSocketComponents} instance to use * @param coreClientSupplier the supplier of the {@link WebSocketCoreClient} instance to use */ - public JavaxWebSocketServerContainer(WebSocketMapping webSocketMapping, WebSocketComponents components, Supplier coreClientSupplier) + public JavaxWebSocketServerContainer(WebSocketMapping webSocketMapping, WebSocketComponents components, Function coreClientSupplier) { super(components, coreClientSupplier); this.webSocketMapping = webSocketMapping; @@ -162,25 +159,6 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer return frameHandlerFactory; } - @Override - protected EndpointConfig newEmptyConfig(Object endpoint) - { - return new UndefinedServerEndpointConfig(endpoint.getClass()); - } - - protected EndpointConfig readAnnotatedConfig(Object endpoint, EndpointConfig config) throws DeploymentException - { - ServerEndpoint anno = endpoint.getClass().getAnnotation(ServerEndpoint.class); - if (anno != null) - { - // Overwrite Config from Annotation - // TODO: should we merge with provided config? - return new AnnotatedServerEndpointConfig(this, endpoint.getClass(), anno, config); - } - return config; - } - - @Override public void addEndpoint(Class endpointClass) throws DeploymentException { if (endpointClass == null) @@ -194,10 +172,7 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer { ServerEndpoint anno = endpointClass.getAnnotation(ServerEndpoint.class); if (anno == null) - { - throw new DeploymentException(String.format("Class must be @%s annotated: %s", - ServerEndpoint.class.getName(), endpointClass.getName())); - } + throw new DeploymentException(String.format("Class must be @%s annotated: %s", ServerEndpoint.class.getName(), endpointClass.getName())); ServerEndpointConfig config = new AnnotatedServerEndpointConfig(this, endpointClass, anno); addEndpointMapping(config); @@ -216,36 +191,36 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer } @Override - public void addEndpoint(ServerEndpointConfig config) throws DeploymentException + public void addEndpoint(ServerEndpointConfig providedConfig) throws DeploymentException { - if (config == null) - { + if (providedConfig == null) throw new DeploymentException("ServerEndpointConfig is null"); - } if (isStarted() || isStarting()) { - if (LOG.isDebugEnabled()) - { - LOG.debug("addEndpoint({}) path={} endpoint={}", config, config.getPath(), config.getEndpointClass()); - } - + Class endpointClass = providedConfig.getEndpointClass(); try { + // If we have annotations merge the annotated ServerEndpointConfig with the provided one. + ServerEndpoint anno = endpointClass.getAnnotation(ServerEndpoint.class); + ServerEndpointConfig config = (anno == null) ? providedConfig + : new AnnotatedServerEndpointConfig(this, endpointClass, anno, providedConfig); + + if (LOG.isDebugEnabled()) + LOG.debug("addEndpoint({}) path={} endpoint={}", config, config.getPath(), endpointClass); + addEndpointMapping(config); } catch (WebSocketException e) { - throw new DeploymentException("Unable to deploy: " + config.getEndpointClass().getName(), e); + throw new DeploymentException("Unable to deploy: " + endpointClass.getName(), e); } } else { if (deferredEndpointConfigs == null) - { deferredEndpointConfigs = new ArrayList<>(); - } - deferredEndpointConfigs.add(config); + deferredEndpointConfigs.add(providedConfig); } } diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServerFrameHandlerFactory.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketServerFrameHandlerFactory.java similarity index 56% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServerFrameHandlerFactory.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketServerFrameHandlerFactory.java index 8a5bdee8907..a31ea1741e6 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/JavaxWebSocketServerFrameHandlerFactory.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JavaxWebSocketServerFrameHandlerFactory.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.server; +package org.eclipse.jetty.websocket.javax.server.internal; import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; @@ -24,16 +24,14 @@ import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientFrameHandlerFactory; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; -import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerMetadata; -import org.eclipse.jetty.websocket.javax.server.internal.DelegatedJavaxServletUpgradeRequest; -import org.eclipse.jetty.websocket.javax.server.internal.PathParamIdentifier; import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; -public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketFrameHandlerFactory implements FrameHandlerFactory +public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketClientFrameHandlerFactory implements FrameHandlerFactory { public JavaxWebSocketServerFrameHandlerFactory(JavaxWebSocketContainer container) { @@ -41,7 +39,7 @@ public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketFrame } @Override - public JavaxWebSocketFrameHandlerMetadata createMetadata(Class endpointClass, EndpointConfig endpointConfig) + public JavaxWebSocketFrameHandlerMetadata getMetadata(Class endpointClass, EndpointConfig endpointConfig) { if (javax.websocket.Endpoint.class.isAssignableFrom(endpointClass)) { @@ -49,10 +47,9 @@ public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketFrame } ServerEndpoint anno = endpointClass.getAnnotation(ServerEndpoint.class); - if (anno == null) { - return null; + return super.getMetadata(endpointClass, endpointConfig); } UriTemplatePathSpec templatePathSpec = new UriTemplatePathSpec(anno.value()); @@ -64,6 +61,6 @@ public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketFrame @Override public FrameHandler newFrameHandler(Object websocketPojo, ServletUpgradeRequest upgradeRequest, ServletUpgradeResponse upgradeResponse) { - return newJavaxWebSocketFrameHandler(websocketPojo, new DelegatedJavaxServletUpgradeRequest(upgradeRequest)); + return newJavaxWebSocketFrameHandler(websocketPojo, new JavaxServerUpgradeRequest(upgradeRequest)); } } diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeRequest.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeRequest.java similarity index 65% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeRequest.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeRequest.java index 77212a85877..be31158e1f2 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeRequest.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.internal; diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeResponse.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeResponse.java similarity index 52% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeResponse.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeResponse.java index 78f37bd7771..8e25272dc36 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeResponse.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/JsrHandshakeResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.internal; diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamIdentifier.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamIdentifier.java similarity index 54% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamIdentifier.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamIdentifier.java index 8296b2689c0..3b26056b2cc 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamIdentifier.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamIdentifier.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.internal; @@ -22,7 +22,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import javax.websocket.server.PathParam; -import org.eclipse.jetty.websocket.javax.common.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.InvokerUtils; /** * Method argument identifier for {@link javax.websocket.server.PathParam} annotations. diff --git a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamServerEndpointConfig.java b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamServerEndpointConfig.java similarity index 59% rename from jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamServerEndpointConfig.java rename to jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamServerEndpointConfig.java index 4c6f81fa22a..4ae75ecac3f 100644 --- a/jetty-websocket/javax-websocket-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamServerEndpointConfig.java +++ b/jetty-websocket/websocket-javax-server/src/main/java/org/eclipse/jetty/websocket/javax/server/internal/PathParamServerEndpointConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.internal; @@ -25,6 +25,7 @@ import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.websocket.javax.common.PathParamProvider; +import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper; /** * Make {@link javax.websocket.server.PathParam} information from the incoming request available diff --git a/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer new file mode 100644 index 00000000000..68d8b37077c --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer @@ -0,0 +1 @@ +org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer \ No newline at end of file diff --git a/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator b/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator new file mode 100644 index 00000000000..e9f7fc540a4 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/javax.websocket.server.ServerEndpointConfig$Configurator @@ -0,0 +1 @@ +org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator \ No newline at end of file diff --git a/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration b/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration new file mode 100644 index 00000000000..9c5a60b0447 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration @@ -0,0 +1 @@ +org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketConfiguration \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserConfigurator.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserConfigurator.java similarity index 60% rename from jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserConfigurator.java rename to jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserConfigurator.java index 22b71882371..ddccb106bd4 100644 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserConfigurator.java +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserConfigurator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.browser; diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserDebugTool.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserDebugTool.java similarity index 73% rename from jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserDebugTool.java rename to jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserDebugTool.java index ccb71039385..23066040239 100644 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserDebugTool.java +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserDebugTool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.browser; @@ -30,10 +30,10 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Tool to help debug JSR based websocket circumstances reported around browsers. @@ -43,7 +43,7 @@ import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerIn */ public class JsrBrowserDebugTool { - private static final Logger LOG = Log.getLogger(JsrBrowserDebugTool.class); + private static final Logger LOG = LoggerFactory.getLogger(JsrBrowserDebugTool.class); public static void main(String[] args) { @@ -68,7 +68,7 @@ public class JsrBrowserDebugTool } catch (Throwable t) { - LOG.warn(t); + LOG.warn("Unable to start {}", JsrBrowserDebugTool.class.getName(), t); } } diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserSocket.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserSocket.java similarity index 88% rename from jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserSocket.java rename to jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserSocket.java index ad8d1f3be6d..4cbe0f0e343 100644 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserSocket.java +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/browser/JsrBrowserSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.browser; @@ -33,8 +33,8 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint(value = "/", subprotocols = {"tool"}, configurator = JsrBrowserConfigurator.class) public class JsrBrowserSocket @@ -74,7 +74,7 @@ public class JsrBrowserSocket } } - private static final Logger LOG = Log.getLogger(JsrBrowserSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(JsrBrowserSocket.class); private Session session; private Async remote; private String userAgent; diff --git a/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionConfigurator.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionConfigurator.java new file mode 100644 index 00000000000..80890503983 --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionConfigurator.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.examples; + +import javax.servlet.http.HttpSession; +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpointConfig; + +public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator +{ + @Override + public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) + { + HttpSession httpSession = (HttpSession)request.getHttpSession(); + config.getUserProperties().put(HttpSession.class.getName(), httpSession); + } +} diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionSocket.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionSocket.java rename to jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionSocket.java index d59995941df..15daea9f5cd 100644 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionSocket.java +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/GetHttpSessionSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.examples; diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedConfigurator.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedConfigurator.java similarity index 53% rename from jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedConfigurator.java rename to jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedConfigurator.java index 6ca85f2545b..d633f2f26be 100644 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedConfigurator.java +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedConfigurator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.server.examples; diff --git a/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedSocket.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedSocket.java new file mode 100644 index 00000000000..a2b6396d19e --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/MyAuthedSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.examples; + +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/secured/socket", configurator = MyAuthedConfigurator.class) +public class MyAuthedSocket +{ + @OnMessage + public String onMessage(String msg) + { + // echo the message back to the remote + return msg; + } +} diff --git a/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/StreamingEchoSocket.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/StreamingEchoSocket.java new file mode 100644 index 00000000000..d5d86e451ec --- /dev/null +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/StreamingEchoSocket.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.server.examples; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.util.IO; + +@ServerEndpoint("/echo") +public class StreamingEchoSocket +{ + @OnMessage + public void onMessage(Session session, Reader reader) + { + try (Writer writer = session.getBasicRemote().getSendWriter()) + { + IO.copy(reader, writer); + } + catch (IOException e) + { + e.printStackTrace(); + } + } +} diff --git a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/WebSocketServerExamplesTest.java b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/WebSocketServerExamplesTest.java similarity index 77% rename from jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/WebSocketServerExamplesTest.java rename to jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/WebSocketServerExamplesTest.java index 56438ccfb47..22c96ca9772 100644 --- a/jetty-websocket/javax-websocket-server/src/test/java/org/eclipse/jetty/websocket/javax/server/WebSocketServerExamplesTest.java +++ b/jetty-websocket/websocket-javax-server/src/test/java/org/eclipse/jetty/websocket/javax/server/examples/WebSocketServerExamplesTest.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.server; +package org.eclipse.jetty.websocket.javax.server.examples; import java.net.URI; import java.util.concurrent.ArrayBlockingQueue; @@ -41,23 +41,21 @@ import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.security.Credential; -import org.eclipse.jetty.websocket.javax.server.examples.GetHttpSessionSocket; -import org.eclipse.jetty.websocket.javax.server.examples.MyAuthedSocket; -import org.eclipse.jetty.websocket.javax.server.examples.StreamingEchoSocket; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; public class WebSocketServerExamplesTest { - private static final Logger LOG = Log.getLogger(WebSocketServerExamplesTest.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketServerExamplesTest.class); @ClientEndpoint public static class ClientSocket @@ -88,20 +86,20 @@ public class WebSocketServerExamplesTest @OnError public void onError(Throwable cause) { - LOG.debug(cause); + LOG.debug("ClientSocket error", cause); } } static Server _server; - static ServerConnector connector; + static ServerConnector _connector; static ServletContextHandler _context; @BeforeAll public static void setup() throws Exception { _server = new Server(); - connector = new ServerConnector(_server); - _server.addConnector(connector); + _connector = new ServerConnector(_server); + _server.addConnector(_connector); _context = new ServletContextHandler(ServletContextHandler.SESSIONS); _context.setContextPath("/"); @@ -116,7 +114,7 @@ public class WebSocketServerExamplesTest }); _server.start(); - System.setProperty("org.eclipse.jetty.websocket.port", Integer.toString(connector.getLocalPort())); + System.setProperty("org.eclipse.jetty.websocket.port", Integer.toString(_connector.getLocalPort())); } @AfterAll @@ -155,7 +153,7 @@ public class WebSocketServerExamplesTest public void testMyAuthedSocket() throws Exception { //HttpClient is configured for BasicAuthentication with the XmlHttpClientProvider - URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/secured/socket"); + URI uri = URI.create("ws://localhost:" + _connector.getLocalPort() + "/secured/socket"); WebSocketContainer clientContainer = ContainerProvider.getWebSocketContainer(); ClientSocket clientEndpoint = new ClientSocket(); @@ -172,7 +170,7 @@ public class WebSocketServerExamplesTest @Test public void testStreamingEchoSocket() throws Exception { - URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/echo"); + URI uri = URI.create("ws://localhost:" + _connector.getLocalPort() + "/echo"); WebSocketContainer clientContainer = ContainerProvider.getWebSocketContainer(); ClientSocket clientEndpoint = new ClientSocket(); @@ -189,7 +187,7 @@ public class WebSocketServerExamplesTest @Test public void testGetHttpSessionSocket() throws Exception { - URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/example"); + URI uri = URI.create("ws://localhost:" + _connector.getLocalPort() + "/example"); WebSocketContainer clientContainer = ContainerProvider.getWebSocketContainer(); ClientSocket clientEndpoint = new ClientSocket(); diff --git a/jetty-websocket/javax-websocket-server/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-javax-server/src/test/resources/jetty-logging.properties similarity index 60% rename from jetty-websocket/javax-websocket-server/src/test/resources/jetty-logging.properties rename to jetty-websocket/websocket-javax-server/src/test/resources/jetty-logging.properties index d9e757d813a..67577df4375 100644 --- a/jetty-websocket/javax-websocket-server/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-javax-server/src/test/resources/jetty-logging.properties @@ -1,11 +1,10 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG # org.eclipse.jetty.websocket.LEVEL=DEBUG # org.eclipse.jetty.websocket.LEVEL=INFO # org.eclipse.jetty.websocket.LEVEL=WARN # org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.WebSocketSession.LEVEL=DEBUG -# org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG ### Show state changes on BrowserDebugTool # -- LEAVE THIS AT DEBUG LEVEL -- -org.eclipse.jetty.websocket.jsr356.server.browser.LEVEL=DEBUG +org.eclipse.jetty.websocket.javax.server.browser.LEVEL=DEBUG diff --git a/jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml b/jetty-websocket/websocket-javax-server/src/test/resources/jetty-websocket-httpclient.xml similarity index 85% rename from jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml rename to jetty-websocket/websocket-javax-server/src/test/resources/jetty-websocket-httpclient.xml index fe9e825c5a6..eef3def7410 100644 --- a/jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml +++ b/jetty-websocket/websocket-javax-server/src/test/resources/jetty-websocket-httpclient.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-websocket/javax-websocket-server/src/test/resources/jsr-browser-debug-tool/index.html b/jetty-websocket/websocket-javax-server/src/test/resources/jsr-browser-debug-tool/index.html similarity index 100% rename from jetty-websocket/javax-websocket-server/src/test/resources/jsr-browser-debug-tool/index.html rename to jetty-websocket/websocket-javax-server/src/test/resources/jsr-browser-debug-tool/index.html diff --git a/jetty-websocket/javax-websocket-server/src/test/resources/jsr-browser-debug-tool/main.css b/jetty-websocket/websocket-javax-server/src/test/resources/jsr-browser-debug-tool/main.css similarity index 100% rename from jetty-websocket/javax-websocket-server/src/test/resources/jsr-browser-debug-tool/main.css rename to jetty-websocket/websocket-javax-server/src/test/resources/jsr-browser-debug-tool/main.css diff --git a/jetty-websocket/javax-websocket-server/src/test/resources/jsr-browser-debug-tool/websocket.js b/jetty-websocket/websocket-javax-server/src/test/resources/jsr-browser-debug-tool/websocket.js similarity index 100% rename from jetty-websocket/javax-websocket-server/src/test/resources/jsr-browser-debug-tool/websocket.js rename to jetty-websocket/websocket-javax-server/src/test/resources/jsr-browser-debug-tool/websocket.js diff --git a/jetty-websocket/websocket-javax-tests/fuzzingclient.json b/jetty-websocket/websocket-javax-tests/fuzzingclient.json new file mode 100644 index 00000000000..fbe1ce7e85e --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/fuzzingclient.json @@ -0,0 +1,18 @@ +{ + "options": { + "failByDrop": false + }, + "outdir": "./target/reports/servers", + "servers": [ + { + "agent": "Jetty-10.0.0-SNAPSHOT", + "url": "ws://127.0.0.1:9001", + "options": { + "version": 18 + } + } + ], + "cases": ["*"], + "exclude-cases": [], + "exclude-agent-cases": {} +} diff --git a/jetty-websocket/websocket-javax-tests/fuzzingserver.json b/jetty-websocket/websocket-javax-tests/fuzzingserver.json new file mode 100644 index 00000000000..ade31281937 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/fuzzingserver.json @@ -0,0 +1,10 @@ +{ + "options": { + "failByDrop": false + }, + "url": "ws://127.0.0.1:9001", + "outdir": "./target/reports/clients", + "cases": ["*"], + "exclude-cases": [], + "exclude-agent-cases": {} +} diff --git a/jetty-websocket/javax-websocket-tests/pom.xml b/jetty-websocket/websocket-javax-tests/pom.xml similarity index 66% rename from jetty-websocket/javax-websocket-tests/pom.xml rename to jetty-websocket/websocket-javax-tests/pom.xml index 0976122edee..83c821612d0 100644 --- a/jetty-websocket/javax-websocket-tests/pom.xml +++ b/jetty-websocket/websocket-javax-tests/pom.xml @@ -7,22 +7,26 @@ 4.0.0 - javax-websocket-tests - Jetty :: Websocket :: javax.websocket :: Integration Tests + websocket-javax-tests + Jetty :: Websocket :: javax.websocket :: Tests - ${project.groupId}.javax.websocket.tests + ${project.groupId}.javax.tests + + org.slf4j + slf4j-api + org.eclipse.jetty.websocket - javax-websocket-client + websocket-javax-client ${project.version} org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} @@ -34,6 +38,11 @@ org.eclipse.jetty.toolchain jetty-javax-websocket-api + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper @@ -46,6 +55,22 @@ + + org.apache.maven.plugins + maven-deploy-plugin + + + true + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + org.apache.felix maven-bundle-plugin diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BadFrame.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BadFrame.java new file mode 100644 index 00000000000..4977927474e --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BadFrame.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; + +/** + * Allow Fuzzer / Generator to create bad frames for testing frame validation + */ +public class BadFrame extends Frame +{ + public BadFrame(byte opcode) + { + super(OpCode.CONTINUATION); + super.finRsvOp = (byte)((finRsvOp & 0xF0) | (opcode & 0x0F)); + // NOTE: Not setting Frame.Type intentionally + } + + @Override + public boolean isControlFrame() + { + return false; + } + + @Override + public boolean isDataFrame() + { + return false; + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BiConsumerServiceServlet.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BiConsumerServiceServlet.java similarity index 51% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BiConsumerServiceServlet.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BiConsumerServiceServlet.java index 83e9a7753e7..b215249b0ae 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BiConsumerServiceServlet.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/BiConsumerServiceServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CompletableFutureMethodHandle.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CompletableFutureMethodHandle.java new file mode 100644 index 00000000000..c7008dea780 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CompletableFutureMethodHandle.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; + +public class CompletableFutureMethodHandle +{ + public static MethodHandle of(Class type, CompletableFuture future) + { + Method method = ReflectUtils.findMethod(CompletableFuture.class, "complete", type); + MethodHandles.Lookup lookup = JavaxWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); + MethodHandle completeHandle = InvokerUtils.mutatedInvoker(lookup, CompletableFuture.class, method, new InvokerUtils.Arg(type)); + return completeHandle.bindTo(future); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CoreServer.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CoreServer.java similarity index 83% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CoreServer.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CoreServer.java index 274fc1d8c26..f9704788735 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CoreServer.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/CoreServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -31,6 +31,7 @@ import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; @@ -116,7 +117,7 @@ public class CoreServer extends ContainerLifeCycle } @Override - public void customize(FrameHandler.Configuration configurable) + public void customize(Configuration configurable) { } @@ -178,7 +179,7 @@ public class CoreServer extends ContainerLifeCycle } @Override - public void customize(FrameHandler.Configuration configurable) + public void customize(Configuration configurable) { } } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DataUtils.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DataUtils.java similarity index 62% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DataUtils.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DataUtils.java index a83404be979..48c01adf893 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DataUtils.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DataUtils.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DummyEndpoint.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DummyEndpoint.java new file mode 100644 index 00000000000..96d92d56e90 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/DummyEndpoint.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.Session; + +public class DummyEndpoint extends Endpoint +{ + @Override + public void onOpen(Session session, EndpointConfig config) + { + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java new file mode 100644 index 00000000000..a69db90ba45 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/EventSocket.java @@ -0,0 +1,101 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import javax.websocket.ClientEndpoint; +import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/") +@ClientEndpoint() +public class EventSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(EventSocket.class); + + public Session session; + public EndpointConfig endpointConfig; + + public BlockingQueue textMessages = new BlockingArrayQueue<>(); + public BlockingQueue binaryMessages = new BlockingArrayQueue<>(); + public volatile Throwable error = null; + public volatile CloseReason closeReason = null; + + public CountDownLatch openLatch = new CountDownLatch(1); + public CountDownLatch closeLatch = new CountDownLatch(1); + public CountDownLatch errorLatch = new CountDownLatch(1); + + @OnOpen + public void onOpen(Session session, EndpointConfig endpointConfig) + { + this.session = session; + this.endpointConfig = endpointConfig; + if (LOG.isDebugEnabled()) + LOG.debug("{} onOpen(): {}", toString(), session); + openLatch.countDown(); + } + + @OnMessage + public void onMessage(String message) throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("{} onMessage(): {}", toString(), message); + textMessages.offer(message); + } + + @OnMessage + public void onMessage(ByteBuffer message) throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("{} onMessage(): {}", toString(), message); + binaryMessages.offer(message); + } + + @OnClose + public void onClose(CloseReason reason) + { + if (LOG.isDebugEnabled()) + LOG.debug("{} onClose(): {}", toString(), reason); + + closeReason = reason; + closeLatch.countDown(); + } + + @OnError + public void onError(Throwable cause) + { + if (LOG.isDebugEnabled()) + LOG.debug("{} onError(): {}", toString(), cause); + error = cause; + errorLatch.countDown(); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/FunctionMethod.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/FunctionMethod.java similarity index 61% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/FunctionMethod.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/FunctionMethod.java index c63882a6481..d6b0bbee06e 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/FunctionMethod.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/FunctionMethod.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Fuzzer.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Fuzzer.java similarity index 84% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Fuzzer.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Fuzzer.java index 56a9bbece5c..d6a2056d075 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Fuzzer.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Fuzzer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -25,11 +25,11 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.toolchain.test.ByteBufferAssert; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -120,7 +120,7 @@ public interface Fuzzer extends AutoCloseable public Adapter() { - logger = Log.getLogger(this.getClass()); + logger = LoggerFactory.getLogger(this.getClass()); } public void expectMessage(BlockingQueue framesQueue, byte expectedDataOp, ByteBuffer expectedMessage) throws InterruptedException @@ -177,12 +177,10 @@ public interface Fuzzer extends AutoCloseable { String expectedText = expected.getPayloadAsUTF8(); String actualText = actual.getPayloadAsUTF8(); - assertThat(prefix + ".payloadLength", actual.getPayloadLength(), is(expected.getPayloadLength())); assertThat(prefix + ".text-payload", actualText, is(expectedText)); } else { - assertThat(prefix + ".payloadLength", actual.getPayloadLength(), is(expected.getPayloadLength())); ByteBufferAssert.assertEquals(prefix + ".payload", expected.getPayload(), actual.getPayload()); } } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java similarity index 90% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java index c9c76778bf7..44053df8719 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; @@ -53,7 +54,7 @@ public class LocalFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseable public LocalFuzzer(Provider provider, CharSequence requestPath) throws Exception { - this(provider, requestPath, UpgradeUtils.newDefaultUpgradeRequestHeaders()); + this(provider, requestPath, new HashMap<>()); } public LocalFuzzer(Provider provider, CharSequence requestPath, Map headers) throws Exception diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java similarity index 88% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java index 5a638ab8cd0..01170fd2a8b 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -43,20 +43,20 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.websocket.core.internal.Parser; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSessionListener; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerContainer; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerFrameHandlerFactory; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer; +import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerFrameHandlerFactory; import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provider { @@ -70,7 +70,7 @@ public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provi } } - private static final Logger LOG = Log.getLogger(LocalServer.class); + private static final Logger LOG = LoggerFactory.getLogger(LocalServer.class); private final ByteBufferPool bufferPool = new MappedByteBufferPool(); private Server server; private ServerConnector connector; @@ -82,6 +82,15 @@ public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provi private boolean ssl = false; private SslContextFactory.Server sslContextFactory; + public LocalServer() + { + QueuedThreadPool threadPool = new QueuedThreadPool(); + threadPool.setName("qtp-LocalServer"); + + // Configure Server + server = new Server(threadPool); + } + public void enableSsl(boolean ssl) { this.ssl = ssl; @@ -179,11 +188,6 @@ public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provi @Override protected void doStart() throws Exception { - QueuedThreadPool threadPool = new QueuedThreadPool(); - threadPool.setName("qtp-LocalServer"); - - // Configure Server - server = new Server(threadPool); if (ssl) { // HTTP Configuration @@ -197,9 +201,8 @@ public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provi httpConfig.setSendDateHeader(false); sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath()); + sslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore.p12").getAbsolutePath()); sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setKeyManagerPassword("keypwd"); sslContextFactory.setExcludeCipherSuites("SSL_RSA_WITH_DES_CBC_SHA", "SSL_DHE_RSA_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"); diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/MessageType.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/MessageType.java new file mode 100644 index 00000000000..a39b53db179 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/MessageType.java @@ -0,0 +1,26 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +public enum MessageType +{ + TEXT, + BINARY, + PONG +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java similarity index 78% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java index e57c86d9bd5..a82972a61a7 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.javax.tests; import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; @@ -33,9 +34,10 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; @@ -51,7 +53,6 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab private final RawUpgradeRequest upgradeRequest; private final UnitGenerator generator; private final FrameCapture frameCapture; - private SharedBlockingCallback sharedBlockingCallback = new SharedBlockingCallback(); public NetworkFuzzer(LocalServer server) throws Exception { @@ -81,7 +82,7 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab this.client.start(); this.generator = new UnitGenerator(Behavior.CLIENT); - CompletableFuture futureHandler = this.client.connect(upgradeRequest); + CompletableFuture futureHandler = this.client.connect(upgradeRequest); CompletableFuture futureCapture = futureHandler.thenCombine(upgradeRequest.getFuture(), (session, capture) -> capture); this.frameCapture = futureCapture.get(10, TimeUnit.SECONDS); } @@ -91,12 +92,11 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab public ByteBuffer asNetworkBuffer(List frames) { int bufferLength = frames.stream().mapToInt((f) -> f.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); - ByteBuffer buffer = ByteBuffer.allocate(bufferLength); + ByteBuffer buffer = BufferUtil.allocate(bufferLength); for (Frame f : frames) { generator.generate(buffer, f); } - BufferUtil.flipToFlush(buffer, 0); return buffer; } @@ -155,23 +155,16 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab { for (Frame f : frames) { - try (SharedBlockingCallback.Blocker blocker = sharedBlockingCallback.acquire()) - { - frameCapture.coreSession.sendFrame(f, blocker, false); - } + FutureCallback callback = new FutureCallback(); + frameCapture.coreSession.sendFrame(f, callback, false); + callback.block(); } } @Override public void sendFrames(Frame... frames) throws IOException { - for (Frame f : frames) - { - try (SharedBlockingCallback.Blocker blocker = sharedBlockingCallback.acquire()) - { - frameCapture.coreSession.sendFrame(f, blocker, false); - } - } + sendFrames(Arrays.asList(frames)); } @Override @@ -208,9 +201,9 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab } @Override - protected void customize(EndPoint endp) + protected void customize(EndPoint endPoint) { - frameCapture.setEndPoint(endp); + frameCapture.setEndPoint(endPoint); futureCapture.complete(frameCapture); } @@ -227,7 +220,6 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab private final BlockingQueue receivedFrames = new LinkedBlockingQueue<>(); private EndPoint endPoint; private CountDownLatch openLatch = new CountDownLatch(1); - private final SharedBlockingCallback blockingCallback = new SharedBlockingCallback(); private CoreSession coreSession; public void setEndPoint(EndPoint endpoint) @@ -275,10 +267,9 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab synchronized (this) { - try (SharedBlockingCallback.Blocker blocker = blockingCallback.acquire()) - { - endPoint.write(blocker, buffer); - } + FutureCallback callback = new FutureCallback(); + endPoint.write(callback, buffer); + callback.block(); } } } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/ParserCapture.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/ParserCapture.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/ParserCapture.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/ParserCapture.java index a47d5748bfc..61c261c8aae 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/ParserCapture.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/ParserCapture.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/RawFrameBuilder.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/RawFrameBuilder.java similarity index 75% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/RawFrameBuilder.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/RawFrameBuilder.java index eeb58a89ae7..b22fb0390ac 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/RawFrameBuilder.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/RawFrameBuilder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/SessionMatchers.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/SessionMatchers.java similarity index 51% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/SessionMatchers.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/SessionMatchers.java index fd74c761b99..14ad0e426da 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/SessionMatchers.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/SessionMatchers.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Sha1Sum.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Sha1Sum.java similarity index 77% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Sha1Sum.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Sha1Sum.java index ebd9b2dcdd6..4841866690e 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Sha1Sum.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Sha1Sum.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Timeouts.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Timeouts.java new file mode 100644 index 00000000000..dae5eff1799 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/Timeouts.java @@ -0,0 +1,28 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.util.concurrent.TimeUnit; + +public final class Timeouts +{ + public static final long CONNECT_MS = TimeUnit.SECONDS.toMillis(10); + public static final long OPEN_EVENT_MS = TimeUnit.SECONDS.toMillis(10); + public static final long CLOSE_EVENT_MS = TimeUnit.SECONDS.toMillis(10); +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java similarity index 70% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java index 10a4af1a6a8..d02b876655c 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -23,7 +23,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Frame; @@ -40,7 +39,6 @@ public class UnitGenerator extends Generator public UnitGenerator(Behavior behavior) { - super(new MappedByteBufferPool()); applyMask = (behavior == Behavior.CLIENT); } diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java new file mode 100644 index 00000000000..b60d67a996a --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.util.Map; + +public class UpgradeUtils +{ + public static String generateUpgradeRequest(CharSequence requestPath, Map headers) + { + StringBuilder upgradeRequest = new StringBuilder(); + upgradeRequest.append("GET "); + upgradeRequest.append(requestPath == null ? "/" : requestPath); + upgradeRequest.append(" HTTP/1.1\r\n"); + headers.entrySet().forEach(e -> + upgradeRequest.append(e.getKey()).append(": ").append(e.getValue()).append("\r\n")); + upgradeRequest.append("\r\n"); + return upgradeRequest.toString(); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEndpointTracker.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEndpointTracker.java similarity index 82% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEndpointTracker.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEndpointTracker.java index b0cd2771638..c0825c90383 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEndpointTracker.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEndpointTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -29,9 +29,9 @@ import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.hamcrest.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -61,7 +61,7 @@ public abstract class WSEndpointTracker extends Endpoint public WSEndpointTracker(String id) { - logger = Log.getLogger(this.getClass().getName() + "." + id); + logger = LoggerFactory.getLogger(this.getClass().getName() + "." + id); logger.debug("init"); } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEventTracker.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEventTracker.java similarity index 85% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEventTracker.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEventTracker.java index c45c26a2d0f..4f80e889d64 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEventTracker.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSEventTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -31,9 +31,9 @@ import javax.websocket.OnError; import javax.websocket.OnOpen; import javax.websocket.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.hamcrest.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -90,7 +90,7 @@ public abstract class WSEventTracker public WSEventTracker(String id) { - logger = Log.getLogger(this.getClass().getName() + "." + id); + logger = LoggerFactory.getLogger(this.getClass().getName() + "." + id); logger.debug("init"); } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java similarity index 77% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java index 817fcc2a7ed..92a9fa0913b 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -24,22 +24,19 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; -import org.eclipse.jetty.annotations.AnnotationConfiguration; -import org.eclipse.jetty.plus.webapp.PlusConfiguration; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.JAR; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketConfiguration; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -52,7 +49,7 @@ import static org.hamcrest.Matchers.notNullValue; */ public class WSServer extends LocalServer implements LocalFuzzer.Provider { - private static final Logger LOG = Log.getLogger(WSServer.class); + private static final Logger LOG = LoggerFactory.getLogger(WSServer.class); private final Path contextDir; private final String contextPath; private ContextHandlerCollection contexts; @@ -129,11 +126,7 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider context.setContextPath(this.contextPath); context.setBaseResource(new PathResource(this.contextDir)); context.setAttribute("org.eclipse.jetty.websocket.javax", Boolean.TRUE); - - context.addConfiguration(new AnnotationConfiguration()); - context.addConfiguration(new PlusConfiguration()); context.addConfiguration(new JavaxWebSocketConfiguration()); - return context; } @@ -162,7 +155,6 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider @Override protected Handler createRootHandler(Server server) throws Exception { - HandlerCollection handlers = new HandlerCollection(); contexts = new ContextHandlerCollection(); return contexts; } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSURI.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSURI.java similarity index 83% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSURI.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSURI.java index 9ac5422b7c4..ddb5bfedfc7 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSURI.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSURI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameEcho.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameEcho.java similarity index 54% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameEcho.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameEcho.java index 6d7cbe87a3d..313d5e540ed 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameEcho.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameEcho.java @@ -1,33 +1,34 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.framehandlers; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class FrameEcho implements FrameHandler { - private static final Logger LOG = Log.getLogger(FrameEcho.class); + private static final Logger LOG = LoggerFactory.getLogger(FrameEcho.class); private CoreSession coreSession; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameHandlerTracker.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameHandlerTracker.java similarity index 73% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameHandlerTracker.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameHandlerTracker.java index b4ff93b0a6b..3326b58f979 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameHandlerTracker.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/FrameHandlerTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.framehandlers; @@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.MessageHandler; public class FrameHandlerTracker extends MessageHandler diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/StaticText.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/StaticText.java new file mode 100644 index 00000000000..f135c3a44d8 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/StaticText.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.framehandlers; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.MessageHandler; + +public class StaticText extends MessageHandler +{ + private final String staticMessage; + + public StaticText(String message) + { + this.staticMessage = message; + } + + @Override + public void onText(String wholeMessage, Callback callback) + { + sendText(staticMessage, callback, false); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/WholeMessageEcho.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/WholeMessageEcho.java new file mode 100644 index 00000000000..12a4d31fcf1 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/framehandlers/WholeMessageEcho.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.framehandlers; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.MessageHandler; + +public class WholeMessageEcho extends MessageHandler +{ + @Override + public void onBinary(ByteBuffer wholeMessage, Callback callback) + { + sendBinary(wholeMessage, callback, false); + } + + @Override + public void onText(String wholeMessage, Callback callback) + { + sendText(wholeMessage, callback, false); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerType.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerType.java similarity index 78% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerType.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerType.java index 3ad84670e97..325d5fd71a1 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerType.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerType.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.matchers; @@ -24,8 +24,8 @@ import javax.websocket.PongMessage; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; -import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; import org.eclipse.jetty.websocket.javax.tests.MessageType; +import org.eclipse.jetty.websocket.util.ReflectUtils; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerTypeRegistered.java b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerTypeRegistered.java similarity index 85% rename from jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerTypeRegistered.java rename to jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerTypeRegistered.java index 5790070b10c..4b89d83771f 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerTypeRegistered.java +++ b/jetty-websocket/websocket-javax-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/matchers/IsMessageHandlerTypeRegistered.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.matchers; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/BasicEchoEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/BasicEchoEndpoint.java new file mode 100644 index 00000000000..b3690ba6d3a --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/BasicEchoEndpoint.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/echo") +public class BasicEchoEndpoint extends Endpoint implements MessageHandler.Whole +{ + private Session session; + + @Override + public void onMessage(String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } + + @OnOpen + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + session.addMessageHandler(this); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/BasicEchoEndpointConfigContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/BasicEchoEndpointConfigContextListener.java new file mode 100644 index 00000000000..e6f3e1c8042 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/BasicEchoEndpointConfigContextListener.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.websocket.DeploymentException; +import javax.websocket.server.ServerEndpointConfig; + +public class BasicEchoEndpointConfigContextListener implements ServletContextListener +{ + @Override + public void contextDestroyed(ServletContextEvent sce) + { + /* do nothing */ + } + + @Override + public void contextInitialized(ServletContextEvent sce) + { + javax.websocket.server.ServerContainer container = (javax.websocket.server.ServerContainer)sce.getServletContext() + .getAttribute(javax.websocket.server.ServerContainer.class.getName()); + if (container == null) + throw new IllegalStateException("No Websocket ServerContainer in " + sce.getServletContext()); + + // Build up a configuration with a specific path + String path = "/echo"; + ServerEndpointConfig.Builder builder = ServerEndpointConfig.Builder.create(BasicEchoEndpoint.class, path); + try + { + container.addEndpoint(builder.build()); + } + catch (DeploymentException e) + { + throw new RuntimeException("Unable to add endpoint via config file", e); + } + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutContextListener.java new file mode 100644 index 00000000000..3d0f19b131b --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutContextListener.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.websocket.DeploymentException; +import javax.websocket.server.ServerContainer; +import javax.websocket.server.ServerEndpointConfig; + +/** + * Example of adding a server WebSocket (extending {@link javax.websocket.Endpoint}) programmatically via config + */ +public class IdleTimeoutContextListener implements ServletContextListener +{ + @Override + public void contextDestroyed(ServletContextEvent sce) + { + /* do nothing */ + } + + @Override + public void contextInitialized(ServletContextEvent sce) + { + ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); + // Build up a configuration with a specific path + String path = "/idle-onopen-endpoint"; + ServerEndpointConfig.Builder builder = ServerEndpointConfig.Builder.create(OnOpenIdleTimeoutEndpoint.class, path); + try + { + container.addEndpoint(builder.build()); + } + catch (DeploymentException e) + { + throw new RuntimeException("Unable to add endpoint via config file", e); + } + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenEndpoint.java new file mode 100644 index 00000000000..4d8208aa967 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenEndpoint.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +public class IdleTimeoutOnOpenEndpoint extends Endpoint implements MessageHandler.Whole +{ + private Session session; + + @Override + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + session.addMessageHandler(this); + session.setMaxIdleTimeout(500); + } + + @Override + public void onMessage(String message) + { + // echo message back (this is an indication of timeout failure) + session.getAsyncRemote().sendText(message); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenSocket.java new file mode 100644 index 00000000000..e6a10fb5373 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException; + +@ServerEndpoint(value = "/idle-onopen-socket") +public class IdleTimeoutOnOpenSocket +{ + @OnOpen + public void onOpen(Session session) + { + session.setMaxIdleTimeout(500); + } + + @OnMessage + public String onMessage(String msg) + { + return msg; + } + + @OnError + public void onError(Throwable cause) + { + if (!(cause instanceof WebSocketTimeoutException)) + throw new RuntimeException(cause); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/LargeEchoContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/LargeEchoContextListener.java new file mode 100644 index 00000000000..0794a7ad477 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/LargeEchoContextListener.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.websocket.server.ServerContainer; + +public class LargeEchoContextListener implements ServletContextListener +{ + @Override + public void contextDestroyed(ServletContextEvent sce) + { + /* do nothing */ + } + + @Override + public void contextInitialized(ServletContextEvent sce) + { + ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); + container.setDefaultMaxTextMessageBufferSize(128 * 1024); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/LargeEchoDefaultSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/LargeEchoDefaultSocket.java new file mode 100644 index 00000000000..a9a72a97b1b --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/LargeEchoDefaultSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/large") +public class LargeEchoDefaultSocket +{ + @OnMessage + public void echo(javax.websocket.Session session, String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/OnOpenIdleTimeoutEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/OnOpenIdleTimeoutEndpoint.java new file mode 100644 index 00000000000..5e9d4de2aa0 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/OnOpenIdleTimeoutEndpoint.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +public class OnOpenIdleTimeoutEndpoint extends Endpoint implements MessageHandler.Whole +{ + private Session session; + + @Override + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + session.addMessageHandler(this); + session.setMaxIdleTimeout(500); + } + + @Override + public void onMessage(String message) + { + // echo message back (this is an indication of timeout failure) + session.getAsyncRemote().sendText(message); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongContextListener.java new file mode 100644 index 00000000000..48010b4e91f --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongContextListener.java @@ -0,0 +1,61 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.websocket.DeploymentException; +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerContainer; +import javax.websocket.server.ServerEndpointConfig; + +public class PongContextListener implements ServletContextListener +{ + public static class Config extends ServerEndpointConfig.Configurator + { + @Override + public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) + { + sec.getUserProperties().put("path", sec.getPath()); + super.modifyHandshake(sec, request, response); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) + { + /* do nothing */ + } + + @Override + public void contextInitialized(ServletContextEvent sce) + { + ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); + try + { + ServerEndpointConfig.Configurator config = new Config(); + container.addEndpoint(ServerEndpointConfig.Builder.create(PongMessageEndpoint.class, "/pong").configurator(config).build()); + } + catch (DeploymentException e) + { + throw new RuntimeException("Unable to add endpoint directly", e); + } + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongMessageEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongMessageEndpoint.java new file mode 100644 index 00000000000..6be7d2a0522 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongMessageEndpoint.java @@ -0,0 +1,66 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.PongMessage; +import javax.websocket.Session; + +public class PongMessageEndpoint extends Endpoint implements MessageHandler.Whole +{ + private String path = "?"; + private Session session; + + @Override + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + this.session.addMessageHandler(this); + this.path = (String)config.getUserProperties().get("path"); + } + + @Override + public void onMessage(PongMessage pong) + { + byte[] buf = toArray(pong.getApplicationData()); + String message = new String(buf, StandardCharsets.UTF_8); + this.session.getAsyncRemote().sendText("PongMessageEndpoint.onMessage(PongMessage):[" + path + "]:" + message); + } + + public static byte[] toArray(ByteBuffer buffer) + { + if (buffer.hasArray()) + { + byte[] array = buffer.array(); + int from = buffer.arrayOffset() + buffer.position(); + return Arrays.copyOfRange(array, from, from + buffer.remaining()); + } + else + { + byte[] to = new byte[buffer.remaining()]; + buffer.slice().get(to); + return to; + } + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongSocket.java new file mode 100644 index 00000000000..ca5455ed18e --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/com/acme/websocket/PongSocket.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme.websocket; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import javax.websocket.EndpointConfig; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.PongMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/pong-socket", configurator = PongContextListener.Config.class) +public class PongSocket +{ + private String path = "?"; + private Session session; + + @OnOpen + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + this.path = (String)config.getUserProperties().get("path"); + } + + @OnMessage + public void onPong(PongMessage pong) + { + byte[] buf = toArray(pong.getApplicationData()); + String message = new String(buf, StandardCharsets.UTF_8); + this.session.getAsyncRemote().sendText("PongSocket.onPong(PongMessage)[" + path + "]:" + message); + } + + public static byte[] toArray(ByteBuffer buffer) + { + if (buffer.hasArray()) + { + byte[] array = buffer.array(); + int from = buffer.arrayOffset() + buffer.position(); + return Arrays.copyOfRange(array, from, from + buffer.remaining()); + } + else + { + byte[] to = new byte[buffer.remaining()]; + buffer.slice().get(to); + return to; + } + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JavaxOnCloseTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JavaxOnCloseTest.java new file mode 100644 index 00000000000..138266304c8 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JavaxOnCloseTest.java @@ -0,0 +1,214 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.net.URI; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import javax.websocket.ClientEndpoint; +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.EndpointConfig; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JavaxOnCloseTest +{ + private static BlockingArrayQueue serverEndpoints = new BlockingArrayQueue<>(); + + private Server server; + private ServerConnector connector; + private JavaxWebSocketClientContainer client = new JavaxWebSocketClientContainer(); + + @ServerEndpoint("/") + public static class OnCloseEndpoint extends EventSocket + { + private Consumer onClose; + + public void setOnClose(Consumer onClose) + { + this.onClose = onClose; + } + + @Override + public void onOpen(Session session, EndpointConfig endpointConfig) + { + super.onOpen(session, endpointConfig); + serverEndpoints.add(this); + } + + @Override + public void onClose(CloseReason reason) + { + super.onClose(reason); + onClose.accept(session); + } + } + + @ClientEndpoint + public static class BlockingClientEndpoint extends EventSocket + { + private CountDownLatch blockInClose = new CountDownLatch(1); + + public void unBlockClose() + { + blockInClose.countDown(); + } + + @Override + public void onClose(CloseReason reason) + { + try + { + blockInClose.await(); + super.onClose(reason); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + } + + @BeforeEach + public void start() throws Exception + { + server = new Server(); + connector = new ServerConnector(server); + connector.setPort(0); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + server.setHandler(contextHandler); + + JavaxWebSocketServletContainerInitializer.configure(contextHandler, ((servletContext, container) -> + container.addEndpoint(OnCloseEndpoint.class))); + + client.start(); + server.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + @Test + public void changeStatusCodeInOnClose() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connectToServer(clientEndpoint, uri); + + OnCloseEndpoint serverEndpoint = Objects.requireNonNull(serverEndpoints.poll(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> assertDoesNotThrow(() -> + session.close(new CloseReason(CloseCodes.SERVICE_RESTART, "custom close reason")))); + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + + clientEndpoint.session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseCodes.SERVICE_RESTART)); + assertThat(clientEndpoint.closeReason.getReasonPhrase(), is("custom close reason")); + } + + @Test + public void secondCloseFromOnCloseFails() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connectToServer(clientEndpoint, uri); + + OnCloseEndpoint serverEndpoint = Objects.requireNonNull(serverEndpoints.poll(5, TimeUnit.SECONDS)); + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> assertDoesNotThrow((Executable)session::close)); + + serverEndpoint.session.close(new CloseReason(CloseCodes.NORMAL_CLOSURE, "first close")); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseCodes.NORMAL_CLOSURE)); + assertThat(clientEndpoint.closeReason.getReasonPhrase(), is("first close")); + } + + @Test + public void abnormalStatusDoesNotChange() throws Exception + { + BlockingClientEndpoint clientEndpoint = new BlockingClientEndpoint(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connectToServer(clientEndpoint, uri); + + OnCloseEndpoint serverEndpoint = Objects.requireNonNull(serverEndpoints.poll(5, TimeUnit.SECONDS)); + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> + { + assertDoesNotThrow(() -> session.close(new CloseReason(CloseCodes.UNEXPECTED_CONDITION, "abnormal close 2"))); + clientEndpoint.unBlockClose(); + }); + + serverEndpoint.session.close(new CloseReason(CloseCodes.PROTOCOL_ERROR, "abnormal close 1")); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseCodes.PROTOCOL_ERROR)); + assertThat(clientEndpoint.closeReason.getReasonPhrase(), is("abnormal close 1")); + } + + @Test + public void onErrorOccurringAfterOnClose() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connectToServer(clientEndpoint, uri); + + OnCloseEndpoint serverEndpoint = Objects.requireNonNull(serverEndpoints.poll(5, TimeUnit.SECONDS)); + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> + { + throw new RuntimeException("trigger onError from onClose"); + }); + + clientEndpoint.session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseCodes.UNEXPECTED_CONDITION)); + assertThat(clientEndpoint.closeReason.getReasonPhrase(), containsString("trigger onError from onClose")); + + assertTrue(serverEndpoint.errorLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverEndpoint.error, instanceOf(RuntimeException.class)); + assertThat(serverEndpoint.error.getMessage(), containsString("trigger onError from onClose")); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java new file mode 100644 index 00000000000..4c48c350898 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/JettySpecificConfigTest.java @@ -0,0 +1,152 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.websocket.ClientEndpoint; +import javax.websocket.CloseReason; +import javax.websocket.ContainerProvider; +import javax.websocket.EndpointConfig; +import javax.websocket.HandshakeResponse; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpoint; +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JettySpecificConfigTest +{ + private Server _server; + private ServerConnector _connector; + private ServletContextHandler _context; + + @ServerEndpoint(value = "/", configurator = JettyServerConfigurator.class) + public static class EchoParamSocket + { + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + + JavaxWebSocketSession javaxSession = (JavaxWebSocketSession)session; + assertThat(javaxSession.getCoreSession().isAutoFragment(), is(false)); + assertThat(javaxSession.getCoreSession().getMaxFrameSize(), is(1337L)); + } + + @OnMessage + public void onMessage(String message) throws IOException + { + session.getBasicRemote().sendText(message); + } + } + + public static class JettyServerConfigurator extends ServerEndpointConfig.Configurator + { + @Override + public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) + { + Map userProperties = sec.getUserProperties(); + userProperties.put("org.eclipse.jetty.websocket.autoFragment", false); + userProperties.put("org.eclipse.jetty.websocket.maxFrameSize", 1337L); + } + } + + @ClientEndpoint + public static class ClientConfigSocket extends EventSocket + { + @Override + public void onOpen(Session session, EndpointConfig endpointConfig) + { + super.onOpen(session, endpointConfig); + Map userProperties = session.getUserProperties(); + userProperties.put("org.eclipse.jetty.websocket.autoFragment", false); + userProperties.put("org.eclipse.jetty.websocket.maxFrameSize", 1337L); + } + } + + @BeforeEach + public void startContainer() throws Exception + { + _server = new Server(); + _connector = new ServerConnector(_server); + _server.addConnector(_connector); + + _context = new ServletContextHandler(ServletContextHandler.SESSIONS); + _context.setContextPath("/"); + _server.setHandler(_context); + + JavaxWebSocketServletContainerInitializer.configure(_context, + (context, container) -> container.addEndpoint(EchoParamSocket.class)); + + _server.start(); + } + + @AfterEach + public void stopContainer() throws Exception + { + _server.stop(); + } + + @Test + public void testJettySpecificConfig() throws Exception + { + WebSocketContainer container = ContainerProvider.getWebSocketContainer(); + EventSocket clientEndpoint = new ClientConfigSocket(); + + URI serverUri = URI.create("ws://localhost:" + _connector.getLocalPort()); + Session session = container.connectToServer(clientEndpoint, serverUri); + + // Check correct client config is set. + JavaxWebSocketSession javaxSession = (JavaxWebSocketSession)session; + assertThat(javaxSession.getCoreSession().isAutoFragment(), is(false)); + assertThat(javaxSession.getCoreSession().getMaxFrameSize(), is(1337L)); + + // Send and receive an echo. + session.getBasicRemote().sendText("echo"); + String resp = clientEndpoint.textMessages.poll(1, TimeUnit.SECONDS); + assertThat("Response echo", resp, is("echo")); + + // Close the Session. + session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseReason.CloseCodes.NO_STATUS_CODE)); + assertNull(clientEndpoint.error); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java new file mode 100644 index 00000000000..2b3e28eeff8 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/PathParamTest.java @@ -0,0 +1,104 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.net.URI; +import java.util.concurrent.TimeUnit; +import javax.websocket.ContainerProvider; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class PathParamTest +{ + private Server _server; + private ServerConnector _connector; + private ServletContextHandler _context; + + @BeforeEach + public void startContainer() throws Exception + { + _server = new Server(); + _connector = new ServerConnector(_server); + _server.addConnector(_connector); + + _context = new ServletContextHandler(ServletContextHandler.SESSIONS); + _context.setContextPath("/"); + _server.setHandler(_context); + + JavaxWebSocketServletContainerInitializer.configure(_context, (context, container) -> + container.addEndpoint(EchoParamSocket.class)); + + _server.start(); + } + + @AfterEach + public void stopContainer() throws Exception + { + _server.stop(); + } + + @ServerEndpoint("/pathparam/echo/{name}") + public static class EchoParamSocket + { + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(String message, @PathParam("name") String name) + { + session.getAsyncRemote().sendText(message + "-" + name); + } + } + + @Test + public void testBasicPathParamSocket() throws Exception + { + WebSocketContainer container = ContainerProvider.getWebSocketContainer(); + EventSocket clientEndpoint = new EventSocket(); + + URI serverUri = URI.create("ws://localhost:" + _connector.getLocalPort() + "/pathparam/echo/myParam"); + Session session = container.connectToServer(clientEndpoint, serverUri); + session.getBasicRemote().sendText("echo"); + + String resp = clientEndpoint.textMessages.poll(1, TimeUnit.SECONDS); + assertThat("Response echo", resp, is("echo-myParam")); + session.close(); + clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/RestartContextTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/RestartContextTest.java similarity index 82% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/RestartContextTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/RestartContextTest.java index 2499f5a5017..dc845795664 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/RestartContextTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/RestartContextTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests; @@ -37,8 +37,8 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerContainer; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -56,7 +56,7 @@ public class RestartContextTest } @Test - public void testStartStopStart_ServletContextListener() throws Exception + public void testStartStopStartServletContextListener() throws Exception { server = new Server(); @@ -96,7 +96,7 @@ public class RestartContextTest } @Test - public void testStartStopStart_Configurator() throws Exception + public void testStartStopStartConfigurator() throws Exception { server = new Server(); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java new file mode 100644 index 00000000000..8c03beb12ee --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ServerConfigTest.java @@ -0,0 +1,137 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests; + +import java.io.IOException; +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.ContainerProvider; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ServerConfigTest +{ + private Server server; + private WebSocketContainer client; + private ServerConnector connector; + + private static final long idleTimeout = 500; + private static final int maxTextMessageSize = 50; + private static final int maxBinaryMessageSize = 60; + private static final long asyncSendTimeout = 200; + + @BeforeEach + public void start() throws Exception + { + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + server.setHandler(contextHandler); + + JavaxWebSocketServletContainerInitializer.configure(contextHandler, (context, container) -> + { + container.setDefaultMaxSessionIdleTimeout(idleTimeout); + container.setDefaultMaxTextMessageBufferSize(maxTextMessageSize); + container.setDefaultMaxBinaryMessageBufferSize(maxBinaryMessageSize); + container.setAsyncSendTimeout(asyncSendTimeout); + container.addEndpoint(ConfigTestSocket.class); + container.addEndpoint(AnnotatedOnMessageSocket.class); + }); + + server.start(); + client = ContainerProvider.getWebSocketContainer(); + } + + @AfterEach + public void stop() throws Exception + { + server.stop(); + } + + @ServerEndpoint("/containerDefaults") + public static class ConfigTestSocket + { + @OnOpen + public void onOpen(Session session) + { + assertThat(session.getMaxIdleTimeout(), is(idleTimeout)); + assertThat(session.getMaxTextMessageBufferSize(), is(maxTextMessageSize)); + assertThat(session.getMaxBinaryMessageBufferSize(), is(maxBinaryMessageSize)); + assertThat(session.getAsyncRemote().getSendTimeout(), is(asyncSendTimeout)); + } + } + + @ServerEndpoint("/annotatedOnMessage") + public static class AnnotatedOnMessageSocket + { + @OnOpen + public void onOpen(Session session) + { + assertThat(session.getMaxTextMessageBufferSize(), is(111)); + assertThat(session.getMaxBinaryMessageBufferSize(), is(maxBinaryMessageSize)); + } + + @OnMessage(maxMessageSize = 111) + public void onMessage(String message) throws IOException + { + } + + @OnMessage() + public void onMessage(ByteBuffer message) throws IOException + { + } + } + + @ParameterizedTest + @ValueSource(strings = {"/containerDefaults", "/annotatedOnMessage"}) + public void testEndpointSettings(String path) throws Exception + { + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + path); + EventSocket clientEndpoint = new EventSocket(); + client.connectToServer(clientEndpoint, uri); + + clientEndpoint.openLatch.await(5, TimeUnit.SECONDS); + clientEndpoint.session.close(new CloseReason(CloseCodes.NORMAL_CLOSURE, "normal close")); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseCodes.NORMAL_CLOSURE)); + assertThat(clientEndpoint.closeReason.getReasonPhrase(), is("normal close")); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java new file mode 100644 index 00000000000..2b38da9946d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnClient.java @@ -0,0 +1,200 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.autobahn; + +import java.net.URI; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; + +import org.eclipse.jetty.util.Jetty; +import org.eclipse.jetty.util.UrlEncoded; +import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.javax.tests.EventSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * WebSocket Client for use with autobahn websocket testsuite (wstest). + *

      + * Installing Autobahn: + *

      + *
      + *    # For Debian / Ubuntu
      + *    $ sudo apt-get install python python-dev python-twisted
      + *    $ sudo apt-get install python-pip
      + *    $ sudo pip install autobahntestsuite
      + *
      + *    # For Fedora / Redhat
      + *    $ sudo yum install python python-dev python-pip twisted
      + *    $ sudo yum install libffi-devel
      + *    $ sudo pip install autobahntestsuite
      + * 
      + *

      + * Upgrading an existing installation of autobahntestsuite + *

      + *
      + *     $ sudo pip install -U autobahntestsuite
      + * 
      + *

      + * Running Autobahn Fuzzing Server (which you run this client implementation against): + *

      + *
      + *     # Change to websocket-javax-tests directory first.
      + *     $ cd jetty-websocket/websocket-javax-tests/
      + *     $ wstest --mode=fuzzingserver --spec=fuzzingserver.json
      + *
      + *     # Report output is configured (in the fuzzingserver.json) at location:
      + *     $ ls target/reports/clients/
      + * 
      + */ +public class JavaxAutobahnClient +{ + public static void main(String[] args) + { + String hostname = "localhost"; + int port = 9001; + + if (args.length > 0) + hostname = args[0]; + if (args.length > 1) + port = Integer.parseInt(args[1]); + + // Optional case numbers + // NOTE: these are url query parameter case numbers (whole integers, eg "6"), not the case ids (eg "7.3.1") + int[] caseNumbers = null; + if (args.length > 2) + { + int offset = 2; + caseNumbers = new int[args.length - offset]; + for (int i = offset; i < args.length; i++) + { + caseNumbers[i - offset] = Integer.parseInt(args[i]); + } + } + + JavaxAutobahnClient client = null; + try + { + String userAgent = "JettyWebsocketClient/" + Jetty.VERSION; + client = new JavaxAutobahnClient(hostname, port, userAgent); + + LOG.info("Running test suite..."); + LOG.info("Using Fuzzing Server: {}:{}", hostname, port); + LOG.info("User Agent: {}", userAgent); + + if (caseNumbers == null) + { + int caseCount = client.getCaseCount(); + LOG.info("Will run all {} cases ...", caseCount); + for (int caseNum = 1; caseNum <= caseCount; caseNum++) + { + LOG.info("Running case {} (of {}) ...", caseNum, caseCount); + client.runCaseByNumber(caseNum); + } + } + else + { + LOG.info("Will run %d cases ...", caseNumbers.length); + for (int caseNum : caseNumbers) + { + client.runCaseByNumber(caseNum); + } + } + LOG.info("All test cases executed."); + client.updateReports(); + } + catch (Throwable t) + { + LOG.warn("Test Failed", t); + } + finally + { + if (client != null) + client.stop(); + } + } + + private static final Logger LOG = LoggerFactory.getLogger(JavaxAutobahnClient.class); + private URI baseWebsocketUri; + private JavaxWebSocketClientContainer clientContainer; + private String userAgent; + + public JavaxAutobahnClient(String hostname, int port, String userAgent) throws Exception + { + this.userAgent = userAgent; + this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port); + this.clientContainer = new JavaxWebSocketClientContainer(); + clientContainer.start(); + } + + public void stop() + { + LifeCycle.stop(clientContainer); + } + + public int getCaseCount() + { + URI wsUri = baseWebsocketUri.resolve("/getCaseCount"); + EventSocket onCaseCount = new EventSocket(); + + try + { + clientContainer.connectToServer(onCaseCount, wsUri); + String msg = onCaseCount.textMessages.poll(10, TimeUnit.SECONDS); + onCaseCount.session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, null)); + assertTrue(onCaseCount.closeLatch.await(2, TimeUnit.SECONDS)); + assertNotNull(msg); + return Integer.decode(msg); + } + catch (Throwable t) + { + throw new IllegalStateException("Unable to get Case Count", t); + } + } + + public void runCaseByNumber(int caseNumber) throws Exception + { + URI wsUri = baseWebsocketUri.resolve("/runCase?case=" + caseNumber + "&agent=" + UrlEncoded.encodeString(userAgent)); + LOG.info("test uri: {}", wsUri); + + JavaxAutobahnSocket echoHandler = new JavaxAutobahnSocket(); + clientContainer.connectToServer(echoHandler, wsUri); + + // Wait up to 5 min as some of the tests can take a while + if (!echoHandler.closeLatch.await(5, TimeUnit.MINUTES)) + { + LOG.warn("could not close {}, closing session", echoHandler); + echoHandler.session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, null)); + } + } + + public void updateReports() throws Exception + { + URI wsUri = baseWebsocketUri.resolve("/updateReports?agent=" + UrlEncoded.encodeString(userAgent)); + EventSocket onUpdateReports = new EventSocket(); + clientContainer.connectToServer(onUpdateReports, wsUri); + assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS)); + LOG.info("Reports updated."); + LOG.info("Test suite finished!"); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnServer.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnServer.java new file mode 100644 index 00000000000..f57163e94a0 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnServer.java @@ -0,0 +1,82 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.autobahn; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; + +/** + * WebSocket Server for use with autobahn websocket testsuite (wstest). + *

      + * Installing Autobahn: + *

      + *
      + *    # For Debian / Ubuntu
      + *    $ sudo apt-get install python python-dev python-twisted
      + *    $ sudo apt-get install python-pip
      + *    $ sudo pip install autobahntestsuite
      + *
      + *    # For Fedora / Redhat
      + *    $ sudo yum install python python-dev python-pip twisted
      + *    $ sudo yum install libffi-devel
      + *    $ sudo pip install autobahntestsuite
      + * 
      + *

      + * Upgrading an existing installation of autobahntestsuite + *

      + *
      + *     $ sudo pip install -U autobahntestsuite
      + * 
      + *

      + * Running Autobahn Fuzzing Client (against this server implementation): + *

      + *
      + *     # Change to websocket-javax-tests directory first.
      + *     $ cd jetty-websocket/websocket-javax-tests/
      + *     $ wstest --mode=fuzzingclient --spec=fuzzingclient.json
      + *
      + *     # Report output is configured (in the fuzzingclient.json) at location:
      + *     $ ls target/reports/servers/
      + * 
      + */ +public class JavaxAutobahnServer +{ + public static void main(String[] args) throws Exception + { + int port = 9001; // same port as found in fuzzing-client.json + if (args != null && args.length > 0) + port = Integer.parseInt(args[0]); + + Server server = new Server(port); + ServerConnector connector = new ServerConnector(server); + connector.setIdleTimeout(10000); + server.addConnector(connector); + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + server.setHandler(context); + + JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, container) -> + container.addEndpoint(JavaxAutobahnSocket.class)); + + server.start(); + server.join(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnSocket.java new file mode 100644 index 00000000000..5e5f239be36 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/autobahn/JavaxAutobahnSocket.java @@ -0,0 +1,76 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.autobahn; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.concurrent.CountDownLatch; +import javax.websocket.ClientEndpoint; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ClientEndpoint +@ServerEndpoint("/") +public class JavaxAutobahnSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(JavaxAutobahnSocket.class); + + public Session session; + public CountDownLatch closeLatch = new CountDownLatch(1); + + @OnOpen + public void onConnect(Session session) + { + this.session = session; + session.setMaxTextMessageBufferSize(Integer.MAX_VALUE); + session.setMaxBinaryMessageBufferSize(Integer.MAX_VALUE); + } + + @OnMessage + public void onText(String message) throws IOException + { + session.getBasicRemote().sendText(message); + } + + @OnMessage + public void onBinary(ByteBuffer message) throws IOException + { + session.getBasicRemote().sendBinary(message); + } + + @OnError + public void onError(Throwable t) + { + if (LOG.isDebugEnabled()) + LOG.debug("onError()", t); + } + + @OnClose + public void onClose() + { + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java similarity index 54% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java index ac8074a647a..1c94084f950 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.javax.client.internal.BasicClientEndpointConfig; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; @@ -42,9 +43,8 @@ public abstract class AbstractClientSessionTest Object websocketPojo = new DummyEndpoint(); UpgradeRequest upgradeRequest = new UpgradeRequestAdapter(); JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(websocketPojo, upgradeRequest); - FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty(); - session = new JavaxWebSocketSession(container, coreSession, frameHandler, null); - container.addManaged(session); + CoreSession coreSession = new CoreSession.Empty(); + session = new JavaxWebSocketSession(container, coreSession, frameHandler, new BasicClientEndpointConfig()); } @AfterAll diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedClientEndpointTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedClientEndpointTest.java new file mode 100644 index 00000000000..5c419efa440 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedClientEndpointTest.java @@ -0,0 +1,179 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.client; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.Date; +import javax.websocket.ClientEndpoint; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.ContainerProvider; +import javax.websocket.EndpointConfig; +import javax.websocket.HandshakeResponse; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; + +import org.eclipse.jetty.websocket.javax.tests.CoreServer; +import org.eclipse.jetty.websocket.javax.tests.coders.DateDecoder; +import org.eclipse.jetty.websocket.javax.tests.coders.TimeEncoder; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static java.util.stream.Collectors.joining; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AnnotatedClientEndpointTest +{ + @ClientEndpoint( + subprotocols = {"chat", "echo-whole"}, + decoders = {DateDecoder.class}, + encoders = {TimeEncoder.class}, + configurator = AnnotatedEndpointConfigurator.class) + public static class AnnotatedEndpointClient + { + public Session session; + public EndpointConfig config; + + @OnOpen + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + this.config = config; + } + + @OnMessage(maxMessageSize = 111222) + public void onText(Date date) + { + /* do nothing - just a test of DateDecoder wiring */ + } + + @OnMessage(maxMessageSize = 333444) + public Date onBinary(ByteBuffer buf) + { + /* do nothing - just a test of TimeEncoder wiring */ + return null; + } + } + + public static class AnnotatedEndpointConfigurator extends ClientEndpointConfig.Configurator + { + @Override + public void afterResponse(HandshakeResponse hr) + { + hr.getHeaders().put("X-Test", Collections.singletonList("Extra")); + super.afterResponse(hr); + } + } + + private static CoreServer server; + private static ClientEndpointConfig config; + private static AnnotatedEndpointClient clientEndpoint; + + @BeforeAll + public static void startEnv() throws Exception + { + // Server + server = new CoreServer(new CoreServer.EchoNegotiator()); + + // Start Server + server.start(); + + // Create Client + WebSocketContainer container = ContainerProvider.getWebSocketContainer(); + server.addBean(container); // allow to shutdown with server + + // Connect to Server + clientEndpoint = new AnnotatedEndpointClient(); + assertNotNull(container.connectToServer(clientEndpoint, server.getWsUri())); + assertNotNull(clientEndpoint.config); + assertThat(clientEndpoint.config, instanceOf(ClientEndpointConfig.class)); + config = (ClientEndpointConfig)clientEndpoint.config; + } + + @AfterAll + public static void stopEnv() + { + // Close Session + try + { + if (clientEndpoint.session != null) + clientEndpoint.session.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + // Stop Server + try + { + server.stop(); + } + catch (Exception e) + { + e.printStackTrace(System.err); + } + } + + @Test + public void testTextMax() throws Exception + { + assertThat(clientEndpoint.session.getMaxTextMessageBufferSize(), is(111222)); + } + + @Test + public void testBinaryMax() throws Exception + { + assertThat(clientEndpoint.session.getMaxBinaryMessageBufferSize(), is(333444)); + } + + @Test + public void testSubProtocols() throws Exception + { + String subprotocols = String.join(", ", config.getPreferredSubprotocols()); + assertThat(subprotocols, is("chat, echo-whole")); + } + + @Test + public void testDecoders() throws Exception + { + String decoders = config.getDecoders().stream().map(Class::getName).collect(joining(", ")); + assertThat(decoders, is(DateDecoder.class.getName())); + } + + @Test + public void testEncoders() throws Exception + { + String encoders = config.getEncoders().stream().map(Class::getName).collect(joining(", ")); + assertThat(encoders, is(TimeEncoder.class.getName())); + } + + @Test + public void testConfigurator() throws Exception + { + assertThat(config.getConfigurator(), instanceOf(AnnotatedEndpointConfigurator.class)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoClient.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoClient.java similarity index 57% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoClient.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoClient.java index 88122bc0165..94ce4dc6b67 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoClient.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoTest.java similarity index 86% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoTest.java index 5d1915fe852..4b87604ea77 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AnnotatedEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/ConfiguratorTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/ConfiguratorTest.java similarity index 82% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/ConfiguratorTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/ConfiguratorTest.java index f8107ebd5c8..b317d9fb6ba 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/ConfiguratorTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/ConfiguratorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/CookiesTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/CookiesTest.java similarity index 88% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/CookiesTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/CookiesTest.java index 9702a7b166b..86434f4204e 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/CookiesTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/CookiesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DecoderReaderManySmallTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DecoderReaderManySmallTest.java similarity index 69% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DecoderReaderManySmallTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DecoderReaderManySmallTest.java index 1de873294be..caf99771299 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DecoderReaderManySmallTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DecoderReaderManySmallTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; @@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.javax.tests.client; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; -import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; @@ -37,15 +36,13 @@ import javax.websocket.Session; import javax.websocket.WebSocketContainer; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.MessageHandler; -import org.eclipse.jetty.websocket.core.server.Negotiation; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; import org.eclipse.jetty.websocket.javax.tests.CoreServer; import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInfo; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -58,21 +55,14 @@ public class DecoderReaderManySmallTest @BeforeEach public void setUp() throws Exception { - server = new CoreServer(new CoreServer.BaseNegotiator() + server = new CoreServer(WebSocketNegotiator.from((negotiation) -> { - @Override - public FrameHandler negotiate(Negotiation negotiation) throws IOException - { - List offeredSubProtocols = negotiation.getOfferedSubprotocols(); + List offeredSubProtocols = negotiation.getOfferedSubprotocols(); + if (!offeredSubProtocols.isEmpty()) + negotiation.setSubprotocol(offeredSubProtocols.get(0)); - if (!offeredSubProtocols.isEmpty()) - { - negotiation.setSubprotocol(offeredSubProtocols.get(0)); - } - - return new EventIdFrameHandler(); - } - }); + return new EventIdFrameHandler(); + })); server.start(); client = ContainerProvider.getWebSocketContainer(); @@ -86,15 +76,13 @@ public class DecoderReaderManySmallTest } @Test - public void testManyIds(TestInfo testInfo) throws Exception + public void testManyIds() throws Exception { - URI wsUri = server.getWsUri().resolve("/eventids"); - EventIdSocket clientSocket = new EventIdSocket(testInfo.getTestMethod().toString()); - final int from = 1000; final int to = 2000; - try (Session clientSession = client.connectToServer(clientSocket, wsUri)) + EventIdSocket clientSocket = new EventIdSocket(); + try (Session clientSession = client.connectToServer(clientSocket, server.getWsUri())) { clientSession.getAsyncRemote().sendText("seq|" + from + "|" + to); } @@ -154,12 +142,6 @@ public class DecoderReaderManySmallTest { public BlockingQueue messageQueue = new LinkedBlockingDeque<>(); - public EventIdSocket(String id) - { - super(id); - } - - @SuppressWarnings("unused") @OnMessage public void onMessage(EventId msg) { diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DelayedStartClientTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DelayedStartClientTest.java similarity index 79% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DelayedStartClientTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DelayedStartClientTest.java index 4d1d9737f22..8307148ba82 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DelayedStartClientTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/DelayedStartClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/EndpointEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/EndpointEchoTest.java similarity index 77% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/EndpointEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/EndpointEchoTest.java index fb3224508de..39066ed9167 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/EndpointEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/EndpointEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; @@ -77,7 +77,7 @@ public class EndpointEchoTest ClientEndpoint clientEndpoint = new ClientEndpoint(); assertThat(clientEndpoint, Matchers.instanceOf(javax.websocket.Endpoint.class)); // Issue connect using instance of class that extends Endpoint - Session session = container.connectToServer(clientEndpoint, server.getWsUri().resolve("/echo/text")); + Session session = container.connectToServer(clientEndpoint, null, server.getWsUri().resolve("/echo/text")); session.getBasicRemote().sendText("Echo"); String resp = clientEndpoint.messageQueue.poll(1, TimeUnit.SECONDS); @@ -91,7 +91,7 @@ public class EndpointEchoTest { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); // Issue connect using class reference (class extends Endpoint) - Session session = container.connectToServer(ClientEndpoint.class, server.getWsUri().resolve("/echo/text")); + Session session = container.connectToServer(ClientEndpoint.class, null, server.getWsUri().resolve("/echo/text")); session.getBasicRemote().sendText("Echo"); JavaxWebSocketSession jsrSession = (JavaxWebSocketSession)session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientEchoTrackingSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientEchoTrackingSocket.java similarity index 63% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientEchoTrackingSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientEchoTrackingSocket.java index a3365374495..ff3522b55ff 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientEchoTrackingSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientEchoTrackingSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientTrackingSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientTrackingSocket.java similarity index 62% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientTrackingSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientTrackingSocket.java index c533f440b4a..84241075903 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientTrackingSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/JsrClientTrackingSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/MessageReceivingTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/MessageReceivingTest.java similarity index 93% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/MessageReceivingTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/MessageReceivingTest.java index 62bbace21bd..5161bf2c05e 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/MessageReceivingTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/MessageReceivingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; @@ -28,7 +28,6 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; - import javax.websocket.ClientEndpointConfig; import javax.websocket.CloseReason; import javax.websocket.ContainerProvider; @@ -40,21 +39,22 @@ import javax.websocket.WebSocketContainer; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.MessageHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.server.Negotiation; -import org.eclipse.jetty.websocket.javax.common.util.TextUtil; import org.eclipse.jetty.websocket.javax.tests.CoreServer; import org.eclipse.jetty.websocket.javax.tests.DataUtils; +import org.eclipse.jetty.websocket.util.TextUtil; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.MatcherAssert.assertThat; @@ -66,7 +66,7 @@ import static org.hamcrest.Matchers.is; */ public class MessageReceivingTest { - private static final Logger LOG = Log.getLogger(MessageReceivingTest.class); + private static final Logger LOG = LoggerFactory.getLogger(MessageReceivingTest.class); private static CoreServer server; private WebSocketContainer container; @@ -305,7 +305,7 @@ public class MessageReceivingTest @Override public void onError(Throwable cause, Callback callback) { - LOG.warn(cause); + LOG.warn("SendPartialBinaryFrameHandler Error", cause); callback.succeeded(); } } @@ -337,7 +337,7 @@ public class MessageReceivingTest @Override public void onError(Throwable cause, Callback callback) { - LOG.warn(cause); + LOG.warn("EchoWholeMessageFrameHandler Error", cause); callback.succeeded(); } } @@ -380,7 +380,7 @@ public class MessageReceivingTest } @Override - public void customize(FrameHandler.Configuration configurable) + public void customize(Configuration configurable) { configurable.setMaxBinaryMessageSize(MAX_MESSAGE_SIZE); configurable.setMaxTextMessageSize(MAX_MESSAGE_SIZE); @@ -414,7 +414,7 @@ public class MessageReceivingTest @Override public void onError(Session session, Throwable thr) { - LOG.warn(thr); + LOG.warn("TestEndpoint Error", thr); } } @@ -477,7 +477,7 @@ public class MessageReceivingTest @Override public void onMessage(ByteBuffer message) { - final String stringResult = new String(message.array()); + final String stringResult = BufferUtil.toString(message); messageQueue.offer(stringResult); } } diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/OnCloseTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/OnCloseTest.java similarity index 76% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/OnCloseTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/OnCloseTest.java index 4076260ce6c..7c9ca2e19b8 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/OnCloseTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/OnCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; @@ -26,9 +26,9 @@ import javax.websocket.ClientEndpointConfig; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.websocket.core.CloseStatus; -import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig; -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.javax.client.internal.BasicClientEndpointConfig; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; import org.eclipse.jetty.websocket.javax.common.UpgradeRequestAdapter; @@ -96,7 +96,7 @@ public class OnCloseTest { WSEventTracker endpoint = (WSEventTracker)testcase.closeClass.getConstructor().newInstance(); - ClientEndpointConfig config = new EmptyClientEndpointConfig(); + ClientEndpointConfig config = new BasicClientEndpointConfig(); // TODO: use ConfiguredEndpoint here? JavaxWebSocketClientContainer container = new JavaxWebSocketClientContainer(); @@ -104,7 +104,7 @@ public class OnCloseTest UpgradeRequest request = new UpgradeRequestAdapter(); JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(endpoint, request); - frameHandler.onOpen(new FrameHandler.CoreSession.Empty(), Callback.NOOP); + frameHandler.onOpen(new CoreSession.Empty(), Callback.NOOP); // Execute onClose call frameHandler.onFrame(CloseStatus.toFrame(CloseStatus.NORMAL), Callback.NOOP); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java similarity index 88% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java index 3bd87fe4d6f..f980f1cd3e6 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client; @@ -27,12 +27,12 @@ import javax.websocket.MessageHandler; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig; -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer; -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientFrameHandlerFactory; +import org.eclipse.jetty.websocket.javax.client.internal.BasicClientEndpointConfig; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientFrameHandlerFactory; import org.eclipse.jetty.websocket.javax.common.ConfiguredEndpoint; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory; @@ -71,24 +71,22 @@ public class SessionAddMessageHandlerTest // Container container = new JavaxWebSocketClientContainer(); container.start(); - ClientEndpointConfig endpointConfig = new EmptyClientEndpointConfig(); + ClientEndpointConfig endpointConfig = new BasicClientEndpointConfig(); ConfiguredEndpoint ei = new ConfiguredEndpoint(new DummyEndpoint(), endpointConfig); UpgradeRequest handshakeRequest = new UpgradeRequestAdapter(); JavaxWebSocketFrameHandlerFactory frameHandlerFactory = new JavaxWebSocketClientFrameHandlerFactory(container); frameHandler = frameHandlerFactory.newJavaxWebSocketFrameHandler(ei, handshakeRequest); - frameHandler.onOpen(new FrameHandler.CoreSession.Empty(), Callback.NOOP); + frameHandler.onOpen(new CoreSession.Empty(), Callback.NOOP); // Session session = frameHandler.getSession(); - session.start(); } @AfterEach public void stopSession() throws Exception { - session.stop(); container.stop(); } @@ -221,7 +219,7 @@ public class SessionAddMessageHandlerTest * Test Java 8 Lamba of {@link javax.websocket.MessageHandler.Whole} */ @Test - public void testMessageHandler_11_WholeLambda() throws Exception + public void testMessageHandler11WholeLambda() throws Exception { final List received = new ArrayList<>(); @@ -246,7 +244,7 @@ public class SessionAddMessageHandlerTest * Test Java 8 Lamba of {@link javax.websocket.MessageHandler.Partial} */ @Test - public void testMessageHandler_11_PartialLambda() throws Exception + public void testMessageHandler11PartialLambda() throws Exception { final List received = new ArrayList<>(); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/WriteTimeoutTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/WriteTimeoutTest.java new file mode 100644 index 00000000000..ca53d60dd66 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/WriteTimeoutTest.java @@ -0,0 +1,100 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.client; + +import java.util.concurrent.TimeUnit; +import javax.websocket.EndpointConfig; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.websocket.core.exception.WebSocketWriteTimeoutException; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer; +import org.eclipse.jetty.websocket.javax.tests.EventSocket; +import org.eclipse.jetty.websocket.javax.tests.LocalServer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class WriteTimeoutTest +{ + @ServerEndpoint("/logSocket") + public static class ServerSocket extends EventSocket + { + @Override + public void onOpen(Session session, EndpointConfig endpointConfig) + { + session.setMaxIdleTimeout(-1); + session.setMaxTextMessageBufferSize(-1); + super.onOpen(session, endpointConfig); + } + } + + private LocalServer server; + private JavaxWebSocketContainer client; + + @BeforeEach + public void start() throws Exception + { + server = new LocalServer(); + server.start(); + server.getServerContainer().addEndpoint(ServerSocket.class); + + client = new JavaxWebSocketClientContainer(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + @Test + public void testTimeoutOnLargeMessage() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + Session session = client.connectToServer(clientEndpoint, server.getWsUri().resolve("/logSocket")); + + session.getAsyncRemote().setSendTimeout(5); + session.setMaxTextMessageBufferSize(1024 * 1024 * 6); + + String string = "xxxxxxx"; + StringBuilder sb = new StringBuilder(); + while (sb.length() < session.getMaxTextMessageBufferSize() - string.length()) + { + sb.append(string); + } + string = sb.toString(); + + while (session.isOpen()) + { + session.getAsyncRemote().sendText(string); + } + + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientEndpoint.errorLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.error, instanceOf(WebSocketWriteTimeoutException.class)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java similarity index 59% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java index 95dc658ada0..79cecff7216 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client.misbehaving; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/EndpointRuntimeOnOpen.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/EndpointRuntimeOnOpen.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/EndpointRuntimeOnOpen.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/EndpointRuntimeOnOpen.java index 9413524e887..4612678fb63 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/EndpointRuntimeOnOpen.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/EndpointRuntimeOnOpen.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client.misbehaving; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java similarity index 72% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java index f83163d2c73..d59fa0d0648 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client.misbehaving; @@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit; import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.eclipse.jetty.websocket.javax.tests.CoreServer; import org.junit.jupiter.api.AfterEach; @@ -60,7 +60,7 @@ public class MisbehavingClassTest try (StacklessLogging ignored = new StacklessLogging(WebSocketCoreSession.class)) { // expecting RuntimeException during onOpen - container.connectToServer(socket, server.getWsUri()); + container.connectToServer(socket, null, server.getWsUri()); assertThat("Close should have occurred", socket.closeLatch.await(1, TimeUnit.SECONDS), is(true)); Throwable cause = socket.errors.pop(); assertThat("Error", cause, instanceOf(RuntimeException.class)); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseEndpointConfigSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseEndpointConfigSocket.java similarity index 52% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseEndpointConfigSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseEndpointConfigSocket.java index c230c3c7152..325898b71b9 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseEndpointConfigSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseEndpointConfigSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client.samples; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSessionSocket.java similarity index 50% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSessionSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSessionSocket.java index 29bbfdd6c74..64728894833 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSessionSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSessionSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client.samples; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSocket.java new file mode 100644 index 00000000000..a3e49b80992 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseReasonSocket.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.client.samples; + +import javax.websocket.ClientEndpoint; +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnOpen; +import javax.websocket.Session; + +import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; + +@ClientEndpoint +public class CloseReasonSocket extends WSEventTracker +{ + @OnOpen + public void onOpen(Session session) + { + super.onWsOpen(session); + } + + @OnError + public void onError(Throwable cause) + { + super.onWsError(cause); + } + + @OnClose + public void onClose(CloseReason reason) + { + addEvent("onClose(CloseReason)"); + super.onWsClose(reason); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionReasonSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionReasonSocket.java similarity index 50% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionReasonSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionReasonSocket.java index 49ec53ee88c..005e7628bb3 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionReasonSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionReasonSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.client.samples; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionSocket.java new file mode 100644 index 00000000000..7f93af19c39 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSessionSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.client.samples; + +import javax.websocket.ClientEndpoint; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnOpen; +import javax.websocket.Session; + +import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; + +@ClientEndpoint +public class CloseSessionSocket extends WSEventTracker +{ + @OnOpen + public void onOpen(Session session) + { + super.onWsOpen(session); + } + + @OnError + public void onError(Throwable cause) + { + super.onWsError(cause); + } + + @OnClose + public void onClose(Session session) + { + addEvent("onClose(Session)"); + super.onWsClose(null); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSocket.java new file mode 100644 index 00000000000..25acfc30abb --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/CloseSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.client.samples; + +import javax.websocket.ClientEndpoint; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnOpen; +import javax.websocket.Session; + +import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; + +@ClientEndpoint +public class CloseSocket extends WSEventTracker +{ + @OnOpen + public void onOpen(Session session) + { + super.onWsOpen(session); + } + + @OnError + public void onError(Throwable cause) + { + super.onWsError(cause); + } + + @OnClose + public void onClose() + { + addEvent("onClose()"); + super.onWsClose(null); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/IntSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/IntSocket.java new file mode 100644 index 00000000000..8ae2be5db14 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/samples/IntSocket.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.client.samples; + +import java.io.IOException; +import javax.websocket.ClientEndpoint; +import javax.websocket.EncodeException; +import javax.websocket.OnMessage; +import javax.websocket.Session; + +import org.eclipse.jetty.websocket.javax.tests.coders.BadDualDecoder; + +@ClientEndpoint(decoders = BadDualDecoder.class) +public class IntSocket +{ + @OnMessage + public void onInt(Session session, int value) + { + try + { + session.getBasicRemote().sendObject(value); + } + catch (IOException | EncodeException e) + { + e.printStackTrace(); + } + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableDecodersTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableDecodersTest.java similarity index 72% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableDecodersTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableDecodersTest.java index b57b76608dd..ff8050c6bbf 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableDecodersTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableDecodersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -28,10 +28,10 @@ import javax.websocket.Decoder; import javax.websocket.EndpointConfig; import org.eclipse.jetty.toolchain.test.Hex; -import org.eclipse.jetty.websocket.javax.common.BasicEndpointConfig; -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; +import org.eclipse.jetty.websocket.javax.client.internal.BasicClientEndpointConfig; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; import org.eclipse.jetty.websocket.javax.common.decoders.IntegerDecoder; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -49,7 +49,7 @@ public class AvailableDecodersTest @BeforeAll public static void initConfig() { - testConfig = new BasicEndpointConfig(); + testConfig = new BasicClientEndpointConfig(); } private AvailableDecoders decoders = new AvailableDecoders(testConfig); @@ -72,112 +72,112 @@ public class AvailableDecodersTest } @Test - public void testCoreDecode_Boolean() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeBoolean() throws IllegalAccessException, InstantiationException, DecodeException { Boolean expected = Boolean.TRUE; assertTextDecoder(Boolean.class, "true", expected); } @Test - public void testCoreDecode_boolean() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeboolean() throws IllegalAccessException, InstantiationException, DecodeException { boolean expected = false; assertTextDecoder(Boolean.TYPE, "false", expected); } @Test - public void testCoreDecode_Byte() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeByte() throws IllegalAccessException, InstantiationException, DecodeException { Byte expected = (byte)0x21; assertTextDecoder(Byte.class, "33", expected); } @Test - public void testCoreDecode_byte() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodebyte() throws IllegalAccessException, InstantiationException, DecodeException { byte expected = 0x21; assertTextDecoder(Byte.TYPE, "33", expected); } @Test - public void testCoreDecode_Character() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeCharacter() throws IllegalAccessException, InstantiationException, DecodeException { Character expected = '!'; assertTextDecoder(Character.class, "!", expected); } @Test - public void testCoreDecode_char() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodechar() throws IllegalAccessException, InstantiationException, DecodeException { char expected = '!'; assertTextDecoder(Character.TYPE, "!", expected); } @Test - public void testCoreDecode_Double() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeDouble() throws IllegalAccessException, InstantiationException, DecodeException { Double expected = 123.45D; assertTextDecoder(Double.class, "123.45", expected); } @Test - public void testCoreDecode_double() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodedouble() throws IllegalAccessException, InstantiationException, DecodeException { double expected = 123.45D; assertTextDecoder(Double.TYPE, "123.45", expected); } @Test - public void testCoreDecode_Float() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeFloat() throws IllegalAccessException, InstantiationException, DecodeException { Float expected = 123.4567F; assertTextDecoder(Float.class, "123.4567", expected); } @Test - public void testCoreDecode_float() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodefloat() throws IllegalAccessException, InstantiationException, DecodeException { float expected = 123.4567F; assertTextDecoder(Float.TYPE, "123.4567", expected); } @Test - public void testCoreDecode_Integer() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeInteger() throws IllegalAccessException, InstantiationException, DecodeException { Integer expected = 1234; assertTextDecoder(Integer.class, "1234", expected); } @Test - public void testCoreDecode_int() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeint() throws IllegalAccessException, InstantiationException, DecodeException { int expected = 1234; assertTextDecoder(Integer.TYPE, "1234", expected); } @Test - public void testCoreDecode_Long() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeLong() throws IllegalAccessException, InstantiationException, DecodeException { Long expected = 123_456_789L; assertTextDecoder(Long.class, "123456789", expected); } @Test - public void testCoreDecode_long() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodelong() throws IllegalAccessException, InstantiationException, DecodeException { long expected = 123_456_789L; assertTextDecoder(Long.TYPE, "123456789", expected); } @Test - public void testCoreDecode_String() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeString() throws IllegalAccessException, InstantiationException, DecodeException { String expected = "Hello World"; assertTextDecoder(String.class, "Hello World", expected); } @Test - public void testCoreDecode_ByteBuffer() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeByteBuffer() throws IllegalAccessException, InstantiationException, DecodeException { ByteBuffer val = Hex.asByteBuffer("112233445566778899"); ByteBuffer expected = Hex.asByteBuffer("112233445566778899"); @@ -185,7 +185,7 @@ public class AvailableDecodersTest } @Test - public void testCoreDecode_ByteArray() throws IllegalAccessException, InstantiationException, DecodeException + public void testCoreDecodeByteArray() throws IllegalAccessException, InstantiationException, DecodeException { ByteBuffer val = Hex.asByteBuffer("112233445566778899"); byte[] expected = Hex.asByteArray("112233445566778899"); @@ -193,7 +193,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_Integer() throws IllegalAccessException, InstantiationException, DecodeException + public void testCustomDecoderInteger() throws IllegalAccessException, InstantiationException, DecodeException { decoders.register(IntegerDecoder.class); @@ -203,7 +203,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_Time() throws IllegalAccessException, InstantiationException, DecodeException + public void testCustomDecoderTime() throws IllegalAccessException, InstantiationException, DecodeException { decoders.register(TimeDecoder.class); @@ -222,7 +222,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_Date() throws IllegalAccessException, InstantiationException, DecodeException + public void testCustomDecoderDate() throws IllegalAccessException, InstantiationException, DecodeException { decoders.register(DateDecoder.class); @@ -241,7 +241,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_DateTime() throws IllegalAccessException, InstantiationException, DecodeException + public void testCustomDecoderDateTime() throws IllegalAccessException, InstantiationException, DecodeException { decoders.register(DateTimeDecoder.class); @@ -264,7 +264,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_ValidDual_Text() throws IllegalAccessException, InstantiationException, DecodeException + public void testCustomDecoderValidDualText() throws IllegalAccessException, InstantiationException, DecodeException { decoders.register(ValidDualDecoder.class); @@ -278,7 +278,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_ValidDual_Binary() throws IllegalAccessException, InstantiationException, DecodeException + public void testCustomDecoderValidDualBinary() throws IllegalAccessException, InstantiationException, DecodeException { decoders.register(ValidDualDecoder.class); @@ -296,7 +296,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_Register_Duplicate() + public void testCustomDecoderRegisterDuplicate() { // has duplicated support for the same target Type Exception e = assertThrows(InvalidWebSocketException.class, () -> decoders.register(BadDualDecoder.class)); @@ -304,7 +304,7 @@ public class AvailableDecodersTest } @Test - public void testCustomDecoder_Register_OtherDuplicate() + public void testCustomDecoderRegisterOtherDuplicate() { // Register DateDecoder (decodes java.util.Date) decoders.register(DateDecoder.class); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableEncodersTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableEncodersTest.java similarity index 69% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableEncodersTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableEncodersTest.java index 60c4c030f16..acde049e045 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableEncodersTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/AvailableEncodersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -30,10 +30,10 @@ import javax.websocket.Encoder; import javax.websocket.EndpointConfig; import org.eclipse.jetty.toolchain.test.Hex; -import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig; -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; +import org.eclipse.jetty.websocket.javax.client.internal.BasicClientEndpointConfig; import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders; import org.eclipse.jetty.websocket.javax.common.encoders.IntegerEncoder; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -50,7 +50,7 @@ public class AvailableEncodersTest @BeforeAll public static void initConfig() { - testConfig = new EmptyClientEndpointConfig(); + testConfig = new BasicClientEndpointConfig(); } private AvailableEncoders encoders = new AvailableEncoders(testConfig); @@ -99,113 +99,113 @@ public class AvailableEncodersTest } @Test - public void testCoreEncoder_Boolean() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderBoolean() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Boolean.class, Boolean.TRUE, "true"); } @Test - public void testCoreEncoder_bool() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderbool() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Boolean.TYPE, true, "true"); } @Test - public void testCoreEncoder_Byte() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderByte() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Byte.class, (byte)0x21, "33"); } @Test - public void testCoreEncoder_byte() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderbyte() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Byte.TYPE, (byte)0x21, "33"); } @Test - public void testCoreEncoder_Character() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderCharacter() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Character.class, '!', "!"); } @Test - public void testCoreEncoder_char() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderchar() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Character.TYPE, '!', "!"); } @Test - public void testCoreEncoder_Double() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderDouble() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Double.class, 123.45D, "123.45"); } @Test - public void testCoreEncoder_double() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderdouble() throws IllegalAccessException, InstantiationException, EncodeException { //noinspection RedundantCast assertTextEncoder(Double.TYPE, 123.45D, "123.45"); } @Test - public void testCoreEncoder_Float() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderFloat() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Float.class, 123.4567f, "123.4567"); } @Test - public void testCoreEncoder_float() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderfloat() throws IllegalAccessException, InstantiationException, EncodeException { //noinspection RedundantCast assertTextEncoder(Float.TYPE, 123.4567F, "123.4567"); } @Test - public void testCoreEncoder_Integer() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderInteger() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Integer.class, 123, "123"); } @Test - public void testCoreEncoder_int() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderint() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Integer.TYPE, 123, "123"); } @Test - public void testCoreEncoder_Long() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderLong() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Long.class, 123_456_789L, "123456789"); } @Test - public void testCoreEncoder_long() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderlong() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(Long.TYPE, 123_456_789L, "123456789"); } @Test - public void testCoreEncoder_String() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderString() throws IllegalAccessException, InstantiationException, EncodeException { assertTextEncoder(String.class, "Hello World", "Hello World"); } @Test - public void testCoreEncoder_ByteBuffer() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderByteBuffer() throws IllegalAccessException, InstantiationException, EncodeException { ByteBuffer buf = Hex.asByteBuffer("1122334455"); assertBinaryEncoder(ByteBuffer.class, buf, "1122334455"); } @Test - public void testCoreEncoder_ByteArray() throws IllegalAccessException, InstantiationException, EncodeException + public void testCoreEncoderByteArray() throws IllegalAccessException, InstantiationException, EncodeException { byte[] buf = Hex.asByteArray("998877665544332211"); assertBinaryEncoder(byte[].class, buf, "998877665544332211"); } @Test - public void testCustomEncoder_Integer() throws IllegalAccessException, InstantiationException, EncodeException + public void testCustomEncoderInteger() throws IllegalAccessException, InstantiationException, EncodeException { encoders.register(IntegerEncoder.class); int val = 99887766; @@ -214,7 +214,7 @@ public class AvailableEncodersTest } @Test - public void testCustomEncoder_Time() throws IllegalAccessException, InstantiationException, EncodeException, IOException + public void testCustomEncoderTime() throws IllegalAccessException, InstantiationException, EncodeException, IOException { encoders.register(TimeEncoder.class); @@ -229,7 +229,7 @@ public class AvailableEncodersTest } @Test - public void testCustomEncoder_Date() throws IllegalAccessException, InstantiationException, EncodeException, IOException + public void testCustomEncoderDate() throws IllegalAccessException, InstantiationException, EncodeException, IOException { encoders.register(DateEncoder.class); @@ -244,7 +244,7 @@ public class AvailableEncodersTest } @Test - public void testCustomEncoder_DateTime() throws IllegalAccessException, InstantiationException, EncodeException, IOException + public void testCustomEncoderDateTime() throws IllegalAccessException, InstantiationException, EncodeException, IOException { encoders.register(DateTimeEncoder.class); @@ -263,14 +263,14 @@ public class AvailableEncodersTest } @Test - public void testCustomEncoder_ValidDual_Text() throws IllegalAccessException, InstantiationException, EncodeException, IOException + public void testCustomEncoderValidDualText() throws IllegalAccessException, InstantiationException, EncodeException, IOException { encoders.register(ValidDualEncoder.class); assertTextEncoder(Integer.class, 1234567, "[1,234,567]"); } @Test - public void testCustomEncoder_ValidDual_Binary() throws IllegalAccessException, InstantiationException, EncodeException, IOException + public void testCustomEncoderValidDualBinary() throws IllegalAccessException, InstantiationException, EncodeException, IOException { encoders.register(ValidDualEncoder.class); long value = 0x112233445566L; @@ -278,7 +278,7 @@ public class AvailableEncodersTest } @Test - public void testCustomEncoder_Register_Duplicate() + public void testCustomEncoderRegisterDuplicate() { // has duplicated support for the same target Type Exception e = assertThrows(InvalidWebSocketException.class, () -> encoders.register(BadDualEncoder.class)); @@ -286,7 +286,7 @@ public class AvailableEncodersTest } @Test - public void testCustomEncoder_Register_OtherDuplicate() + public void testCustomEncoderRegisterOtherDuplicate() { // Register DateEncoder (decodes java.util.Date) encoders.register(DateEncoder.class); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualDecoder.java similarity index 77% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualDecoder.java index 016666886e9..b795e241294 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualEncoder.java similarity index 52% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualEncoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualEncoder.java index 418324709c0..decb7288d88 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualEncoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/BadDualEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/CoderEventTracking.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/CoderEventTracking.java similarity index 69% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/CoderEventTracking.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/CoderEventTracking.java index 8cf6a9cc376..0c60f58c58d 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/CoderEventTracking.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/CoderEventTracking.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateDecoder.java similarity index 59% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateDecoder.java index 68588e776ac..1326ca6c129 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -31,7 +31,7 @@ import javax.websocket.EndpointConfig; */ public class DateDecoder implements Decoder.Text { - private TimeZone GMT = TimeZone.getTimeZone("GMT"); + private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Override public Date decode(String s) throws DecodeException diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateEncoder.java similarity index 50% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateEncoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateEncoder.java index 4fdb0163e83..bf531847531 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateEncoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -30,7 +30,7 @@ import javax.websocket.EndpointConfig; */ public class DateEncoder implements Encoder.Text { - private TimeZone GMT = TimeZone.getTimeZone("GMT"); + private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Override public String encode(Date object) throws EncodeException diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeDecoder.java similarity index 59% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeDecoder.java index 7a5a78ed8ad..1146d3180ab 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeEncoder.java similarity index 51% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeEncoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeEncoder.java index 6b867449cf7..ae3cb861358 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeEncoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DateTimeEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -30,7 +30,7 @@ import javax.websocket.EndpointConfig; */ public class DateTimeEncoder implements Encoder.Text { - private TimeZone GMT = TimeZone.getTimeZone("GMT"); + private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Override public String encode(Date object) throws EncodeException diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextStreamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextStreamTest.java similarity index 70% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextStreamTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextStreamTest.java index ec96ec4107e..43aaa9db5b5 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextStreamTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -30,8 +30,8 @@ import java.util.function.Function; import javax.websocket.Decoder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.javax.common.CompletableFutureCallback; import org.eclipse.jetty.websocket.javax.common.messages.DecodedTextStreamMessageSink; import org.eclipse.jetty.websocket.javax.tests.FunctionMethod; import org.eclipse.jetty.websocket.javax.tests.client.AbstractClientSessionTest; @@ -47,7 +47,7 @@ import static org.hamcrest.Matchers.notNullValue; public class DecoderTextStreamTest extends AbstractClientSessionTest { @Test - public void testQuotes_Decoder_Direct() throws Exception + public void testQuotesDecoderDirect() throws Exception { Decoder.TextStream decoder = new QuotesDecoder(); @@ -62,7 +62,7 @@ public class DecoderTextStreamTest extends AbstractClientSessionTest } @Test - public void testQuotes_DecodedReaderMessageSink() throws Exception + public void testQuotesDecodedReaderMessageSink() throws Exception { Decoder.TextStream decoder = new QuotesDecoder(); CompletableFuture futureQuotes = new CompletableFuture<>(); @@ -80,14 +80,14 @@ public class DecoderTextStreamTest extends AbstractClientSessionTest return null; }); - DecodedTextStreamMessageSink sink = new DecodedTextStreamMessageSink(session, decoder, quoteHandle); + DecodedTextStreamMessageSink sink = new DecodedTextStreamMessageSink(session.getCoreSession(), decoder, quoteHandle); - List callbacks = new ArrayList<>(); - CompletableFutureCallback finCallback = null; + List callbacks = new ArrayList<>(); + FutureCallback finCallback = null; List frames = QuotesUtil.loadAsWebSocketFrames("quotes-ben.txt"); for (Frame frame : frames) { - CompletableFutureCallback callback = new CompletableFutureCallback(); + FutureCallback callback = new FutureCallback(); if (frame.isFin()) { finCallback = callback; @@ -100,7 +100,7 @@ public class DecoderTextStreamTest extends AbstractClientSessionTest finCallback.get(1, TimeUnit.SECONDS); // wait for fin Quotes quotes = futureQuotes.get(1, TimeUnit.SECONDS); assertThat("Quotes", quotes, notNullValue()); - for (CompletableFutureCallback callback : callbacks) + for (FutureCallback callback : callbacks) { assertThat("Callback", callback.isDone(), is(true)); } diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextTest.java similarity index 50% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextTest.java index 775975a4e1d..8aac6661224 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/DecoderTextTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -30,7 +30,7 @@ import static org.hamcrest.Matchers.is; public class DecoderTextTest { - private TimeZone GMT = TimeZone.getTimeZone("GMT"); + private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); @Test public void testDateDecoder() throws DecodeException diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderTextTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderTextTest.java new file mode 100644 index 00000000000..0077c25d5f1 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/EncoderTextTest.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.coders; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; + +/** + * Test various {@link javax.websocket.Encoder.Text} scenarios + */ +public class EncoderTextTest +{ + @Test + public void testQuotesEncoderDirect() throws Exception + { + QuotesEncoder encoder = new QuotesEncoder(); + Quotes quotes = QuotesUtil.loadQuote("quotes-ben.txt"); + String result = encoder.encode(quotes); + assertThat("Result", result, containsString("Author: Benjamin Franklin\n")); + assertThat("Result", result, containsString("Quote: We must, ")); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ExtDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ExtDecoder.java new file mode 100644 index 00000000000..059609b804c --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ExtDecoder.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.coders; + +import javax.websocket.Decoder; + +/** + * Testing scenario of an extended Decoder interface + * + * @param the decoder type + */ +public interface ExtDecoder extends Decoder.Text +{ + void setId(String id); +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FloatDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FloatDecoderTest.java similarity index 61% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FloatDecoderTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FloatDecoderTest.java index cd47059fa20..6695cc2ab9b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FloatDecoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FloatDecoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Fruit.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Fruit.java new file mode 100644 index 00000000000..5961c4cddfe --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Fruit.java @@ -0,0 +1,25 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.coders; + +public class Fruit +{ + public String name; + public String color; +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitBinaryEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitBinaryEncoder.java similarity index 61% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitBinaryEncoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitBinaryEncoder.java index 32210eaf8bc..cfd7ddf8785 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitBinaryEncoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitBinaryEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitDecoder.java similarity index 62% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitDecoder.java index 86bac30a458..7f7a15b4bc1 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitTextEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitTextEncoder.java new file mode 100644 index 00000000000..7adbc45ffc2 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/FruitTextEncoder.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.coders; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class FruitTextEncoder implements Encoder.Text +{ + @Override + public void destroy() + { + } + + @Override + public String encode(Fruit fruit) throws EncodeException + { + return String.format("%s|%s", fruit.name, fruit.color); + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/IntegerDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/IntegerDecoderTest.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/IntegerDecoderTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/IntegerDecoderTest.java index b67c29c486c..d906331a7da 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/IntegerDecoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/IntegerDecoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/LongDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/LongDecoderTest.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/LongDecoderTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/LongDecoderTest.java index 4a39c9d1796..35a2a4b99af 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/LongDecoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/LongDecoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Quotes.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Quotes.java new file mode 100644 index 00000000000..f149aa05c1a --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/Quotes.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.coders; + +import java.util.ArrayList; +import java.util.List; + +public class Quotes +{ + private String author; + private List quotes = new ArrayList<>(); + + public void addQuote(String quote) + { + quotes.add(quote); + } + + public String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + this.author = author; + } + + public List getQuotes() + { + return quotes; + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesDecoder.java similarity index 60% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesDecoder.java index b20624ecc0d..3504bf418ce 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; @@ -25,12 +25,12 @@ import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class QuotesDecoder implements Decoder.TextStream { - private static final Logger LOG = Log.getLogger(QuotesDecoder.class); + private static final Logger LOG = LoggerFactory.getLogger(QuotesDecoder.class); @Override public Quotes decode(Reader reader) throws DecodeException, IOException diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesEncoder.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesEncoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesEncoder.java index 8018d0d0ba4..f5b2a99d30e 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesEncoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesUtil.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesUtil.java similarity index 74% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesUtil.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesUtil.java index d14df301e15..37f2fc36b4c 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesUtil.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/QuotesUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ShortDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ShortDecoderTest.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ShortDecoderTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ShortDecoderTest.java index a52d83acef4..951dca199b1 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ShortDecoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ShortDecoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeDecoder.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeDecoder.java index ec5e9e36fd9..f1f31e7a38a 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeEncoder.java new file mode 100644 index 00000000000..f18a3c12cb3 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/TimeEncoder.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.coders; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +/** + * Encode Time + */ +public class TimeEncoder implements Encoder.Text +{ + private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + @Override + public String encode(Date object) throws EncodeException + { + SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss z"); + format.setTimeZone(GMT); + return format.format(object); + } + + @Override + public void destroy() + { + // TODO: verify destroy called + } + + @Override + public void init(EndpointConfig config) + { + // TODO: verify init called + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualDecoder.java similarity index 71% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualDecoder.java index f52a5a86e7e..31d6c857077 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualEncoder.java similarity index 56% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualEncoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualEncoder.java index f154f60975e..e0c86d44669 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualEncoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/coders/ValidDualEncoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.coders; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/BaseMessageHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/BaseMessageHandler.java new file mode 100644 index 00000000000..1df281c32f4 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/BaseMessageHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import javax.websocket.MessageHandler; + +public class BaseMessageHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(String message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayPartialHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayPartialHandler.java new file mode 100644 index 00000000000..32f9bc222e9 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayPartialHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import javax.websocket.MessageHandler; + +public class ByteArrayPartialHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(byte[] partialMessage, boolean last) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayWholeHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayWholeHandler.java new file mode 100644 index 00000000000..9c93050a373 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteArrayWholeHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import javax.websocket.MessageHandler; + +public class ByteArrayWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(byte[] message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferPartialHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferPartialHandler.java new file mode 100644 index 00000000000..f203e9a0cd9 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferPartialHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +public class ByteBufferPartialHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(ByteBuffer partialMessage, boolean last) + { + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferWholeHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferWholeHandler.java new file mode 100644 index 00000000000..4e350776b28 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ByteBufferWholeHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +public class ByteBufferWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(ByteBuffer message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ComboMessageHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ComboMessageHandler.java new file mode 100644 index 00000000000..a266e5a5c1d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ComboMessageHandler.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +/** + * A particularly annoying type of MessageHandler. One defining 2 implementations. + */ +public class ComboMessageHandler implements MessageHandler.Whole, MessageHandler.Partial +{ + @Override + public void onMessage(ByteBuffer partialMessage, boolean last) + { + // TODO Auto-generated method stub + } + + @Override + public void onMessage(String message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ExtendedMessageHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ExtendedMessageHandler.java new file mode 100644 index 00000000000..9cb1f749d85 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ExtendedMessageHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import java.nio.ByteBuffer; +import javax.websocket.MessageHandler; + +public class ExtendedMessageHandler extends BaseMessageHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(ByteBuffer partialMessage, boolean last) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/InputStreamWholeHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/InputStreamWholeHandler.java new file mode 100644 index 00000000000..34c5af063b8 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/InputStreamWholeHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import java.io.InputStream; +import javax.websocket.MessageHandler; + +public class InputStreamWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(InputStream stream) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/LongMessageHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/LongMessageHandler.java new file mode 100644 index 00000000000..f1155847855 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/LongMessageHandler.java @@ -0,0 +1,29 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import javax.websocket.MessageHandler; + +public class LongMessageHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(Long message) + { + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ReaderWholeHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ReaderWholeHandler.java new file mode 100644 index 00000000000..d8637aa7080 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/ReaderWholeHandler.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import java.io.Reader; +import javax.websocket.MessageHandler; + +public class ReaderWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(Reader reader) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringPartialHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringPartialHandler.java new file mode 100644 index 00000000000..d614d282a1f --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringPartialHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import javax.websocket.MessageHandler; + +public class StringPartialHandler implements MessageHandler.Partial +{ + @Override + public void onMessage(String partialMessage, boolean last) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringWholeHandler.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringWholeHandler.java new file mode 100644 index 00000000000..2f072ebc9bb --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/handlers/StringWholeHandler.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.handlers; + +import javax.websocket.MessageHandler; + +public class StringWholeHandler implements MessageHandler.Whole +{ + @Override + public void onMessage(String message) + { + // TODO Auto-generated method stub + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/Quotes.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/Quotes.java new file mode 100644 index 00000000000..a34d3fe0c2f --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/Quotes.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.quotes; + +import java.util.ArrayList; +import java.util.List; + +public class Quotes +{ + private String author; + private List quotes = new ArrayList<>(); + + public void addQuote(String quote) + { + quotes.add(quote); + } + + public String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + this.author = author; + } + + public List getQuotes() + { + return quotes; + } + + @Override + public String toString() + { + return String.format("Quotes[%s,quotes.size=%d]", author, quotes.size()); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoder.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoder.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoder.java index 37db7017554..d500ee004fd 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoder.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoder.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.quotes; @@ -25,12 +25,12 @@ import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class QuotesDecoder implements Decoder.TextStream { - private static final Logger LOG = Log.getLogger(QuotesDecoder.class); + private static final Logger LOG = LoggerFactory.getLogger(QuotesDecoder.class); @SuppressWarnings("RedundantThrows") @Override diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTest.java similarity index 82% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTest.java index b4e49400eb5..9b36099fddc 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.quotes; @@ -31,14 +31,14 @@ import javax.websocket.Session; import javax.websocket.WebSocketContainer; import javax.websocket.server.ServerEndpoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.eclipse.jetty.websocket.javax.tests.WSEventTracker; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -88,7 +88,7 @@ public class QuotesDecoderTest } } - private static final Logger LOG = Log.getLogger(QuotesDecoderTest.class); + private static final Logger LOG = LoggerFactory.getLogger(QuotesDecoderTest.class); private LocalServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java similarity index 81% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java index aa95b86edb3..a65fd402498 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.quotes; @@ -77,7 +77,7 @@ public class QuotesDecoderTextStreamTest } @Test - public void testQuoteEchoString_Bulk() throws Exception + public void testQuoteEchoStringBulk() throws Exception { List send = QuotesUtil.loadAsWebSocketFrames("quotes-ben.txt"); send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); @@ -97,7 +97,7 @@ public class QuotesDecoderTextStreamTest } @Test - public void testQuoteEchoString_SmallSegments() throws Exception + public void testQuoteEchoStringSmallSegments() throws Exception { List send = QuotesUtil.loadAsWebSocketFrames("quotes-ben.txt"); send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); @@ -117,7 +117,7 @@ public class QuotesDecoderTextStreamTest } @Test - public void testQuoteEchoString_FrameWise() throws Exception + public void testQuoteEchoStringFrameWise() throws Exception { List send = QuotesUtil.loadAsWebSocketFrames("quotes-ben.txt"); send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoder.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoder.java new file mode 100644 index 00000000000..871807b8399 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoder.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.quotes; + +import javax.websocket.EncodeException; +import javax.websocket.Encoder; +import javax.websocket.EndpointConfig; + +public class QuotesEncoder implements Encoder.Text +{ + @SuppressWarnings("RedundantThrows") + @Override + public String encode(Quotes q) throws EncodeException + { + StringBuilder buf = new StringBuilder(); + buf.append("Author: ").append(q.getAuthor()).append('\n'); + for (String quote : q.getQuotes()) + { + buf.append("Quote: ").append(quote).append('\n'); + } + return buf.toString(); + } + + @Override + public void destroy() + { + } + + @Override + public void init(EndpointConfig config) + { + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoderTest.java similarity index 87% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoderTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoderTest.java index 7b1eb1b9eb7..403b76ddc53 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoderTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesEncoderTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.quotes; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesSocket.java similarity index 60% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesSocket.java index 99e27d2c27c..0166f756766 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.quotes; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesUtil.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesUtil.java similarity index 74% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesUtil.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesUtil.java index 1fedc4cfdeb..e65549563fd 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesUtil.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.quotes; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AbstractJavaxWebSocketServerFrameHandlerTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AbstractJavaxWebSocketServerFrameHandlerTest.java similarity index 59% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AbstractJavaxWebSocketServerFrameHandlerTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AbstractJavaxWebSocketServerFrameHandlerTest.java index 548526309ee..9a2f5f1f314 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AbstractJavaxWebSocketServerFrameHandlerTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AbstractJavaxWebSocketServerFrameHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -24,11 +24,11 @@ import javax.websocket.EndpointConfig; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig; +import org.eclipse.jetty.websocket.javax.client.internal.BasicClientEndpointConfig; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerContainer; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -62,7 +62,7 @@ public abstract class AbstractJavaxWebSocketServerFrameHandlerTest public AbstractJavaxWebSocketServerFrameHandlerTest() { - endpointConfig = new EmptyClientEndpointConfig(); + endpointConfig = new BasicClientEndpointConfig(); encoders = new AvailableEncoders(endpointConfig); decoders = new AvailableDecoders(endpointConfig); uriParams = new HashMap<>(); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AltFilterTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AltFilterTest.java similarity index 76% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AltFilterTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AltFilterTest.java index de40f16150c..e6c93a0ce17 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AltFilterTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AltFilterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java new file mode 100644 index 00000000000..d81f71df0bb --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java @@ -0,0 +1,137 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.javax.tests.Fuzzer; +import org.eclipse.jetty.websocket.javax.tests.LocalServer; +import org.eclipse.jetty.websocket.javax.tests.coders.DateDecoder; +import org.eclipse.jetty.websocket.javax.tests.coders.TimeEncoder; +import org.eclipse.jetty.websocket.javax.tests.server.configs.EchoSocketConfigurator; +import org.eclipse.jetty.websocket.javax.tests.server.sockets.ConfiguredEchoSocket; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class AnnotatedServerEndpointTest +{ + private LocalServer server; + private String path = "/echo"; + private String subprotocol = "echo"; + + @BeforeEach + public void startServer() throws Exception + { + server = new LocalServer(); + server.start(); + server.getServerContainer().addEndpoint(ConfiguredEchoSocket.class); + + ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder + .create(ConfiguredEchoSocket.class, "/override") + .subprotocols(Collections.singletonList("override")) + .build(); + server.getServerContainer().addEndpoint(endpointConfig); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + private void assertResponse(String message, String expectedText) throws Exception + { + Map headers = new HashMap<>(); + headers.put(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), subprotocol); + + List send = new ArrayList<>(); + send.add(new Frame(OpCode.TEXT).setPayload(message)); + send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); + + List expect = new ArrayList<>(); + expect.add(new Frame(OpCode.TEXT).setPayload(expectedText)); + expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); + + try (Fuzzer session = server.newNetworkFuzzer(path, headers)) + { + session.sendFrames(send); + session.expect(expect); + } + } + + @Test + public void testConfigurator() throws Exception + { + assertResponse("configurator", EchoSocketConfigurator.class.getName()); + } + + @Test + public void testTextMax() throws Exception + { + assertResponse("text-max", "111,222"); + } + + @Test + public void testBinaryMax() throws Exception + { + assertResponse("binary-max", "333,444"); + } + + @Test + public void testDecoders() throws Exception + { + assertResponse("decoders", DateDecoder.class.getName()); + } + + @Test + public void testEncoders() throws Exception + { + assertResponse("encoders", TimeEncoder.class.getName()); + } + + @Test + public void testSubProtocols() throws Exception + { + assertResponse("subprotocols", "chat, echo, test"); + } + + @Test + public void testOverrideEndpointConfig() throws Exception + { + this.path = "/override"; + this.subprotocol = "override"; + + assertResponse("configurator", EchoSocketConfigurator.class.getName()); + assertResponse("text-max", "111,222"); + assertResponse("binary-max", "333,444"); + assertResponse("decoders", DateDecoder.class.getName()); + assertResponse("encoders", TimeEncoder.class.getName()); + assertResponse("subprotocols", "override"); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointConfigContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointConfigContextListener.java similarity index 65% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointConfigContextListener.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointConfigContextListener.java index 08dd37f920b..4dbb670e9e9 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointConfigContextListener.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointConfigContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointContextListener.java similarity index 64% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointContextListener.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointContextListener.java index bbc5a02a8a0..fdbfe913634 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointContextListener.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoEndpointContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketConfigContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketConfigContextListener.java similarity index 65% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketConfigContextListener.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketConfigContextListener.java index 55712e2026d..7b0185b6a67 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketConfigContextListener.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketConfigContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketContextListener.java similarity index 57% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketContextListener.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketContextListener.java index 7eb71f4256f..3c80ed9a313 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketContextListener.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BasicEchoSocketContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BinaryStreamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BinaryStreamTest.java similarity index 81% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BinaryStreamTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BinaryStreamTest.java index c6d1ff72bd3..e63c75994f2 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BinaryStreamTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/BinaryStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -31,8 +31,6 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -42,6 +40,8 @@ import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class BinaryStreamTest { @@ -128,7 +128,7 @@ public class BinaryStreamTest @ServerEndpoint(PATH) public static class ServerBinaryStreamer { - private static final Logger LOG = Log.getLogger(ServerBinaryStreamer.class); + private static final Logger LOG = LoggerFactory.getLogger(ServerBinaryStreamer.class); @OnMessage public void echo(Session session, InputStream input) throws IOException diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ConfiguratorTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ConfiguratorTest.java similarity index 87% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ConfiguratorTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ConfiguratorTest.java index ac72ce9732e..573ccd47b3c 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ConfiguratorTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ConfiguratorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -51,10 +51,8 @@ import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; @@ -68,13 +66,15 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; public class ConfiguratorTest { - private static final Logger LOG = Log.getLogger(ConfiguratorTest.class); + private static final Logger LOG = LoggerFactory.getLogger(ConfiguratorTest.class); public static class EmptyConfigurator extends ServerEndpointConfig.Configurator { @@ -303,20 +303,20 @@ public class ConfiguratorTest public static class GmtTimeDecoder implements Decoder.Text { - private TimeZone TZ; + private TimeZone tz; @Override public Calendar decode(String s) throws DecodeException { - if (TZ == null) + if (tz == null) throw new DecodeException(s, ".init() not called"); try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - dateFormat.setTimeZone(TZ); + dateFormat.setTimeZone(tz); Date time = dateFormat.parse(s); Calendar cal = Calendar.getInstance(); - cal.setTimeZone(TZ); + cal.setTimeZone(tz); cal.setTime(time); return cal; } @@ -329,7 +329,7 @@ public class ConfiguratorTest @Override public void init(EndpointConfig config) { - TZ = TimeZone.getTimeZone("GMT+0"); + tz = TimeZone.getTimeZone("GMT+0"); } @Override @@ -351,7 +351,7 @@ public class ConfiguratorTest decoders = {GmtTimeDecoder.class}) public static class TimeDecoderSocket { - private TimeZone TZ = TimeZone.getTimeZone("GMT+0"); + private final TimeZone tz = TimeZone.getTimeZone("GMT+0"); @OnMessage public String onMessage(Calendar cal) @@ -362,7 +362,7 @@ public class ConfiguratorTest private SimpleDateFormat newDateFormat() { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss Z", Locale.ENGLISH); - dateFormat.setTimeZone(TZ); + dateFormat.setTimeZone(tz); return dateFormat; } } @@ -432,9 +432,9 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.addExtensions("identity"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload(HttpHeader.SEC_WEBSOCKET_EXTENSIONS.asString()), Callback.NOOP, false); @@ -456,9 +456,9 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.addExtensions("identity"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload("NegoExts"), Callback.NOOP, false); @@ -480,9 +480,9 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.header("X-Dummy", "Bogus"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload("X-Dummy"), Callback.NOOP, false); @@ -504,9 +504,9 @@ public class ConfiguratorTest // First Request FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { // first request has this UserProperty @@ -551,9 +551,9 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { SocketAddress expectedLocal = coreSession.getLocalAddress(); @@ -585,7 +585,7 @@ public class ConfiguratorTest * @throws Exception on test failure */ @Test - public void testProtocol_Single() throws Exception + public void testProtocolSingle() throws Exception { URI wsUri = server.getWsUri().resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); @@ -593,7 +593,7 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.setSubProtocols("status"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); assertProtocols(clientSocket, clientConnectFuture, is("Requested Protocols: [status]")); } @@ -604,7 +604,7 @@ public class ConfiguratorTest * @throws Exception on test failure */ @Test - public void testProtocol_Triple() throws Exception + public void testProtocolTriple() throws Exception { URI wsUri = server.getWsUri().resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); @@ -612,7 +612,7 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.setSubProtocols("echo", "chat", "status"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); assertProtocols(clientSocket, clientConnectFuture, is("Requested Protocols: [echo,chat,status]")); } @@ -623,7 +623,7 @@ public class ConfiguratorTest * @throws Exception on test failure */ @Test - public void testProtocol_LowercaseHeader() throws Exception + public void testProtocolLowercaseHeader() throws Exception { URI wsUri = server.getWsUri().resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); @@ -631,7 +631,7 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.setSubProtocols("echo", "chat", "status"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); assertProtocols(clientSocket, clientConnectFuture, is("Requested Protocols: [echo,chat,status]")); } @@ -642,7 +642,7 @@ public class ConfiguratorTest * @throws Exception on test failure */ @Test - public void testProtocol_AltHeaderCase() throws Exception + public void testProtocolAltHeaderCase() throws Exception { URI wsUri = server.getWsUri().resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); @@ -650,15 +650,15 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.setSubProtocols("echo", "chat", "status"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); assertProtocols(clientSocket, clientConnectFuture, is("Requested Protocols: [echo,chat,status]")); } - protected void assertProtocols(FrameHandlerTracker clientSocket, Future clientConnectFuture, Matcher responseMatcher) + protected void assertProtocols(FrameHandlerTracker clientSocket, Future clientConnectFuture, Matcher responseMatcher) throws InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException { - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload("getProtocols"), Callback.NOOP, false); @@ -683,9 +683,9 @@ public class ConfiguratorTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, wsUri, clientSocket); upgradeRequest.setSubProtocols("gmt"); - Future clientConnectFuture = client.connect(upgradeRequest); + Future clientConnectFuture = client.connect(upgradeRequest); - FrameHandler.CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + CoreSession coreSession = clientConnectFuture.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); try { coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload("2016-06-20T14:27:44"), Callback.NOOP, false); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ContainerProviderServerTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ContainerProviderServerTest.java new file mode 100644 index 00000000000..849d329c8d7 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ContainerProviderServerTest.java @@ -0,0 +1,89 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; +import javax.websocket.ContainerProvider; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.javax.tests.EventSocket; +import org.eclipse.jetty.websocket.javax.tests.WSServer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static javax.websocket.CloseReason.CloseCodes.NORMAL_CLOSURE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ContainerProviderServerTest +{ + @ServerEndpoint("/echo") + public static class MySocket + { + @OnOpen + public void onOpen() + { + WebSocketContainer client = ContainerProvider.getWebSocketContainer(); + assertNotNull(client); + } + } + + private WSServer server; + + @BeforeEach + public void startServer() throws Exception + { + Path testdir = MavenTestingUtils.getTargetTestingPath(ContainerProviderServerTest.class.getName()); + server = new WSServer(testdir, "app"); + server.createWebInf(); + server.copyEndpoint(MySocket.class); + server.start(); + WebAppContext webapp = server.createWebAppContext(); + server.deployWebapp(webapp); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + @Test + public void testJavaxWsContainerInServer() throws Exception + { + WebSocketContainer client = ContainerProvider.getWebSocketContainer(); + EventSocket clientSocket = new EventSocket(); + Session session = client.connectToServer(clientSocket, server.getWsUri().resolve("/app/echo")); + session.close(new CloseReason(NORMAL_CLOSURE, null)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientSocket.closeReason.getCloseCode(), is(NORMAL_CLOSURE)); + assertNull(clientSocket.error); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/DeploymentExceptionTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/DeploymentExceptionTest.java similarity index 77% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/DeploymentExceptionTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/DeploymentExceptionTest.java index 052d8f87e3f..e8abab0ecc6 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/DeploymentExceptionTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/DeploymentExceptionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -29,14 +29,14 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.websocket.javax.common.util.InvalidSignatureException; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.javax.tests.server.sockets.InvalidCloseIntSocket; import org.eclipse.jetty.websocket.javax.tests.server.sockets.InvalidErrorErrorSocket; import org.eclipse.jetty.websocket.javax.tests.server.sockets.InvalidErrorIntSocket; import org.eclipse.jetty.websocket.javax.tests.server.sockets.InvalidOpenCloseReasonSocket; import org.eclipse.jetty.websocket.javax.tests.server.sockets.InvalidOpenIntSocket; import org.eclipse.jetty.websocket.javax.tests.server.sockets.InvalidOpenSessionIntSocket; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; @@ -93,7 +93,7 @@ public class DeploymentExceptionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testDeploy_InvalidSignature(Class pojo) throws Exception + public void testDeployInvalidSignature(Class pojo) throws Exception { ServletContextHandler context = new ServletContextHandler(); context.setServer(server); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/EndpointViaConfigTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/EndpointViaConfigTest.java new file mode 100644 index 00000000000..57d9f839f37 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/EndpointViaConfigTest.java @@ -0,0 +1,106 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.net.URI; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import com.acme.websocket.BasicEchoEndpoint; +import com.acme.websocket.BasicEchoEndpointConfigContextListener; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.javax.tests.WSServer; +import org.eclipse.jetty.websocket.javax.tests.framehandlers.FrameHandlerTracker; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * Example of an {@link javax.websocket.Endpoint} extended echo server added programmatically via the + * {@link javax.websocket.server.ServerContainer#addEndpoint(javax.websocket.server.ServerEndpointConfig)} + */ +@ExtendWith(WorkDirExtension.class) +public class EndpointViaConfigTest +{ + private static final Logger LOG = LoggerFactory.getLogger(EndpointViaConfigTest.class); + + public WorkDir testdir; + + @Test + public void testEcho() throws Exception + { + WSServer wsb = new WSServer(testdir.getPath(), "app"); + wsb.copyWebInf("basic-echo-endpoint-config-web.xml"); + // the endpoint (extends javax.websocket.Endpoint) + wsb.copyClass(BasicEchoEndpoint.class); + // the configuration (adds the endpoint) + wsb.copyClass(BasicEchoEndpointConfigContextListener.class); + + try + { + wsb.start(); + URI uri = wsb.getWsUri(); + + WebAppContext webapp = wsb.createWebAppContext(); + wsb.deployWebapp(webapp); + + WebSocketCoreClient client = new WebSocketCoreClient(); + try + { + client.start(); + FrameHandlerTracker clientSocket = new FrameHandlerTracker(); + Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echo")); + // wait for connect + CoreSession coreSession = clientConnectFuture.get(5, TimeUnit.SECONDS); + try + { + coreSession.sendFrame(new Frame(OpCode.TEXT).setPayload("Hello World"), Callback.NOOP, false); + + String incomingMessage = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS); + assertThat("Expected message", incomingMessage, is("Hello World")); + } + finally + { + coreSession.close(Callback.NOOP); + } + } + finally + { + client.stop(); + LOG.debug("Stopped - " + client); + } + } + finally + { + wsb.stop(); + LOG.debug("Stopped - " + wsb); + } + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutContextListener.java similarity index 63% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutContextListener.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutContextListener.java index 5d042405944..df799eae498 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutContextListener.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutTest.java similarity index 66% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutTest.java index 261f265c3d0..4948dc66515 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/IdleTimeoutTest.java @@ -1,43 +1,48 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; +import java.io.IOException; +import java.nio.channels.ClosedChannelException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; +import com.acme.websocket.IdleTimeoutContextListener; +import com.acme.websocket.IdleTimeoutOnOpenEndpoint; +import com.acme.websocket.IdleTimeoutOnOpenSocket; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.tests.Fuzzer; import org.eclipse.jetty.websocket.javax.tests.WSServer; -import org.eclipse.jetty.websocket.javax.tests.server.sockets.IdleTimeoutOnOpenEndpoint; -import org.eclipse.jetty.websocket.javax.tests.server.sockets.IdleTimeoutOnOpenSocket; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; public class IdleTimeoutTest { @@ -59,7 +64,6 @@ public class IdleTimeoutTest WebAppContext webapp = server.createWebAppContext(); server.deployWebapp(webapp); - // wsb.dump(); } @AfterAll @@ -76,7 +80,9 @@ public class IdleTimeoutTest // wait 1 second to allow timeout to fire off TimeUnit.SECONDS.sleep(1); - session.sendFrames(new Frame(OpCode.TEXT).setPayload("You shouldn't be there")); + IOException error = assertThrows(IOException.class, + () -> session.sendFrames(new Frame(OpCode.TEXT).setPayload("You shouldn't be there"))); + assertThat(error.getCause(), instanceOf(ClosedChannelException.class)); BlockingQueue framesQueue = session.getOutputFrames(); Frame frame = framesQueue.poll(1, TimeUnit.SECONDS); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/InputStreamEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/InputStreamEchoTest.java similarity index 79% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/InputStreamEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/InputStreamEchoTest.java index c7714714fe7..d7cf252ea8c 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/InputStreamEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/InputStreamEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -28,8 +28,6 @@ import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -38,13 +36,15 @@ import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Test various {@link javax.websocket.Decoder.BinaryStream Decoder.BinaryStream} echo behavior of Java InputStreams */ public class InputStreamEchoTest { - private static final Logger LOG = Log.getLogger(InputStreamEchoTest.class); + private static final Logger LOG = LoggerFactory.getLogger(InputStreamEchoTest.class); public static class BaseSocket { diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JavaxWebSocketFrameHandler_OnMessage_TextStreamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JavaxWebSocketFrameHandlerOnMessageTextStreamTest.java similarity index 78% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JavaxWebSocketFrameHandler_OnMessage_TextStreamTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JavaxWebSocketFrameHandlerOnMessageTextStreamTest.java index 0891c15d484..78117206672 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JavaxWebSocketFrameHandler_OnMessage_TextStreamTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JavaxWebSocketFrameHandlerOnMessageTextStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -29,8 +29,8 @@ import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler; import org.eclipse.jetty.websocket.javax.common.UpgradeRequest; @@ -41,7 +41,7 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -public class JavaxWebSocketFrameHandler_OnMessage_TextStreamTest extends AbstractJavaxWebSocketServerFrameHandlerTest +public class JavaxWebSocketFrameHandlerOnMessageTextStreamTest extends AbstractJavaxWebSocketServerFrameHandlerTest { @SuppressWarnings("Duplicates") private T performOnMessageInvocation(T socket, Consumer func) throws Exception @@ -50,7 +50,7 @@ public class JavaxWebSocketFrameHandler_OnMessage_TextStreamTest extends Abstrac // Establish endpoint function JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(socket, request); - frameHandler.onOpen(new FrameHandler.CoreSession.Empty(), Callback.NOOP); + frameHandler.onOpen(new CoreSession.Empty(), Callback.NOOP); func.accept(frameHandler); return socket; } diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JettyServerEndpointConfiguratorTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JettyServerEndpointConfiguratorTest.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JettyServerEndpointConfiguratorTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JettyServerEndpointConfiguratorTest.java index 0c28d087267..2b1cd0eb5e5 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JettyServerEndpointConfiguratorTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JettyServerEndpointConfiguratorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -22,7 +22,7 @@ import java.util.Iterator; import java.util.ServiceLoader; import javax.websocket.server.ServerEndpointConfig; -import org.eclipse.jetty.websocket.javax.server.ContainerDefaultConfigurator; +import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrBatchModeTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrBatchModeTest.java similarity index 72% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrBatchModeTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrBatchModeTest.java index 27f1e6c580c..f3689739fb5 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrBatchModeTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrBatchModeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -89,15 +89,8 @@ public class JsrBatchModeTest URI uri = server.getWsUri(); - final CountDownLatch latch = new CountDownLatch(1); - EndpointAdapter endpoint = new EndpointAdapter() - { - @Override - public void onMessage(String message) - { - latch.countDown(); - } - }; + CountDownLatch latch = new CountDownLatch(1); + EndpointAdapter endpoint = new EndpointAdapter(latch); try (Session session = client.connectToServer(endpoint, config, uri)) { @@ -126,15 +119,8 @@ public class JsrBatchModeTest URI uri = server.getWsUri(); - final CountDownLatch latch = new CountDownLatch(1); - EndpointAdapter endpoint = new EndpointAdapter() - { - @Override - public void onMessage(String message) - { - latch.countDown(); - } - }; + CountDownLatch latch = new CountDownLatch(1); + EndpointAdapter endpoint = new EndpointAdapter(latch); try (Session session = client.connectToServer(endpoint, config, uri)) { @@ -157,15 +143,8 @@ public class JsrBatchModeTest URI uri = server.getWsUri(); - final CountDownLatch latch = new CountDownLatch(1); - EndpointAdapter endpoint = new EndpointAdapter() - { - @Override - public void onMessage(String message) - { - latch.countDown(); - } - }; + CountDownLatch latch = new CountDownLatch(1); + EndpointAdapter endpoint = new EndpointAdapter(latch); try (Session session = client.connectToServer(endpoint, config, uri)) { @@ -180,12 +159,25 @@ public class JsrBatchModeTest } } - public abstract static class EndpointAdapter extends Endpoint implements MessageHandler.Whole + public static class EndpointAdapter extends Endpoint implements MessageHandler.Whole { + private final CountDownLatch latch; + + public EndpointAdapter(CountDownLatch latch) + { + this.latch = latch; + } + @Override public void onOpen(Session session, EndpointConfig config) { session.addMessageHandler(this); } + + @Override + public void onMessage(String message) + { + latch.countDown(); + } } } diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrEchoTest.java similarity index 87% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrEchoTest.java index 0e0d6148fbc..64798e6a4be 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/JsrEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeAnnotatedTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeAnnotatedTest.java similarity index 74% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeAnnotatedTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeAnnotatedTest.java index 91a702836d1..66d21d6a25d 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeAnnotatedTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeAnnotatedTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -30,8 +30,8 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; import org.eclipse.jetty.websocket.javax.tests.WSServer; @@ -82,9 +82,9 @@ public class LargeAnnotatedTest FrameHandlerTracker clientSocket = new FrameHandlerTracker(); - Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echo/large")); + Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echo/large")); // wait for connect - FrameHandler.CoreSession coreSession = clientConnectFuture.get(1, TimeUnit.SECONDS); + CoreSession coreSession = clientConnectFuture.get(1, TimeUnit.SECONDS); coreSession.setMaxTextMessageSize(128 * 1024); try { diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeContainerTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeContainerTest.java similarity index 57% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeContainerTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeContainerTest.java index 21ffd70a40a..541cc93b648 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeContainerTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeContainerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -23,18 +23,14 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.websocket.OnMessage; -import javax.websocket.server.ServerContainer; -import javax.websocket.server.ServerEndpoint; +import com.acme.websocket.LargeEchoDefaultSocket; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; import org.eclipse.jetty.websocket.javax.tests.WSServer; @@ -51,33 +47,6 @@ import static org.hamcrest.Matchers.is; @ExtendWith(WorkDirExtension.class) public class LargeContainerTest { - @ServerEndpoint(value = "/echo/large") - public static class LargeEchoDefaultSocket - { - @OnMessage - public void echo(javax.websocket.Session session, String msg) - { - // reply with echo - session.getAsyncRemote().sendText(msg); - } - } - - public static class LargeEchoContextListener implements ServletContextListener - { - @Override - public void contextDestroyed(ServletContextEvent sce) - { - /* do nothing */ - } - - @Override - public void contextInitialized(ServletContextEvent sce) - { - ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); - container.setDefaultMaxTextMessageBufferSize(128 * 1024); - } - } - public WorkDir testdir; @SuppressWarnings("Duplicates") @@ -95,7 +64,6 @@ public class LargeContainerTest WebAppContext webapp = wsb.createWebAppContext(); wsb.deployWebapp(webapp); - // wsb.dump(); WebSocketCoreClient client = new WebSocketCoreClient(); try @@ -103,10 +71,10 @@ public class LargeContainerTest client.start(); FrameHandlerTracker clientSocket = new FrameHandlerTracker(); - Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echo/large")); + Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echo/large")); // wait for connect - FrameHandler.CoreSession coreSession = clientConnectFuture.get(5, TimeUnit.SECONDS); + CoreSession coreSession = clientConnectFuture.get(5, TimeUnit.SECONDS); coreSession.setMaxTextMessageSize(128 * 1024); try { diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeEchoContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeEchoContextListener.java new file mode 100644 index 00000000000..8f911b49656 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/LargeEchoContextListener.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.websocket.server.ServerContainer; + +/** + * Configure the Large Text Message Size via the Container + */ +public class LargeEchoContextListener implements ServletContextListener +{ + @Override + public void contextDestroyed(ServletContextEvent sce) + { + /* do nothing */ + } + + @Override + public void contextInitialized(ServletContextEvent sce) + { + ServerContainer container = (ServerContainer)sce.getServletContext().getAttribute(ServerContainer.class.getName()); + container.setDefaultMaxTextMessageBufferSize(128 * 1024); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java similarity index 83% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java index e5e0a6821a6..55688823c0c 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -35,7 +35,7 @@ import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/OnMessageReturnTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/OnMessageReturnTest.java similarity index 76% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/OnMessageReturnTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/OnMessageReturnTest.java index 1204b55304c..074205796b0 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/OnMessageReturnTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/OnMessageReturnTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -32,8 +32,8 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; import org.eclipse.jetty.websocket.javax.tests.WSServer; @@ -105,10 +105,10 @@ public class OnMessageReturnTest client.start(); FrameHandlerTracker clientSocket = new FrameHandlerTracker(); - Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echoreturn")); + Future clientConnectFuture = client.connect(clientSocket, uri.resolve("/app/echoreturn")); // wait for connect - FrameHandler.CoreSession coreSession = clientConnectFuture.get(5, TimeUnit.SECONDS); + CoreSession coreSession = clientConnectFuture.get(5, TimeUnit.SECONDS); try { // Send message diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PartialEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PartialEchoTest.java similarity index 83% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PartialEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PartialEchoTest.java index 68f1b1fb8c9..f2da4b4a1ec 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PartialEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PartialEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -27,8 +27,6 @@ import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -37,6 +35,8 @@ import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Sends raw TEXT or BINARY messages to server. @@ -46,7 +46,7 @@ import org.junit.jupiter.api.Test; */ public class PartialEchoTest { - private static final Logger LOG = Log.getLogger(PartialEchoTest.class); + private static final Logger LOG = LoggerFactory.getLogger(PartialEchoTest.class); public static class BaseSocket { diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PingPongTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PingPongTest.java new file mode 100644 index 00000000000..4d548a2f05b --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PingPongTest.java @@ -0,0 +1,133 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.net.URI; +import java.nio.file.Path; +import java.time.Duration; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +import com.acme.websocket.PongContextListener; +import com.acme.websocket.PongMessageEndpoint; +import com.acme.websocket.PongSocket; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.javax.tests.Timeouts; +import org.eclipse.jetty.websocket.javax.tests.WSServer; +import org.eclipse.jetty.websocket.javax.tests.framehandlers.FrameHandlerTracker; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertTimeout; + +public class PingPongTest +{ + private static WSServer server; + private static WebSocketCoreClient client; + + @BeforeAll + public static void startServer() throws Exception + { + Path testdir = MavenTestingUtils.getTargetTestingPath(PingPongTest.class.getName()); + server = new WSServer(testdir, "app"); + server.copyWebInf("pong-config-web.xml"); + + server.copyClass(PongContextListener.class); + server.copyClass(PongMessageEndpoint.class); + server.copyClass(PongSocket.class); + + server.start(); + + WebAppContext webapp = server.createWebAppContext(); + server.deployWebapp(webapp); + } + + @BeforeAll + public static void startClient() throws Exception + { + client = new WebSocketCoreClient(); + client.start(); + } + + @AfterAll + public static void stopServer() throws Exception + { + server.stop(); + } + + private void assertEcho(String endpointPath, Consumer sendAction, String... expectedMsgs) throws Exception + { + FrameHandlerTracker clientSocket = new FrameHandlerTracker(); + URI toUri = server.getWsUri().resolve(endpointPath); + + // Connect + Future futureSession = client.connect(clientSocket, toUri); + CoreSession coreSession = futureSession.get(Timeouts.CONNECT_MS, TimeUnit.MILLISECONDS); + try + { + // Apply send action + sendAction.accept(coreSession); + + // Validate Responses + for (int i = 0; i < expectedMsgs.length; i++) + { + String pingMsg = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS); + assertThat("Expected message[" + i + "]", pingMsg, containsString(expectedMsgs[i])); + } + } + finally + { + coreSession.close(Callback.NOOP); + } + } + + @Test + public void testPongEndpoint() throws Exception + { + assertTimeout(Duration.ofMillis(6000), () -> + { + assertEcho("/app/pong", (session) -> + { + session.sendFrame(new Frame(OpCode.PONG).setPayload("hello"), Callback.NOOP, false); + }, "PongMessageEndpoint.onMessage(PongMessage):[/pong]:hello"); + }); + } + + @Test + public void testPongSocket() throws Exception + { + assertTimeout(Duration.ofMillis(6000), () -> + { + assertEcho("/app/pong-socket", (session) -> + { + session.sendFrame(new Frame(OpCode.PONG).setPayload("hello"), Callback.NOOP, false); + }, "PongSocket.onPong(PongMessage)[/pong-socket]:hello"); + }); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongContextListener.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongContextListener.java similarity index 67% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongContextListener.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongContextListener.java index 13108e4ee1d..28ebee0ac02 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongContextListener.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongContextListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongSocket.java similarity index 56% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongSocket.java index f6eb7cb15d7..ce1d2d82d5b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PongSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -27,13 +27,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint(value = "/pong-socket", configurator = PongContextListener.Config.class) public class PongSocket { - private static final Logger LOG = Log.getLogger(PongSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(PongSocket.class); private String path = "?"; private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesBinaryEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesBinaryEchoTest.java similarity index 82% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesBinaryEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesBinaryEchoTest.java index 543263f6564..a1bef5dec69 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesBinaryEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesBinaryEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -28,8 +28,6 @@ import javax.websocket.OnMessage; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.Hex; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -40,13 +38,15 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Test various {@link javax.websocket.Decoder.Binary Decoder.Binary} / {@link javax.websocket.Encoder.Binary Encoder.Binary} echo behavior of Java Primitives */ public class PrimitivesBinaryEchoTest { - private static final Logger LOG = Log.getLogger(PrimitivesBinaryEchoTest.class); + private static final Logger LOG = LoggerFactory.getLogger(PrimitivesBinaryEchoTest.class); public static class BaseSocket { diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesTextEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesTextEchoTest.java similarity index 93% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesTextEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesTextEchoTest.java index a01395e264b..da646af8a58 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesTextEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/PrimitivesTextEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -27,8 +27,6 @@ import javax.websocket.OnMessage; import javax.websocket.server.ServerContainer; import javax.websocket.server.ServerEndpoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -39,13 +37,15 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Test various {@link javax.websocket.Decoder.Text Decoder.Text} / {@link javax.websocket.Encoder.Text Encoder.Text} echo behavior of Java Primitives */ public class PrimitivesTextEchoTest { - private static final Logger LOG = Log.getLogger(PrimitivesTextEchoTest.class); + private static final Logger LOG = LoggerFactory.getLogger(PrimitivesTextEchoTest.class); public static class BaseSocket { @@ -268,6 +268,7 @@ public class PrimitivesTextEchoTest addCase(data, CharacterEchoSocket.class, Character.toString((char)40), "("); addCase(data, CharacterEchoSocket.class, Character.toString((char)106), "j"); addCase(data, CharacterEchoSocket.class, Character.toString((char)64), "@"); + // @checkstyle-disable-check : AvoidEscapedUnicodeCharactersCheck addCase(data, CharacterEchoSocket.class, Character.toString((char)0x262f), "\u262f"); addCase(data, CharacterObjEchoSocket.class, Character.toString((char)40), "("); @@ -324,14 +325,14 @@ public class PrimitivesTextEchoTest addCase(data, LongEchoSocket.class, Long.toString(0), "0"); addCase(data, LongEchoSocket.class, Long.toString(100_000), "100000"); addCase(data, LongEchoSocket.class, Long.toString(-2_000_000), "-2000000"); - addCase(data, LongEchoSocket.class, Long.toString(300_000_000_000l), "300000000000"); + addCase(data, LongEchoSocket.class, Long.toString(300_000_000_000L), "300000000000"); addCase(data, LongEchoSocket.class, Long.toString(Long.MAX_VALUE), Long.toString(Long.MAX_VALUE)); addCase(data, LongEchoSocket.class, Long.toString(Long.MIN_VALUE), Long.toString(Long.MIN_VALUE)); addCase(data, LongObjEchoSocket.class, Long.toString(0), "0"); addCase(data, LongObjEchoSocket.class, Long.toString(100_000), "100000"); addCase(data, LongObjEchoSocket.class, Long.toString(-2_000_000), "-2000000"); - addCase(data, LongObjEchoSocket.class, Long.toString(300_000_000_000l), "300000000000"); + addCase(data, LongObjEchoSocket.class, Long.toString(300_000_000_000L), "300000000000"); addCase(data, LongObjEchoSocket.class, Long.toString(Long.MAX_VALUE), Long.toString(Long.MAX_VALUE)); addCase(data, LongObjEchoSocket.class, Long.toString(Long.MIN_VALUE), Long.toString(Long.MIN_VALUE)); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ReaderEchoTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ReaderEchoTest.java similarity index 79% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ReaderEchoTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ReaderEchoTest.java index d7a60cdee0d..794b2470999 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ReaderEchoTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ReaderEchoTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -28,8 +28,6 @@ import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -38,13 +36,15 @@ import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Test various {@link javax.websocket.Decoder.TextStream Decoder.TextStream} and {@link javax.websocket.Encoder.TextStream Encoder.TextStream} echo behavior of Java Readers */ public class ReaderEchoTest { - private static final Logger LOG = Log.getLogger(ReaderEchoTest.class); + private static final Logger LOG = LoggerFactory.getLogger(ReaderEchoTest.class); public static class BaseSocket { diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java new file mode 100644 index 00000000000..f64f11814fc --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/ServerDecoderTest.java @@ -0,0 +1,170 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.net.URI; +import java.util.Collections; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import javax.websocket.ContainerProvider; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.javax.common.decoders.StringDecoder; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.tests.EventSocket; +import org.eclipse.jetty.websocket.javax.tests.WSEndpointTracker; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Example of an annotated echo server discovered via annotation scanning. + */ +public class ServerDecoderTest +{ + private static CompletableFuture annotatedServerSocket = new CompletableFuture<>(); + private static CompletableFuture configuredServerSocket = new CompletableFuture<>(); + + private Server server; + private URI serverURI; + + public static class EqualsAppendDecoder extends StringDecoder + { + @Override + public String decode(String s) + { + return s + "="; + } + } + + public static class PlusAppendDecoder extends StringDecoder + { + @Override + public String decode(String s) + { + return s + "+"; + } + } + + @ServerEndpoint(value = "/annotated", decoders = {EqualsAppendDecoder.class}) + public static class AnnotatedEndpoint extends EventSocket + { + @Override + public void onOpen(Session session, EndpointConfig config) + { + super.onOpen(session, config); + annotatedServerSocket.complete(this); + } + } + + public static class ConfiguredEndpoint extends WSEndpointTracker implements MessageHandler.Whole + { + @Override + public void onOpen(Session session, EndpointConfig config) + { + super.onOpen(session, config); + session.addMessageHandler(this); + configuredServerSocket.complete(this); + } + + @Override + public void onMessage(String message) + { + super.onWsText(message); + } + } + + @BeforeEach + public void startServer() throws Exception + { + server = new Server(); + ServerConnector serverConnector = new ServerConnector(server); + server.addConnector(serverConnector); + ServletContextHandler servletContextHandler = new ServletContextHandler(null, "/"); + server.setHandler(servletContextHandler); + + JavaxWebSocketServletContainerInitializer.configure(servletContextHandler, ((servletContext, serverContainer) -> + { + serverContainer.addEndpoint(AnnotatedEndpoint.class); + + ServerEndpointConfig config = ServerEndpointConfig.Builder.create(ConfiguredEndpoint.class, "/configured") + .decoders(Collections.singletonList(PlusAppendDecoder.class)) + .build(); + serverContainer.addEndpoint(config); + })); + + server.start(); + serverURI = new URI("ws://localhost:" + serverConnector.getLocalPort()); + } + + @AfterEach + public void stopServer() throws Exception + { + if (server != null) + server.stop(); + } + + @Test + public void testAnnotatedDecoder() throws Exception + { + WebSocketContainer client = ContainerProvider.getWebSocketContainer(); + EventSocket clientSocket = new EventSocket(); + Session session = client.connectToServer(clientSocket, serverURI.resolve("/annotated")); + session.getBasicRemote().sendText("hello world"); + + EventSocket serverSocket = annotatedServerSocket.get(5, TimeUnit.SECONDS); + assertTrue(serverSocket.openLatch.await(5, TimeUnit.SECONDS)); + String msg = serverSocket.textMessages.poll(5, TimeUnit.SECONDS); + assertThat(msg, is("hello world=")); + + clientSocket.session.close(); + clientSocket.closeLatch.await(5, TimeUnit.SECONDS); + serverSocket.closeLatch.await(5, TimeUnit.SECONDS); + } + + @Test + public void testConfiguredDecoder() throws Exception + { + WebSocketContainer client = ContainerProvider.getWebSocketContainer(); + EventSocket clientSocket = new EventSocket(); + Session session = client.connectToServer(clientSocket, serverURI.resolve("/configured")); + session.getBasicRemote().sendText("hello world"); + + WSEndpointTracker serverSocket = configuredServerSocket.get(5, TimeUnit.SECONDS); + assertTrue(serverSocket.openLatch.await(5, TimeUnit.SECONDS)); + String msg = serverSocket.messageQueue.poll(5, TimeUnit.SECONDS); + assertThat(msg, is("hello world+")); + + clientSocket.session.close(); + clientSocket.closeLatch.await(5, TimeUnit.SECONDS); + serverSocket.closeLatch.await(5, TimeUnit.SECONDS); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTest.java similarity index 86% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTest.java index e6863627545..91ab10a03ed 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -262,7 +262,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testPathParams_Annotated_Empty(Case testCase) throws Exception + public void testPathParamsAnnotatedEmpty(Case testCase) throws Exception { setup(testCase); assertResponse("/info/", "pathParams", @@ -271,7 +271,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testPathParams_Annotated_Single(Case testCase) throws Exception + public void testPathParamsAnnotatedSingle(Case testCase) throws Exception { setup(testCase); assertResponse("/info/apple/", "pathParams", @@ -280,7 +280,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testPathParams_Annotated_Double(Case testCase) throws Exception + public void testPathParamsAnnotatedDouble(Case testCase) throws Exception { setup(testCase); assertResponse("/info/apple/pear/", "pathParams", @@ -289,7 +289,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testPathParams_Annotated_Triple(Case testCase) throws Exception + public void testPathParamsAnnotatedTriple(Case testCase) throws Exception { setup(testCase); assertResponse("/info/apple/pear/cherry/", "pathParams", @@ -299,7 +299,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testPathParams_Endpoint_Empty(Case testCase) throws Exception + public void testPathParamsEndpointEmpty(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/", "pathParams", @@ -309,7 +309,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testPathParams_Endpoint_Single(Case testCase) throws Exception + public void testPathParamsEndpointSingle(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/apple/", "pathParams", @@ -319,7 +319,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testPathParams_Endpoint_Double(Case testCase) throws Exception + public void testPathParamsEndpointDouble(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/apple/pear/", "pathParams", @@ -329,7 +329,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testPathParams_Endpoint_Triple(Case testCase) throws Exception + public void testPathParamsEndpointTriple(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/apple/pear/cherry/", "pathParams", @@ -338,7 +338,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testRequestUri_Annotated_Basic(Case testCase) throws Exception + public void testRequestUriAnnotatedBasic(Case testCase) throws Exception { setup(testCase); assertResponse("/info/", "requestUri", @@ -347,7 +347,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testRequestUri_Annotated_WithPathParam(Case testCase) throws Exception + public void testRequestUriAnnotatedWithPathParam(Case testCase) throws Exception { setup(testCase); assertResponse("/info/apple/banana/", "requestUri", @@ -357,7 +357,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") - public void testRequestUri_Annotated_WithPathParam_WithQuery(Case testCase) throws Exception + public void testRequestUriAnnotatedWithPathParamWithQuery(Case testCase) throws Exception { setup(testCase); assertResponse("/info/apple/banana/?fruit=fresh&store=grandmasfarm", @@ -369,7 +369,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testRequestUri_Endpoint_Basic(Case testCase) throws Exception + public void testRequestUriEndpointBasic(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/", "requestUri", @@ -379,7 +379,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testRequestUri_Endpoint_WithPathParam(Case testCase) throws Exception + public void testRequestUriEndpointWithPathParam(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/apple/banana/", "requestUri", @@ -389,7 +389,7 @@ public class SessionTest @ParameterizedTest(name = "{0}") @MethodSource("data") @Disabled - public void testRequestUri_Endpoint_WithPathParam_WithQuery(Case testCase) throws Exception + public void testRequestUriEndpointWithPathParamWithQuery(Case testCase) throws Exception { setup(testCase); assertResponse("/einfo/apple/banana/?fruit=fresh&store=grandmasfarm", diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java similarity index 77% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java index b7de619e7ab..7a660cc421a 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/SessionTrackingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -27,7 +27,7 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.util.BlockingArrayQueue; -import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer; +import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; import org.eclipse.jetty.websocket.javax.tests.EventSocket; import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.junit.jupiter.api.AfterAll; @@ -42,7 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class SessionTrackingTest { - static BlockingArrayQueue serverSessions = new BlockingArrayQueue<>(); + private static BlockingArrayQueue serverSessions = new BlockingArrayQueue<>(); @ServerEndpoint("/session-info/{sessionId}") public static class SessionTrackingSocket @@ -109,29 +109,29 @@ public class SessionTrackingTest Session serverSession1 = serverSessions.poll(5, TimeUnit.SECONDS); assertNotNull(serverSession1); sendTextFrameToAll("openSessions|in-1", session1); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-1).size=1")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-1).size=1")); try (Session session2 = client.connectToServer(clientSocket2, server.getWsUri().resolve("/session-info/2"))) { Session serverSession2 = serverSessions.poll(5, TimeUnit.SECONDS); assertNotNull(serverSession2); sendTextFrameToAll("openSessions|in-2", session1, session2); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-2).size=2")); try (Session session3 = client.connectToServer(clientSocket3, server.getWsUri().resolve("/session-info/3"))) { Session serverSession3 = serverSessions.poll(5, TimeUnit.SECONDS); assertNotNull(serverSession3); sendTextFrameToAll("openSessions|in-3", session1, session2, session3); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); - assertThat(clientSocket3.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); + assertThat(clientSocket3.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@in-3).size=3")); sendTextFrameToAll("openSessions|lvl-3", session1, session2, session3); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); - assertThat(clientSocket3.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); + assertThat(clientSocket3.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-3).size=3")); // assert session is closed, and we have received the notification from the SessionListener session3.close(); @@ -140,8 +140,8 @@ public class SessionTrackingTest } sendTextFrameToAll("openSessions|lvl-2", session1, session2); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); - assertThat(clientSocket2.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); + assertThat(clientSocket2.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-2).size=2")); // assert session is closed, and we have received the notification from the SessionListener session2.close(); @@ -150,7 +150,7 @@ public class SessionTrackingTest } sendTextFrameToAll("openSessions|lvl-1", session1); - assertThat(clientSocket1.messageQueue.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-1).size=1")); + assertThat(clientSocket1.textMessages.poll(5, TimeUnit.SECONDS), is("openSessions(@lvl-1).size=1")); // assert session is closed, and we have received the notification from the SessionListener session1.close(); diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/StreamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/StreamTest.java similarity index 89% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/StreamTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/StreamTest.java index bfccd8681e6..ce70a7f39d9 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/StreamTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/StreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -51,14 +51,14 @@ import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainerProvider; import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.eclipse.jetty.websocket.javax.tests.Sha1Sum; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalToIgnoringCase; @@ -67,7 +67,7 @@ import static org.junit.jupiter.api.Assertions.assertTimeout; public class StreamTest { - private static final Logger LOG = Log.getLogger(StreamTest.class); + private static final Logger LOG = LoggerFactory.getLogger(StreamTest.class); private static File outputDir; private static LocalServer server; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/TextStreamTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/TextStreamTest.java new file mode 100644 index 00000000000..046608a90f2 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/TextStreamTest.java @@ -0,0 +1,368 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.ContainerProvider; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerContainer; +import javax.websocket.server.ServerEndpoint; +import javax.websocket.server.ServerEndpointConfig; + +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; +import org.eclipse.jetty.websocket.javax.tests.DataUtils; +import org.eclipse.jetty.websocket.javax.tests.Fuzzer; +import org.eclipse.jetty.websocket.javax.tests.LocalServer; +import org.eclipse.jetty.websocket.javax.tests.WSEndpointTracker; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TextStreamTest +{ + private static final Logger LOG = LoggerFactory.getLogger(TextStreamTest.class); + private static final BlockingArrayQueue serverEndpoints = new BlockingArrayQueue<>(); + + private final ClientEndpointConfig clientConfig = ClientEndpointConfig.Builder.create().build(); + private LocalServer server; + private ServerContainer container; + private WebSocketContainer wsClient; + + @BeforeEach + public void startServer() throws Exception + { + server = new LocalServer(); + server.start(); + container = server.getServerContainer(); + container.addEndpoint(ServerTextStreamer.class); + container.addEndpoint(ServerEndpointConfig.Builder.create(QueuedTextStreamer.class, "/test").build()); + container.addEndpoint(ServerEndpointConfig.Builder.create(QueuedPartialTextStreamer.class, "/partial").build()); + + wsClient = ContainerProvider.getWebSocketContainer(); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + @Test + public void testWith1kMessage() throws Exception + { + testEcho(1024); + } + + private byte[] newData(int size) + { + @SuppressWarnings("SpellCheckingInspection") + byte[] pattern = "01234567890abcdefghijlklmopqrstuvwxyz".getBytes(StandardCharsets.UTF_8); + byte[] data = new byte[size]; + for (int i = 0; i < size; i++) + { + data[i] = pattern[i % pattern.length]; + } + return data; + } + + private void testEcho(int size) throws Exception + { + byte[] data = newData(size); + + List send = new ArrayList<>(); + send.add(new Frame(OpCode.TEXT).setPayload(ByteBuffer.wrap(data))); + send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); + + ByteBuffer expectedMessage = DataUtils.copyOf(data); + List expect = new ArrayList<>(); + expect.add(new Frame(OpCode.TEXT).setPayload(expectedMessage)); + expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); + + try (Fuzzer fuzzer = server.newNetworkFuzzer("/echo")) + { + fuzzer.sendBulk(send); + fuzzer.expect(expect); + } + } + + // TODO These tests incorrectly assumes no frame fragmentation. + // When message fragmentation is implemented in PartialStringMessageSink then update + // this test to check on the server side for no buffers larger than the maxTextMessageBufferSize. + + @Disabled + @Test + public void testAtMaxDefaultMessageBufferSize() throws Exception + { + testEcho(container.getDefaultMaxTextMessageBufferSize()); + } + + @Disabled + @Test + public void testLargerThenMaxDefaultMessageBufferSize() throws Exception + { + int size = container.getDefaultMaxTextMessageBufferSize() + 16; + byte[] data = newData(size); + + List send = new ArrayList<>(); + send.add(new Frame(OpCode.TEXT).setPayload(ByteBuffer.wrap(data))); + send.add(CloseStatus.toFrame(CloseStatus.NORMAL)); + + // make copy of raw data (to avoid client masking during send) + byte[] expectedData = new byte[data.length]; + System.arraycopy(data, 0, expectedData, 0, data.length); + + // Frames expected are influenced by container.getDefaultMaxTextMessageBufferSize setting + ByteBuffer frame1 = ByteBuffer.wrap(expectedData, 0, container.getDefaultMaxTextMessageBufferSize()); + ByteBuffer frame2 = ByteBuffer + .wrap(expectedData, container.getDefaultMaxTextMessageBufferSize(), size - container.getDefaultMaxTextMessageBufferSize()); + List expect = new ArrayList<>(); + expect.add(new Frame(OpCode.TEXT).setPayload(frame1).setFin(false)); + expect.add(new Frame(OpCode.CONTINUATION).setPayload(frame2).setFin(true)); + expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); + + try (Fuzzer fuzzer = server.newNetworkFuzzer("/echo")) + { + fuzzer.sendBulk(send); + fuzzer.expect(expect); + } + } + + @Test + public void testMessageOrdering() throws Exception + { + ClientTextStreamer client = new ClientTextStreamer(); + Session session = wsClient.connectToServer(client, clientConfig, server.getWsUri().resolve("/test")); + + final int numLoops = 20; + for (int i = 0; i < numLoops; i++) + { + session.getBasicRemote().sendText(Integer.toString(i)); + } + session.close(); + + QueuedTextStreamer queuedTextStreamer = serverEndpoints.poll(5, TimeUnit.SECONDS); + assertNotNull(queuedTextStreamer); + for (int i = 0; i < numLoops; i++) + { + String msg = queuedTextStreamer.messages.poll(5, TimeUnit.SECONDS); + assertThat(msg, Matchers.is(Integer.toString(i))); + } + } + + @Test + public void testFragmentedMessageOrdering() throws Exception + { + ClientTextStreamer client = new ClientTextStreamer(); + Session session = wsClient.connectToServer(client, clientConfig, server.getWsUri().resolve("/test")); + + final int numLoops = 20; + for (int i = 0; i < numLoops; i++) + { + session.getBasicRemote().sendText("firstFrame" + i, false); + session.getBasicRemote().sendText("|secondFrame" + i, false); + session.getBasicRemote().sendText("|finalFrame" + i, true); + } + session.close(); + + QueuedTextStreamer queuedTextStreamer = serverEndpoints.poll(5, TimeUnit.SECONDS); + assertNotNull(queuedTextStreamer); + for (int i = 0; i < numLoops; i++) + { + String msg = queuedTextStreamer.messages.poll(5, TimeUnit.SECONDS); + String expected = "firstFrame" + i + "|secondFrame" + i + "|finalFrame" + i; + assertThat(msg, Matchers.is(expected)); + } + } + + @Test + public void testMessageOrderingDoNotReadToEOF() throws Exception + { + ClientTextStreamer clientEndpoint = new ClientTextStreamer(); + Session session = wsClient.connectToServer(clientEndpoint, clientConfig, server.getWsUri().resolve("/partial")); + QueuedTextStreamer serverEndpoint = Objects.requireNonNull(serverEndpoints.poll(5, TimeUnit.SECONDS)); + + int serverInputBufferSize = 1024; + JavaxWebSocketSession serverSession = (JavaxWebSocketSession)serverEndpoint.session; + serverSession.getCoreSession().setInputBufferSize(serverInputBufferSize); + + // Write some initial data. + Writer writer = session.getBasicRemote().getSendWriter(); + writer.write("first frame"); + writer.flush(); + + // Signal to stop reading. + writer.write("|"); + writer.flush(); + + // Lots of data after we have stopped reading and onMessage exits. + final String largePayload = StringUtil.stringFrom("x", serverInputBufferSize * 2); + writer.write(largePayload); + writer.close(); + + session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(serverEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertNull(clientEndpoint.error.get()); + assertNull(serverEndpoint.error.get()); + + String msg = serverEndpoint.messages.poll(5, TimeUnit.SECONDS); + assertThat(msg, Matchers.is("first frame")); + } + + public static class ClientTextStreamer extends WSEndpointTracker implements MessageHandler.Whole + { + private final CountDownLatch latch = new CountDownLatch(1); + private final StringBuilder output = new StringBuilder(); + + @Override + public void onOpen(Session session, EndpointConfig config) + { + session.addMessageHandler(this); + super.onOpen(session, config); + } + + @Override + public void onMessage(Reader input) + { + try + { + while (true) + { + int read = input.read(); + if (read < 0) + break; + output.append((char)read); + } + latch.countDown(); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + } + + @ServerEndpoint("/echo") + public static class ServerTextStreamer + { + @OnMessage + public void echo(Session session, Reader input) throws IOException + { + char[] buffer = new char[128]; + try (Writer output = session.getBasicRemote().getSendWriter()) + { + long totalRead = 0; + int read; + while ((read = input.read(buffer)) >= 0) + { + totalRead += read; + output.write(buffer, 0, read); + } + + LOG.debug("{} total bytes read/write", totalRead); + } + } + } + + public static class QueuedTextStreamer extends WSEndpointTracker implements MessageHandler.Whole + { + protected BlockingArrayQueue messages = new BlockingArrayQueue<>(); + + @Override + public void onOpen(Session session, EndpointConfig config) + { + session.addMessageHandler(this); + super.onOpen(session, config); + serverEndpoints.add(this); + } + + @Override + public void onMessage(Reader input) + { + try + { + Thread.sleep(Math.abs(new Random().nextLong() % 200)); + messages.add(IO.toString(input)); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + + public static class QueuedPartialTextStreamer extends QueuedTextStreamer + { + @Override + public void onMessage(Reader input) + { + try + { + Thread.sleep(Math.abs(new Random().nextLong() % 200)); + + // Do not read to EOF but just the first '|'. + StringWriter writer = new StringWriter(); + while (true) + { + int read = input.read(); + if (read < 0 || read == '|') + break; + writer.write(read); + } + + messages.add(writer.toString()); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/UriTemplateParameterTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/UriTemplateParameterTest.java similarity index 69% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/UriTemplateParameterTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/UriTemplateParameterTest.java index 8cee01f94e3..2accaf59ce2 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/UriTemplateParameterTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/UriTemplateParameterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -26,8 +26,6 @@ import javax.websocket.OnMessage; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; @@ -36,10 +34,12 @@ import org.eclipse.jetty.websocket.javax.tests.LocalServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class UriTemplateParameterTest { - private static final Logger LOG = Log.getLogger(UriTemplateParameterTest.class); + private static final Logger LOG = LoggerFactory.getLogger(UriTemplateParameterTest.class); @ServerEndpoint("/echo/params/{a}/{b}") public static class IntParamTextSocket diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebAppClassLoaderTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebAppClassLoaderTest.java new file mode 100644 index 00000000000..9e40e26ab78 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebAppClassLoaderTest.java @@ -0,0 +1,141 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server; + +import java.nio.file.Path; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; +import javax.websocket.ContainerProvider; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession; +import org.eclipse.jetty.websocket.javax.tests.EventSocket; +import org.eclipse.jetty.websocket.javax.tests.WSServer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class WebAppClassLoaderTest +{ + @ServerEndpoint("/echo") + public static class MySocket + { + public static final CountDownLatch closeLatch = new CountDownLatch(1); + public static final Map classLoaders = new ConcurrentHashMap<>(); + + public MySocket() + { + classLoaders.put("constructor", Thread.currentThread().getContextClassLoader()); + } + + @OnOpen + public void onOpen(Session session) + { + classLoaders.put("onOpen", Thread.currentThread().getContextClassLoader()); + } + + @OnMessage + public void onMessage(Session session, String msg) + { + classLoaders.put("onMessage", Thread.currentThread().getContextClassLoader()); + } + + @OnError + public void onError(Throwable error) + { + classLoaders.put("onError", Thread.currentThread().getContextClassLoader()); + } + + @OnClose + public void onClose(CloseReason closeReason) + { + classLoaders.put("onClose", Thread.currentThread().getContextClassLoader()); + closeLatch.countDown(); + } + } + + private WSServer server; + private WebAppContext webapp; + + @BeforeEach + public void startServer() throws Exception + { + Path testdir = MavenTestingUtils.getTargetTestingPath(WebAppClassLoaderTest.class.getName()); + server = new WSServer(testdir, "app"); + server.createWebInf(); + server.copyEndpoint(MySocket.class); + server.start(); + webapp = server.createWebAppContext(); + server.deployWebapp(webapp); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + private void awaitServerClose() throws Exception + { + ClassLoader webAppClassLoader = webapp.getClassLoader(); + Class mySocketClass = webAppClassLoader.loadClass(MySocket.class.getName()); + CountDownLatch closeLatch = (CountDownLatch)mySocketClass.getDeclaredField("closeLatch").get(null); + assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); + } + + private ClassLoader getClassLoader(String event) throws Exception + { + ClassLoader webAppClassLoader = webapp.getClassLoader(); + Class mySocketClass = webAppClassLoader.loadClass(MySocket.class.getName()); + Map classLoaderMap = (Map)mySocketClass.getDeclaredField("classLoaders").get(null); + return classLoaderMap.get(event); + } + + @ParameterizedTest + @ValueSource(strings = {"constructor", "onOpen", "onMessage", "onError", "onClose"}) + public void testForWebAppClassLoader(String event) throws Exception + { + WebSocketContainer client = ContainerProvider.getWebSocketContainer(); + EventSocket clientSocket = new EventSocket(); + Session session = client.connectToServer(clientSocket, server.getWsUri().resolve("/app/echo")); + session.getBasicRemote().sendText("trigger onMessage -> onError -> onClose"); + ((JavaxWebSocketSession)session).abort(); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + awaitServerClose(); + + ClassLoader webAppClassLoader = webapp.getClassLoader(); + assertThat(event, getClassLoader(event), is(webAppClassLoader)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java similarity index 83% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java index 7db6aa77bbe..081037827e1 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server; @@ -30,11 +30,12 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.websocket.ClientEndpoint; import javax.websocket.ContainerProvider; -import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.OnError; import javax.websocket.OnMessage; +import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.WebSocketContainer; import javax.websocket.server.ServerEndpoint; @@ -44,12 +45,12 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServerContainer; -import org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer; import org.eclipse.jetty.websocket.javax.tests.WSURI; import org.junit.jupiter.api.Test; -import static org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer.HTTPCLIENT_ATTRIBUTE; +import static org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer.HTTPCLIENT_ATTRIBUTE; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.sameInstance; @@ -73,9 +74,10 @@ public class WebSocketServerContainerExecutorTest } } - public static class EndpointAdapter extends Endpoint + @ClientEndpoint + public static class EndpointAdapter { - @Override + @OnOpen public void onOpen(Session session, EndpointConfig config) { /* do nothing */ @@ -172,7 +174,7 @@ public class WebSocketServerContainerExecutorTest try { server.start(); - String response = GET(server.getURI().resolve("/connect")); + String response = doGet(server.getURI().resolve("/connect")); assertThat("Response", response, startsWith("Connected to ws://")); Executor containerExecutor = getJavaxServerContainerExecutor(contextHandler); @@ -201,7 +203,7 @@ public class WebSocketServerContainerExecutorTest try { server.start(); - String response = GET(server.getURI().resolve("/connect")); + String response = doGet(server.getURI().resolve("/connect")); assertThat("Response", response, startsWith("Connected to ws://")); Executor containerExecutor = getJavaxServerContainerExecutor(contextHandler); @@ -213,7 +215,7 @@ public class WebSocketServerContainerExecutorTest } } - private String GET(URI destURI) throws IOException + private String doGet(URI destURI) throws IOException { HttpURLConnection http = (HttpURLConnection)destURI.toURL().openConnection(); assertThat("HTTP GET (" + destURI + ") Response Code", http.getResponseCode(), is(200)); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/configs/EchoSocketConfigurator.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/configs/EchoSocketConfigurator.java new file mode 100644 index 00000000000..1037e6e8e3d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/configs/EchoSocketConfigurator.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.configs; + +import java.util.Collections; +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpointConfig; + +public class EchoSocketConfigurator extends ServerEndpointConfig.Configurator +{ + @Override + public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) + { + response.getHeaders().put("X-Test", Collections.singletonList("Extra")); + super.modifyHandshake(sec, request, response); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java new file mode 100644 index 00000000000..f0e10464f7a --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import java.nio.ByteBuffer; +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/basic") +public class BasicBinaryMessageByteBufferSocket extends TrackingSocket +{ + @OnMessage + public void onBinary(ByteBuffer data) + { + addEvent("onBinary(%s)", data); + dataLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSessionSocket.java new file mode 100644 index 00000000000..d749fade608 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSessionSocket.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/close/reason/session") +public class BasicCloseReasonSessionSocket extends TrackingSocket +{ + @OnClose + public void onClose(CloseReason reason, Session session) + { + addEvent("onClose(%s,%s)", reason, session); + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSocket.java new file mode 100644 index 00000000000..2f88a7b2e6d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseReasonSocket.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/close/reason") +public class BasicCloseReasonSocket extends TrackingSocket +{ + @OnClose + public void onClose(CloseReason reason) + { + addEvent("onClose(%s)", reason); + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSessionReasonSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSessionReasonSocket.java new file mode 100644 index 00000000000..1c9c8c98083 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSessionReasonSocket.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/close/session/reason") +public class BasicCloseSessionReasonSocket extends TrackingSocket +{ + @OnClose + public void onClose(Session session, CloseReason reason) + { + addEvent("onClose(%s,%s)", session, reason); + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSocket.java new file mode 100644 index 00000000000..a3ea2a243d6 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicCloseSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnClose; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/close") +public class BasicCloseSocket extends TrackingSocket +{ + @OnClose + public void onClose() + { + addEvent("onClose()"); + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicEchoSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicEchoSocket.java new file mode 100644 index 00000000000..35a8c754c00 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicEchoSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** + * Annotated echo socket + */ +@ServerEndpoint("/echo") +public class BasicEchoSocket +{ + @OnMessage + public void echo(Session session, String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionSocket.java new file mode 100644 index 00000000000..72465a614dc --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/error/session") +public class BasicErrorSessionSocket extends TrackingSocket +{ + @OnError + public void onError(Session session) + { + addEvent("onError(%s)", session); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionThrowableSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionThrowableSocket.java new file mode 100644 index 00000000000..0ca9f6e090a --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSessionThrowableSocket.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/error/session/throwable") +public class BasicErrorSessionThrowableSocket extends TrackingSocket +{ + @OnError + public void onError(Session session, Throwable t) + { + addEvent("onError(%s,%s)", session, t); + addError(t); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSocket.java new file mode 100644 index 00000000000..4219628a1ea --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorSocket.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/error") +public class BasicErrorSocket extends TrackingSocket +{ + @OnError + public void onError() + { + addEvent("onError()"); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSessionSocket.java new file mode 100644 index 00000000000..b504bb6af19 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSessionSocket.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/error/throwable/session") +public class BasicErrorThrowableSessionSocket extends TrackingSocket +{ + @OnError + public void onError(Throwable t, Session session) + { + addEvent("onError(%s,%s)", t, session); + addError(t); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSocket.java new file mode 100644 index 00000000000..a5a2df0495d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicErrorThrowableSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/error/throwable") +public class BasicErrorThrowableSocket extends TrackingSocket +{ + @OnError + public void onError(Throwable t) + { + addEvent("onError(%s)", t); + addError(t); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSessionSocket.java new file mode 100644 index 00000000000..0100981b7a6 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSessionSocket.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/basic") +public class BasicOpenCloseSessionSocket extends TrackingSocket +{ + @OnClose + public void onClose(CloseReason close, Session session) + { + addEvent("onClose(%s, %s)", close, session); + this.closeReason = close; + closeLatch.countDown(); + } + + @OnOpen + public void onOpen(Session session) + { + addEvent("onOpen(%s)", session); + openLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSocket.java new file mode 100644 index 00000000000..f7f7eece16e --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenCloseSocket.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.OnOpen; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/basic") +public class BasicOpenCloseSocket extends TrackingSocket +{ + @OnOpen + public void onOpen() + { + openLatch.countDown(); + } + + @OnClose + public void onClose(CloseReason close) + { + this.closeReason = close; + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSessionSocket.java new file mode 100644 index 00000000000..deff1f6761f --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSessionSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/onOpen/session") +public class BasicOpenSessionSocket extends TrackingSocket +{ + @OnOpen + public void onOpen(Session session) + { + openLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSocket.java new file mode 100644 index 00000000000..d5bd497cc1a --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicOpenSocket.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnOpen; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/onOpen") +public class BasicOpenSocket extends TrackingSocket +{ + @OnOpen + public void onOpen() + { + openLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicPongMessageSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicPongMessageSocket.java new file mode 100644 index 00000000000..418a5d40d07 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicPongMessageSocket.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnMessage; +import javax.websocket.PongMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/echo/pong") +public class BasicPongMessageSocket extends TrackingSocket +{ + @OnMessage + public void onPong(PongMessage pong) + { + addEvent("onPong(%s)", pong); + dataLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicTextMessageStringSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicTextMessageStringSocket.java new file mode 100644 index 00000000000..f4ddd4bf9ac --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicTextMessageStringSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/basic") +public class BasicTextMessageStringSocket extends TrackingSocket +{ + @OnMessage + public void onText(String message) + { + addEvent("onText(%s)", message); + dataLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ByteBufferSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ByteBufferSocket.java new file mode 100644 index 00000000000..29f0b43fe49 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ByteBufferSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import java.io.IOException; +import java.nio.ByteBuffer; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.eclipse.jetty.util.BufferUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/binary/bytebuffer") +public class ByteBufferSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(ByteBufferSocket.class); + + @OnMessage + public String onByteBuffer(ByteBuffer bbuf) + { + return BufferUtil.toUTF8String(bbuf); + } + + @OnError + public void onError(Session session, Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ConfiguredEchoSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ConfiguredEchoSocket.java similarity index 80% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ConfiguredEchoSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ConfiguredEchoSocket.java index 0b186acd9fc..7e4c15cff58 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ConfiguredEchoSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/ConfiguredEchoSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/DateTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/DateTextSocket.java similarity index 59% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/DateTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/DateTextSocket.java index 8a6225b52ee..62f885d837d 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/DateTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/DateTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets; @@ -27,15 +27,15 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.javax.tests.coders.DateDecoder; import org.eclipse.jetty.websocket.javax.tests.coders.DateEncoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint(value = "/echo/beans/date", decoders = {DateDecoder.class}, encoders = {DateEncoder.class}) public class DateTextSocket { - private static final Logger LOG = Log.getLogger(DateTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(DateTextSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java new file mode 100644 index 00000000000..fe1dadcdace --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +public class IdleTimeoutOnOpenEndpoint extends Endpoint implements MessageHandler.Whole +{ + private Session session; + + @Override + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + session.addMessageHandler(this); + session.setMaxIdleTimeout(500); + } + + @Override + public void onMessage(String message) + { + // echo message back (this is an indication of timeout failure) + session.getAsyncRemote().sendText(message); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenSocket.java new file mode 100644 index 00000000000..a0f50073941 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/IdleTimeoutOnOpenSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException; + +@ServerEndpoint(value = "/idle-onopen-socket") +public class IdleTimeoutOnOpenSocket +{ + @OnOpen + public void onOpen(Session session) + { + session.setMaxIdleTimeout(500); + } + + @OnMessage + public String onMessage(String msg) + { + return msg; + } + + @OnError + public void onError(Throwable cause) + { + if (!(cause instanceof WebSocketTimeoutException)) + throw new RuntimeException(cause); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidCloseIntSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidCloseIntSocket.java new file mode 100644 index 00000000000..9bf08efa13c --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidCloseIntSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnClose; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/invalid") +public class InvalidCloseIntSocket extends TrackingSocket +{ + /** + * Invalid Close Method Declaration (parameter type int) + * + * @param statusCode the status code + */ + @OnClose + public void onClose(int statusCode) + { + closeLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorErrorSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorErrorSocket.java new file mode 100644 index 00000000000..a30d53d1a4b --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorErrorSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/invalid") +public class InvalidErrorErrorSocket extends TrackingSocket +{ + /** + * Invalid Error Method Declaration (parameter type Error) + * + * @param error the error + */ + @OnError + public void onError(Error error) + { + /* no impl */ + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorIntSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorIntSocket.java new file mode 100644 index 00000000000..e9641d6df64 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidErrorIntSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnError; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/invalid") +public class InvalidErrorIntSocket extends TrackingSocket +{ + /** + * Invalid Error Method Declaration (parameter type int) + * + * @param errorCount the error count + */ + @OnError + public void onError(int errorCount) + { + /* no impl */ + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenCloseReasonSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenCloseReasonSocket.java new file mode 100644 index 00000000000..81f8182896f --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenCloseReasonSocket.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.CloseReason; +import javax.websocket.OnOpen; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/invalid") +public class InvalidOpenCloseReasonSocket extends TrackingSocket +{ + /** + * Invalid Open Method Declaration (parameter type CloseReason) + * + * @param reason the close reason + */ + @OnOpen + public void onOpen(CloseReason reason) + { + openLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenIntSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenIntSocket.java new file mode 100644 index 00000000000..2ceb4b482c8 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenIntSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnOpen; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/invalid") +public class InvalidOpenIntSocket extends TrackingSocket +{ + /** + * Invalid Open Method Declaration (parameter type int) + * + * @param value the value + */ + @OnOpen + public void onOpen(int value) + { + openLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenSessionIntSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenSessionIntSocket.java new file mode 100644 index 00000000000..d1b087d94ea --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/InvalidOpenSessionIntSocket.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/invalid") +public class InvalidOpenSessionIntSocket extends TrackingSocket +{ + /** + * Invalid Open Method Declaration (parameter of type int) + * + * @param session the sesion + * @param count the count + */ + @OnOpen + public void onOpen(Session session, int count) + { + openLatch.countDown(); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/StatelessTextMessageStringSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/StatelessTextMessageStringSocket.java new file mode 100644 index 00000000000..b1004a0b225 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/StatelessTextMessageStringSocket.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets; + +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/stateless") +public class StatelessTextMessageStringSocket extends TrackingSocket +{ + @OnMessage + public void onText(Session session, String message) + { + addEvent("onText(%s,%s)", session, message); + dataLatch.countDown(); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/TrackingSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/TrackingSocket.java similarity index 52% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/TrackingSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/TrackingSocket.java index c2f1c6fcde7..1ef52879c42 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/TrackingSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/TrackingSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/binary/ByteBufferSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/binary/ByteBufferSocket.java new file mode 100644 index 00000000000..95001d54f3c --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/binary/ByteBufferSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.binary; + +import java.io.IOException; +import java.nio.ByteBuffer; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.eclipse.jetty.util.BufferUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/binary/bytebuffer") +public class ByteBufferSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(ByteBufferSocket.class); + + @OnMessage + public String onByteBuffer(ByteBuffer bbuf) + { + return BufferUtil.toUTF8String(bbuf); + } + + @OnError + public void onError(Session session, Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoEndpoint.java new file mode 100644 index 00000000000..83356059e81 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoEndpoint.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +/** + * Example of websocket endpoint based on extending {@link Endpoint} + */ +public class BasicEchoEndpoint extends Endpoint implements MessageHandler.Whole +{ + private Session session; + + @Override + public void onMessage(String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } + + @Override + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + this.session.addMessageHandler(this); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoSocket.java new file mode 100644 index 00000000000..810630e9474 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/BasicEchoSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** + * Annotated echo socket + */ +@ServerEndpoint("/echo") +public class BasicEchoSocket +{ + @OnMessage + public void echo(Session session, String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoAsyncTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoAsyncTextSocket.java new file mode 100644 index 00000000000..aeec2baefe9 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoAsyncTextSocket.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/echo/text/async") +public class EchoAsyncTextSocket +{ + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onText(String msg) + { + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoBasicTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoBasicTextSocket.java similarity index 56% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoBasicTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoBasicTextSocket.java index a20543e03d4..705771aebbe 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoBasicTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoBasicTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnEndpoint.java similarity index 58% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnEndpoint.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnEndpoint.java index 4ecbcb20501..01561d25b50 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnEndpoint.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnTextSocket.java new file mode 100644 index 00000000000..f1e576445d0 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoReturnTextSocket.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/echo/text/return") +public class EchoReturnTextSocket +{ + @OnMessage + public String onText(String msg) + { + return msg; + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java new file mode 100644 index 00000000000..881882d7553 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/echo/text/async/stateless") +public class EchoStatelessAsyncTextSocket +{ + @OnMessage + public void onText(Session session, String msg) + { + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java index 84eba4efb2f..d335fae8434 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.echo; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoConfiguredSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoConfiguredSocket.java new file mode 100644 index 00000000000..291aab54a0d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoConfiguredSocket.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +/** + * Annotated echo socket + */ +@ServerEndpoint(value = "/echo/large") +public class LargeEchoConfiguredSocket +{ + private Session session; + + @OnOpen + public void open(Session session) + { + this.session = session; + this.session.setMaxTextMessageBufferSize(128 * 1024); + } + + @OnMessage + public void echo(String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoDefaultSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoDefaultSocket.java new file mode 100644 index 00000000000..1eb5d6e234c --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/echo/LargeEchoDefaultSocket.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.echo; + +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; + +/** + * Annotated echo socket (default behavior as defined from {@link WebSocketContainer#setDefaultMaxTextMessageBufferSize(int)}) + */ +@ServerEndpoint(value = "/echo/large") +public class LargeEchoDefaultSocket +{ + @OnMessage + public void echo(Session session, String msg) + { + // reply with echo + session.getAsyncRemote().sendText(msg); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java new file mode 100644 index 00000000000..569c9b8c983 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.idletimeout; + +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.MessageHandler; +import javax.websocket.Session; + +public class OnOpenIdleTimeoutEndpoint extends Endpoint implements MessageHandler.Whole +{ + private Session session; + + @Override + public void onOpen(Session session, EndpointConfig config) + { + this.session = session; + session.addMessageHandler(this); + session.setMaxIdleTimeout(500); + } + + @Override + public void onMessage(String message) + { + // echo message back (this is an indication of timeout failure) + session.getAsyncRemote().sendText(message); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java new file mode 100644 index 00000000000..caef4148749 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.idletimeout; + +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint(value = "/idle-onopen-socket") +public class OnOpenIdleTimeoutSocket +{ + @OnOpen + public void onOpen(Session session) + { + session.setMaxIdleTimeout(500); + } + + @OnMessage + public String onMessage(String msg) + { + return msg; + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSessionSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSessionSocket.java similarity index 51% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSessionSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSessionSocket.java index 52bc7ff1eb6..94e6748af76 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSessionSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSessionSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.partial; @@ -25,13 +25,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/partial/textsession") public class PartialTextSessionSocket { - private static final Logger LOG = Log.getLogger(PartialTextSessionSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(PartialTextSessionSocket.class); private StringBuilder buf = new StringBuilder(); @OnMessage diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSocket.java similarity index 54% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSocket.java index 91d64bcfa77..72b64f102ba 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.partial; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/partial/text") public class PartialTextSocket { - private static final Logger LOG = Log.getLogger(PartialTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(PartialTextSocket.class); private Session session; private StringBuilder buf = new StringBuilder(); diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTrackingSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTrackingSocket.java new file mode 100644 index 00000000000..27aaa397a82 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/partial/PartialTrackingSocket.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.partial; + +import java.io.IOException; +import javax.websocket.OnMessage; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.websocket.javax.tests.server.sockets.TrackingSocket; + +@ServerEndpoint("/echo/partial/tracking") +public class PartialTrackingSocket extends TrackingSocket +{ + @OnMessage + public void onPartial(String msg, boolean fin) throws IOException + { + addEvent("onPartial(\"%s\",%b)", msg, fin); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/pong/PongMessageEndpoint.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/pong/PongMessageEndpoint.java similarity index 57% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/pong/PongMessageEndpoint.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/pong/PongMessageEndpoint.java index c6b12f79fe1..bec0b116ec8 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/pong/PongMessageEndpoint.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/pong/PongMessageEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.pong; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java similarity index 55% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java index 4197abec7ef..56f572f0aac 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/booleanobject/params/{a}") public class BooleanObjectTextParamSocket { - private static final Logger LOG = Log.getLogger(BooleanObjectTextParamSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(BooleanObjectTextParamSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextSocket.java index d0eae4dcfb4..a7f0ffd1fdf 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/booleanobject") public class BooleanObjectTextSocket { - private static final Logger LOG = Log.getLogger(BooleanObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(BooleanObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextParamSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextParamSocket.java similarity index 52% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextParamSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextParamSocket.java index 898e464dda7..c45c25059e9 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextParamSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextParamSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/boolean/params/{a}") public class BooleanTextParamSocket { - private static final Logger LOG = Log.getLogger(BooleanTextParamSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(BooleanTextParamSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextSocket.java new file mode 100644 index 00000000000..d73bafcdd78 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/BooleanTextSocket.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.primitives; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/primitives/boolean") +public class BooleanTextSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(BooleanTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(boolean b) throws IOException + { + String msg = Boolean.toString(b); + session.getAsyncRemote().sendText(msg); + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteObjectTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteObjectTextSocket.java index ba152452d47..676a29d955b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/byteobject") public class ByteObjectTextSocket { - private static final Logger LOG = Log.getLogger(ByteObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(ByteObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteTextSocket.java new file mode 100644 index 00000000000..014fc4e55eb --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ByteTextSocket.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.primitives; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/primitives/byte") +public class ByteTextSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(ByteTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(byte b) throws IOException + { + String msg = String.format("0x%02X", b); + session.getAsyncRemote().sendText(msg); + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharTextSocket.java new file mode 100644 index 00000000000..471a5c7646d --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharTextSocket.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.primitives; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/primitives/char") +public class CharTextSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(CharTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(char c) throws IOException + { + String msg = Character.toString(c); + session.getAsyncRemote().sendText(msg); + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharacterObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharacterObjectTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharacterObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharacterObjectTextSocket.java index 76f6d7d9b0f..635ca8736cb 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharacterObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/CharacterObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/characterobject") public class CharacterObjectTextSocket { - private static final Logger LOG = Log.getLogger(CharacterObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(CharacterObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleObjectTextSocket.java similarity index 54% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleObjectTextSocket.java index 1ba0538e02b..24d3471b5e6 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/doubleobject") public class DoubleObjectTextSocket { - private static final Logger LOG = Log.getLogger(DoubleObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(DoubleObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleTextSocket.java similarity index 50% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleTextSocket.java index b7f05086674..2bb42b77d4b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/DoubleTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/double") public class DoubleTextSocket { - private static final Logger LOG = Log.getLogger(DoubleTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(DoubleTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatObjectTextSocket.java similarity index 54% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatObjectTextSocket.java index 9d5593e4aa1..700cf6cb1e5 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/floatobject") public class FloatObjectTextSocket { - private static final Logger LOG = Log.getLogger(FloatObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(FloatObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatTextSocket.java similarity index 50% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatTextSocket.java index 6fc6e4bc1a2..a862539626e 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/FloatTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/float") public class FloatTextSocket { - private static final Logger LOG = Log.getLogger(FloatTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(FloatTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntParamTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntParamTextSocket.java similarity index 52% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntParamTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntParamTextSocket.java index 53d9c4fa3e8..d82a0a2837f 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntParamTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntParamTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/integer/params/{a}") public class IntParamTextSocket { - private static final Logger LOG = Log.getLogger(IntParamTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(IntParamTextSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntTextSocket.java new file mode 100644 index 00000000000..8a0e05e712b --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntTextSocket.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.primitives; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/primitives/integer") +public class IntTextSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(IntTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(int i) throws IOException + { + String msg = Integer.toString(i); + session.getAsyncRemote().sendText(msg); + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java similarity index 55% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java index 2ecde8d2881..e8aaa7f271f 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -27,13 +27,13 @@ import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/integerobject/params/{a}") public class IntegerObjectParamTextSocket { - private static final Logger LOG = Log.getLogger(IntegerObjectParamTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(IntegerObjectParamTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectTextSocket.java index 2e053c15103..df438c93cf3 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/IntegerObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/integerobject") public class IntegerObjectTextSocket { - private static final Logger LOG = Log.getLogger(IntegerObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(IntegerObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongObjectTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongObjectTextSocket.java index bc5bac68040..24c800e2d5a 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/longobject") public class LongObjectTextSocket { - private static final Logger LOG = Log.getLogger(LongObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(LongObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongTextSocket.java new file mode 100644 index 00000000000..e8850a95af9 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/LongTextSocket.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.primitives; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/primitives/long") +public class LongTextSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(LongTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(long l) throws IOException + { + String msg = Long.toString(l); + session.getAsyncRemote().sendText(msg); + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortObjectTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortObjectTextSocket.java similarity index 53% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortObjectTextSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortObjectTextSocket.java index 76d8f013271..c9cabf12fd6 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortObjectTextSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortObjectTextSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.primitives; @@ -26,13 +26,13 @@ import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/primitives/shortobject") public class ShortObjectTextSocket { - private static final Logger LOG = Log.getLogger(ShortObjectTextSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(ShortObjectTextSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortTextSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortTextSocket.java new file mode 100644 index 00000000000..8a6974b52e3 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/primitives/ShortTextSocket.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.primitives; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/primitives/short") +public class ShortTextSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(ShortTextSocket.class); + + private Session session; + + @OnOpen + public void onOpen(Session session) + { + this.session = session; + } + + @OnMessage + public void onMessage(short s) throws IOException + { + String msg = Short.toString(s); + session.getAsyncRemote().sendText(msg); + } + + @OnError + public void onError(Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/InputStreamSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/InputStreamSocket.java new file mode 100644 index 00000000000..361f44c3bc7 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/InputStreamSocket.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.streaming; + +import java.io.IOException; +import java.io.InputStream; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/streaming/inputstream") +public class InputStreamSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(InputStreamSocket.class); + + @OnMessage + public String onInputStream(InputStream stream) throws IOException + { + return IO.toString(stream, StringUtil.__UTF8); + } + + @OnError + public void onError(Session session, Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderParamSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderParamSocket.java similarity index 55% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderParamSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderParamSocket.java index e62a563f105..113a51a1a9e 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderParamSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderParamSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.streaming; @@ -29,13 +29,13 @@ import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/streaming/readerparam/{param}") public class ReaderParamSocket { - private static final Logger LOG = Log.getLogger(ReaderParamSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(ReaderParamSocket.class); private Session session; diff --git a/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderSocket.java new file mode 100644 index 00000000000..538ff988599 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/ReaderSocket.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.javax.tests.server.sockets.streaming; + +import java.io.IOException; +import java.io.Reader; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.toolchain.test.StackUtils; +import org.eclipse.jetty.util.IO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServerEndpoint("/echo/streaming/reader") +public class ReaderSocket +{ + private static final Logger LOG = LoggerFactory.getLogger(ReaderSocket.class); + + @OnMessage + public String onReader(Reader reader) throws IOException + { + return IO.toString(reader); + } + + @OnError + public void onError(Session session, Throwable cause) throws IOException + { + LOG.warn("Error", cause); + session.getBasicRemote().sendText("Exception: " + StackUtils.toString(cause)); + } +} diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/StringReturnReaderParamSocket.java b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/StringReturnReaderParamSocket.java similarity index 52% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/StringReturnReaderParamSocket.java rename to jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/StringReturnReaderParamSocket.java index 02d35890abc..3e5176f92cf 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/StringReturnReaderParamSocket.java +++ b/jetty-websocket/websocket-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/streaming/StringReturnReaderParamSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.javax.tests.server.sockets.streaming; @@ -28,13 +28,13 @@ import javax.websocket.server.ServerEndpoint; import org.eclipse.jetty.toolchain.test.StackUtils; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ServerEndpoint("/echo/streaming/readerparam2/{param}") public class StringReturnReaderParamSocket { - private static final Logger LOG = Log.getLogger(StringReturnReaderParamSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(StringReturnReaderParamSocket.class); @OnMessage public String onReader(Reader reader, @PathParam("param") String param) throws IOException diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/alt-filter-web.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/alt-filter-web.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/alt-filter-web.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/alt-filter-web.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/large-echo-config-web.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/basic-echo-endpoint-config-web.xml similarity index 72% rename from jetty-websocket/javax-websocket-tests/src/test/resources/large-echo-config-web.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/basic-echo-endpoint-config-web.xml index c4dfacddef3..191ba7fff8b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/resources/large-echo-config-web.xml +++ b/jetty-websocket/websocket-javax-tests/src/test/resources/basic-echo-endpoint-config-web.xml @@ -7,6 +7,6 @@ version="3.0"> - org.eclipse.jetty.websocket.javax.tests.server.LargeContainerTest$LargeEchoContextListener + com.acme.websocket.BasicEchoEndpointConfigContextListener \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/larger.png b/jetty-websocket/websocket-javax-tests/src/test/resources/data/larger.png similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/larger.png rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/larger.png diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/larger.png.sha b/jetty-websocket/websocket-javax-tests/src/test/resources/data/larger.png.sha similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/larger.png.sha rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/larger.png.sha diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/largest.jpg b/jetty-websocket/websocket-javax-tests/src/test/resources/data/largest.jpg similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/largest.jpg rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/largest.jpg diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/largest.jpg.sha b/jetty-websocket/websocket-javax-tests/src/test/resources/data/largest.jpg.sha similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/largest.jpg.sha rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/largest.jpg.sha diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/medium.png b/jetty-websocket/websocket-javax-tests/src/test/resources/data/medium.png similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/medium.png rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/medium.png diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/medium.png.sha b/jetty-websocket/websocket-javax-tests/src/test/resources/data/medium.png.sha similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/medium.png.sha rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/medium.png.sha diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/small.png b/jetty-websocket/websocket-javax-tests/src/test/resources/data/small.png similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/small.png rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/small.png diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/data/small.png.sha b/jetty-websocket/websocket-javax-tests/src/test/resources/data/small.png.sha similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/data/small.png.sha rename to jetty-websocket/websocket-javax-tests/src/test/resources/data/small.png.sha diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/empty-web.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/empty-web.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/empty-web.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/empty-web.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/idle-timeout-config-web.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/idle-timeout-config-web.xml similarity index 75% rename from jetty-websocket/javax-websocket-tests/src/test/resources/idle-timeout-config-web.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/idle-timeout-config-web.xml index ecb89d2acd2..a60cea6c700 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/resources/idle-timeout-config-web.xml +++ b/jetty-websocket/websocket-javax-tests/src/test/resources/idle-timeout-config-web.xml @@ -7,6 +7,6 @@ version="3.0"> - org.eclipse.jetty.websocket.javax.tests.server.IdleTimeoutContextListener + com.acme.websocket.IdleTimeoutContextListener \ No newline at end of file diff --git a/jetty-websocket/websocket-javax-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-javax-tests/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..7485b6d2a83 --- /dev/null +++ b/jetty-websocket/websocket-javax-tests/src/test/resources/jetty-logging.properties @@ -0,0 +1,15 @@ +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG +# org.eclipse.jetty.util.log.stderr.LONG=true +# org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG +# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG +# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG +# org.eclipse.jetty.client.LEVEL=DEBUG +# org.eclipse.jetty.io.LEVEL=DEBUG +# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO +# org.eclipse.jetty.websocket.LEVEL=DEBUG +# org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.LEVEL=DEBUG +# org.eclipse.jetty.websocket.LEVEL=INFO +# org.eclipse.jetty.websocket.tests.LEVEL=DEBUG +# org.eclipse.jetty.websocket.tests.client.LEVEL=DEBUG +# org.eclipse.jetty.websocket.tests.server.LEVEL=DEBUG diff --git a/jetty-websocket/websocket-javax-tests/src/test/resources/keystore.p12 b/jetty-websocket/websocket-javax-tests/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..33d32ed933e Binary files /dev/null and b/jetty-websocket/websocket-javax-tests/src/test/resources/keystore.p12 differ diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/basic-echo-endpoint-config-web.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/large-echo-config-web.xml similarity index 73% rename from jetty-websocket/javax-websocket-tests/src/test/resources/basic-echo-endpoint-config-web.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/large-echo-config-web.xml index 2daa96edb6c..b032926b059 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/resources/basic-echo-endpoint-config-web.xml +++ b/jetty-websocket/websocket-javax-tests/src/test/resources/large-echo-config-web.xml @@ -7,6 +7,6 @@ version="3.0"> - org.eclipse.jetty.websocket.javax.tests.server.EndpointViaConfigTest$BasicEchoEndpointConfigContextListener + com.acme.websocket.LargeEchoContextListener \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/logback-test.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/logback-test.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/logback-test.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/logback-test.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/pong-config-web.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/pong-config-web.xml similarity index 74% rename from jetty-websocket/javax-websocket-tests/src/test/resources/pong-config-web.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/pong-config-web.xml index aa16c7af156..a3478e35e2a 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/resources/pong-config-web.xml +++ b/jetty-websocket/websocket-javax-tests/src/test/resources/pong-config-web.xml @@ -7,6 +7,6 @@ version="3.0"> - org.eclipse.jetty.websocket.javax.tests.server.PingPongTest$PongContextListener + com.acme.websocket.PongContextListener \ No newline at end of file diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/quotes-ben.txt b/jetty-websocket/websocket-javax-tests/src/test/resources/quotes-ben.txt similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/quotes-ben.txt rename to jetty-websocket/websocket-javax-tests/src/test/resources/quotes-ben.txt diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/quotes-twain.txt b/jetty-websocket/websocket-javax-tests/src/test/resources/quotes-twain.txt similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/quotes-twain.txt rename to jetty-websocket/websocket-javax-tests/src/test/resources/quotes-twain.txt diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/simple/jetty-websocket-httpclient.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/simple/jetty-websocket-httpclient.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/simple/jetty-websocket-httpclient.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/simple/jetty-websocket-httpclient.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/wsuf-alt-config-via-listener.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/wsuf-alt-config-via-listener.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/wsuf-alt-config-via-listener.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/wsuf-alt-config-via-listener.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/wsuf-config-via-listener.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/wsuf-config-via-listener.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/wsuf-config-via-listener.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/wsuf-config-via-listener.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/wsuf-config-via-servlet-init.xml b/jetty-websocket/websocket-javax-tests/src/test/resources/wsuf-config-via-servlet-init.xml similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/resources/wsuf-config-via-servlet-init.xml rename to jetty-websocket/websocket-javax-tests/src/test/resources/wsuf-config-via-servlet-init.xml diff --git a/jetty-websocket/javax-websocket-tests/src/test/webapp/index.html b/jetty-websocket/websocket-javax-tests/src/test/webapp/index.html similarity index 100% rename from jetty-websocket/javax-websocket-tests/src/test/webapp/index.html rename to jetty-websocket/websocket-javax-tests/src/test/webapp/index.html diff --git a/jetty-websocket/jetty-websocket-api/pom.xml b/jetty-websocket/websocket-jetty-api/pom.xml similarity index 97% rename from jetty-websocket/jetty-websocket-api/pom.xml rename to jetty-websocket/websocket-jetty-api/pom.xml index a2486c5739b..5f7a34e1f77 100644 --- a/jetty-websocket/jetty-websocket-api/pom.xml +++ b/jetty-websocket/websocket-jetty-api/pom.xml @@ -7,7 +7,7 @@ 4.0.0 - jetty-websocket-api + websocket-jetty-api Jetty :: Websocket :: org.eclipse.jetty.websocket :: API diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/module-info.java b/jetty-websocket/websocket-jetty-api/src/main/java/module-info.java new file mode 100644 index 00000000000..9bd0d472ca8 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/module-info.java @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +module org.eclipse.jetty.websocket.jetty.api +{ + exports org.eclipse.jetty.websocket.api; + exports org.eclipse.jetty.websocket.api.annotations; + exports org.eclipse.jetty.websocket.api.extensions; + exports org.eclipse.jetty.websocket.api.util; + + uses org.eclipse.jetty.websocket.api.extensions.ExtensionConfig.Parser; +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java new file mode 100644 index 00000000000..444c0c87188 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/BadPayloadException.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Exception to terminate the connection because it has received data within a frame payload that was not consistent with the requirements of that frame + * payload. (eg: not UTF-8 in a text frame, or a unexpected data seen by an extension) + * + * @see StatusCode#BAD_PAYLOAD + */ +@SuppressWarnings("serial") +public class BadPayloadException extends CloseException +{ + public BadPayloadException(String message) + { + super(StatusCode.BAD_PAYLOAD, message); + } + + public BadPayloadException(String message, Throwable t) + { + super(StatusCode.BAD_PAYLOAD, message, t); + } + + public BadPayloadException(Throwable t) + { + super(StatusCode.BAD_PAYLOAD, t); + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/BatchMode.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/BatchMode.java new file mode 100644 index 00000000000..783c94f86cc --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/BatchMode.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * The possible batch modes when enqueuing outgoing frames. + */ +public enum BatchMode +{ + /** + * Implementers are free to decide whether to send or not frames + * to the network layer. + */ + AUTO, + + /** + * Implementers must batch frames. + */ + ON, + + /** + * Implementers must send frames to the network layer. + */ + OFF; + + public static BatchMode max(BatchMode one, BatchMode two) + { + // Return the BatchMode that has the higher priority, where AUTO < ON < OFF. + return one.ordinal() < two.ordinal() ? two : one; + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java new file mode 100644 index 00000000000..0e9e1c79633 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/CloseException.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +@SuppressWarnings("serial") +public class CloseException extends WebSocketException +{ + private int statusCode; + + public CloseException(int closeCode, String message) + { + super(message); + this.statusCode = closeCode; + } + + public CloseException(int closeCode, String message, Throwable cause) + { + super(message, cause); + this.statusCode = closeCode; + } + + public CloseException(int closeCode, Throwable cause) + { + super(cause); + this.statusCode = closeCode; + } + + public int getStatusCode() + { + return statusCode; + } +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseStatus.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/CloseStatus.java similarity index 54% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseStatus.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/CloseStatus.java index 5e77c6c8f18..015cd6f81bc 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/CloseStatus.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/CloseStatus.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Frame.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/Frame.java similarity index 69% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Frame.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/Frame.java index eaf32c64a13..c548759eef9 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Frame.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/Frame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java new file mode 100644 index 00000000000..2cd01a8d30e --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/InvalidWebSocketException.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +/** + * Indicating that the provided Class is not a valid WebSocket as defined by the API. + *

      + * A valid WebSocket should do one of the following: + *

        + *
      • Implement {@link WebSocketListener}
      • + *
      • Extend {@link WebSocketAdapter}
      • + *
      • Declare the {@link WebSocket @WebSocket} annotation on the type
      • + *
      + */ +@SuppressWarnings("serial") +public class InvalidWebSocketException extends WebSocketException +{ + public InvalidWebSocketException(String message) + { + super(message); + } + + public InvalidWebSocketException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java new file mode 100644 index 00000000000..166ae51d169 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/MessageTooLargeException.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Exception when a message is too large for the internal buffers occurs and should trigger a connection close. + * + * @see StatusCode#MESSAGE_TOO_LARGE + */ +@SuppressWarnings("serial") +public class MessageTooLargeException extends CloseException +{ + public MessageTooLargeException(String message) + { + super(StatusCode.MESSAGE_TOO_LARGE, message); + } + + public MessageTooLargeException(String message, Throwable t) + { + super(StatusCode.MESSAGE_TOO_LARGE, message, t); + } + + public MessageTooLargeException(Throwable t) + { + super(StatusCode.MESSAGE_TOO_LARGE, t); + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java new file mode 100644 index 00000000000..44c6663da8d --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/PolicyViolationException.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Exception when a violation of policy occurs and should trigger a connection close. + * + * @see StatusCode#POLICY_VIOLATION + */ +@SuppressWarnings("serial") +public class PolicyViolationException extends CloseException +{ + public PolicyViolationException(String message) + { + super(StatusCode.POLICY_VIOLATION, message); + } + + public PolicyViolationException(String message, Throwable t) + { + super(StatusCode.POLICY_VIOLATION, message, t); + } + + public PolicyViolationException(Throwable t) + { + super(StatusCode.POLICY_VIOLATION, t); + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java new file mode 100644 index 00000000000..0ac3721c95d --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/ProtocolException.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Per spec, a protocol error should result in a Close frame of status code 1002 (PROTOCOL_ERROR) + */ +@SuppressWarnings("serial") +public class ProtocolException extends CloseException +{ + public ProtocolException(String message) + { + super(StatusCode.PROTOCOL, message); + } + + public ProtocolException(String message, Throwable t) + { + super(StatusCode.PROTOCOL, message, t); + } + + public ProtocolException(Throwable t) + { + super(StatusCode.PROTOCOL, t); + } +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java similarity index 89% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java index a6d081b0e45..2fc3de74f46 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/RemoteEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java similarity index 86% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java index 76c0c86f481..f8e3ed02888 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java similarity index 91% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java index 1e371d1f407..3b1e1cae8da 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/StatusCode.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java new file mode 100644 index 00000000000..475eebd3744 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/SuspendToken.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Connection suspend token + */ +public interface SuspendToken +{ + /** + * Resume a previously suspended connection. + */ + void resume(); +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java similarity index 61% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java index 65df1fe8404..bdcc7d9e655 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeException.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java similarity index 82% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java index 1767a751d4f..9db3f0a81f3 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; @@ -255,34 +255,6 @@ public interface UpgradeRequest */ void setHeaders(Map> headers); - /** - * Set the HTTP Version to use. - *

      - * As of RFC6455 (December 2011) this should always be - * {@code HTTP/1.1} - * - * @param httpVersion the HTTP version to use. - */ - void setHttpVersion(String httpVersion); - - /** - * Set the HTTP method to use. - *

      - * As of RFC6455 (December 2011) this is always {@code GET} - * - * @param method the HTTP method to use. - */ - void setMethod(String method); - - /** - * Set the Request URI to use for this request. - *

      - * Must be an absolute URI with scheme {@code 'ws'} or {@code 'wss'} - * - * @param uri the Request URI - */ - void setRequestURI(URI uri); - /** * Set the Session associated with this request. *

      diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java similarity index 80% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java index 34dc2400d25..922f3764edc 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java similarity index 62% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java index 1211ce140c0..6a0e5ded87f 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java new file mode 100644 index 00000000000..7029ee1b7d6 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketBehavior.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Behavior for how the WebSocket should operate. + *

      + * This dictated by the RFC 6455 spec in various places, where certain behavior must be performed depending on + * operation as a CLIENT vs a SERVER + */ +public enum WebSocketBehavior +{ + CLIENT, + SERVER +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnectionListener.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnectionListener.java similarity index 63% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnectionListener.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnectionListener.java index 7c86344a998..7dac7419859 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnectionListener.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConnectionListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConstants.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConstants.java new file mode 100644 index 00000000000..24bddbcc990 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketConstants.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +public final class WebSocketConstants +{ + public static final String SEC_WEBSOCKET_EXTENSIONS = "Sec-WebSocket-Extensions"; + public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol"; + public static final String SEC_WEBSOCKET_VERSION = "Sec-WebSocket-Version"; + public static final String SEC_WEBSOCKET_ACCEPT = "Sec-WebSocket-Accept"; + public static final String SEC_WEBSOCKET_ORIGIN = "Sec-WebSocket-Origin"; + public static final String SEC_WEBSOCKET_KEY = "Sec-WebSocket-Key"; + public static final int SPEC_VERSION = 13; +} + diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketContainer.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketContainer.java similarity index 55% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketContainer.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketContainer.java index f0b027e6b76..0c32ce6b5f8 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketContainer.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketContainer.java @@ -1,30 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.common; +package org.eclipse.jetty.websocket.api; import java.util.Collection; import java.util.concurrent.Executor; import java.util.function.Consumer; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketSessionListener; - /** * Generic interface to the Container (server or client) */ diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java new file mode 100644 index 00000000000..3dd7eed0aa7 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketException.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * A recoverable exception within the websocket framework. + */ +@SuppressWarnings("serial") +public class WebSocketException extends RuntimeException +{ + public WebSocketException() + { + super(); + } + + public WebSocketException(String message) + { + super(message); + } + + public WebSocketException(String message, Throwable cause) + { + super(message, cause); + } + + public WebSocketException(Throwable cause) + { + super(cause); + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketFrameListener.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketFrameListener.java new file mode 100644 index 00000000000..a7b9f204c8f --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketFrameListener.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * WebSocket Frame Listener interface for incoming WebSocket frames. + */ +public interface WebSocketFrameListener extends WebSocketConnectionListener +{ + /** + * A WebSocket frame has been received. + * + * @param frame the immutable frame received + */ + void onWebSocketFrame(Frame frame); +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java new file mode 100644 index 00000000000..8f11b97c375 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketListener.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Basic WebSocket Listener interface for incoming WebSocket message events. + */ +public interface WebSocketListener extends WebSocketConnectionListener +{ + /** + * A WebSocket binary frame has been received. + * + * @param payload the raw payload array received + * @param offset the offset in the payload array where the data starts + * @param len the length of bytes in the payload + */ + void onWebSocketBinary(byte[] payload, int offset, int len); + + /** + * A WebSocket Text frame was received. + * + * @param message the message + */ + void onWebSocketText(String message); +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPartialListener.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPartialListener.java similarity index 67% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPartialListener.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPartialListener.java index 4852a9bd479..26b4cc0a830 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPartialListener.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPartialListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPingPongListener.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPingPongListener.java new file mode 100644 index 00000000000..dde0f7fb0ea --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPingPongListener.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +import java.nio.ByteBuffer; + +/** + * WebSocket PING/PONG Listener interface for incoming WebSocket PING/PONG frames. + */ +public interface WebSocketPingPongListener extends WebSocketConnectionListener +{ + /** + * A WebSocket PING has been received. + * + * @param payload the ping payload + */ + void onWebSocketPing(ByteBuffer payload); + + /** + * A WebSocket PONG has been received. + * + * @param payload the pong payload + */ + void onWebSocketPong(ByteBuffer payload); +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java similarity index 65% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java index 8b089fdbcba..08d9f7bfadc 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; @@ -84,6 +84,20 @@ public interface WebSocketPolicy */ long getMaxTextMessageSize(); + /** + * The maximum payload size of any WebSocket Frame which can be received. + * + * @return the maximum size of a WebSocket Frame. + */ + long getMaxFrameSize(); + + /** + * If true, frames are automatically fragmented to respect the maximum frame size. + * + * @return whether to automatically fragment incoming WebSocket Frames. + */ + boolean isAutoFragment(); + /** * The duration that a websocket may be idle before being closed by the implementation * @@ -123,4 +137,21 @@ public interface WebSocketPolicy * @param size the maximum allowed size of a text message. */ void setMaxTextMessageSize(long size); + + /** + * The maximum payload size of any WebSocket Frame which can be received. + *

      + * WebSocket Frames over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE} + *

      + * + * @param maxFrameSize the maximum allowed size of a WebSocket Frame. + */ + void setMaxFrameSize(long maxFrameSize); + + /** + * If set to true, frames are automatically fragmented to respect the maximum frame size. + * + * @param autoFragment whether to automatically fragment incoming WebSocket Frames. + */ + void setAutoFragment(boolean autoFragment); } diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketSessionListener.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketSessionListener.java new file mode 100644 index 00000000000..22d13152b77 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketSessionListener.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Interface for Listeners that are interested in knowing about the Session history. + */ +public interface WebSocketSessionListener +{ + default void onWebSocketSessionOpened(Session session) + { + } + + default void onWebSocketSessionClosed(Session session) + { + } +} diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketTimeoutException.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketTimeoutException.java new file mode 100644 index 00000000000..1c859b8c9c2 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketTimeoutException.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api; + +/** + * Exception thrown to indicate a connection I/O timeout. + */ +public class WebSocketTimeoutException extends WebSocketException +{ + private static final long serialVersionUID = -6145098200250676673L; + + public WebSocketTimeoutException(String message) + { + super(message); + } + + public WebSocketTimeoutException(String message, Throwable cause) + { + super(message, cause); + } + + public WebSocketTimeoutException(Throwable cause) + { + super(cause); + } +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WriteCallback.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WriteCallback.java similarity index 52% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WriteCallback.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WriteCallback.java index 97ae6ac513c..45385e38cef 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WriteCallback.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/WriteCallback.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java similarity index 52% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java index 4399c2bac20..a728a2c24c6 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketClose.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.annotations; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java new file mode 100644 index 00000000000..a20d96123dc --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketConnect.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.api.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.eclipse.jetty.websocket.api.Session; + +/** + * Annotation for tagging methods to receive connection open events. + *

      + * Only 1 acceptable method pattern for this annotation.
      + * Note: {@code methodName} can be any name you want to use. + *

        + *
      1. public void methodName({@link Session} session)
      2. + *
      + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(value = + {ElementType.METHOD}) +public @interface OnWebSocketConnect +{ + /* no config */ +} diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java similarity index 53% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java index b626526b2cb..6672b2eb46f 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketError.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.annotations; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java similarity index 52% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java index 1b87c94027e..0c35226397d 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.annotations; diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java similarity index 65% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java index 00483883708..acbee3fbd3b 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/OnWebSocketMessage.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.annotations; @@ -45,6 +45,8 @@ import org.eclipse.jetty.websocket.api.Session; *

      * Binary Message Versions *

        + *
      1. {@code public void methodName(ByteBuffer message)}
      2. + *
      3. public void methodName({@link Session} session, ByteBuffer message)
      4. *
      5. {@code public void methodName(byte buf[], int offset, int length)}
      6. *
      7. public void methodName({@link Session} session, byte buf[], int offset, int length)
      8. *
      9. {@code public void methodName(InputStream stream)}
      10. diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java similarity index 65% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java index 05393a9aa67..a142f8a2c47 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/WebSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.annotations; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/package-info.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/package-info.java new file mode 100644 index 00000000000..8f1505c4e4f --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/annotations/package-info.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty WebSocket API : WebSocket POJO Annotations + */ +package org.eclipse.jetty.websocket.api.annotations; + diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java similarity index 58% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java index b13d5e70ac7..5902690f280 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/ExtensionConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.extensions; @@ -34,7 +34,7 @@ public interface ExtensionConfig private static ExtensionConfig.Parser getParser() { - return ServiceLoader.load(ExtensionConfig.Parser.class).findFirst().get(); + return ServiceLoader.load(ExtensionConfig.Parser.class).iterator().next(); } static ExtensionConfig parse(String parameterizedName) diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/package-info.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/package-info.java new file mode 100644 index 00000000000..9ab270f0695 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/extensions/package-info.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty WebSocket API : WebSocket Extension API + */ +package org.eclipse.jetty.websocket.api.extensions; + diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/package-info.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/package-info.java new file mode 100644 index 00000000000..4071afae7ff --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/package-info.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty WebSocket API + */ +package org.eclipse.jetty.websocket.api; + diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/WSURI.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/util/WSURI.java similarity index 83% rename from jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/WSURI.java rename to jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/util/WSURI.java index 7838363a3ae..412296b7672 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/util/WSURI.java +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/util/WSURI.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.api.util; diff --git a/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/util/package-info.java b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/util/package-info.java new file mode 100644 index 00000000000..5296a201c65 --- /dev/null +++ b/jetty-websocket/websocket-jetty-api/src/main/java/org/eclipse/jetty/websocket/api/util/package-info.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty WebSocket API : Utility Classes + */ +package org.eclipse.jetty.websocket.api.util; + diff --git a/jetty-websocket/jetty-websocket-client/pom.xml b/jetty-websocket/websocket-jetty-client/pom.xml similarity index 85% rename from jetty-websocket/jetty-websocket-client/pom.xml rename to jetty-websocket/websocket-jetty-client/pom.xml index caeae04bc80..ad9d334d39f 100644 --- a/jetty-websocket/jetty-websocket-client/pom.xml +++ b/jetty-websocket/websocket-jetty-client/pom.xml @@ -7,22 +7,22 @@ 4.0.0 - jetty-websocket-client + websocket-jetty-client Jetty :: Websocket :: org.eclipse.jetty.websocket :: Client - ${project.groupId}.client.api + ${project.groupId}.client org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api ${project.version} org.eclipse.jetty.websocket - jetty-websocket-common + websocket-jetty-common ${project.version} @@ -30,10 +30,13 @@ jetty-client ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty - jetty-server - ${project.version} + jetty-slf4j-impl test diff --git a/jetty-websocket/websocket-jetty-client/src/main/java/module-info.java b/jetty-websocket/websocket-jetty-client/src/main/java/module-info.java new file mode 100644 index 00000000000..aa113d80a62 --- /dev/null +++ b/jetty-websocket/websocket-jetty-client/src/main/java/module-info.java @@ -0,0 +1,28 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +module org.eclipse.jetty.websocket.jetty.client +{ + exports org.eclipse.jetty.websocket.client; + + requires transitive org.eclipse.jetty.client; + requires transitive org.eclipse.jetty.websocket.jetty.api; + requires org.eclipse.jetty.websocket.core; + requires org.eclipse.jetty.websocket.jetty.common; + requires org.slf4j; +} diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java similarity index 85% rename from jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java rename to jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java index 14cb4a8e9b0..edd4695ac76 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client; @@ -26,9 +26,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; @@ -46,7 +48,6 @@ public final class ClientUpgradeRequest implements UpgradeRequest private String httpVersion; private String method; private String host; - private boolean secure; public ClientUpgradeRequest() { @@ -57,12 +58,9 @@ public final class ClientUpgradeRequest implements UpgradeRequest { this.requestURI = uri; String scheme = uri.getScheme(); - if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) - { + if (!HttpScheme.WS.is(scheme) || !HttpScheme.WSS.is(scheme)) throw new IllegalArgumentException("URI scheme must be 'ws' or 'wss'"); - } this.host = this.requestURI.getHost(); - this.parameters.clear(); } @Override @@ -193,11 +191,7 @@ public final class ClientUpgradeRequest implements UpgradeRequest public String getProtocolVersion() { String version = getHeader("Sec-WebSocket-Version"); - if (version == null) - { - return "13"; // Default - } - return version; + return Objects.requireNonNullElse(version, "13"); } @Override @@ -288,8 +282,7 @@ public final class ClientUpgradeRequest implements UpgradeRequest @Override public void setHeaders(Map> headers) { - headers.clear(); - + this.headers.clear(); for (Map.Entry> entry : headers.entrySet()) { String name = entry.getKey(); @@ -298,24 +291,6 @@ public final class ClientUpgradeRequest implements UpgradeRequest } } - @Override - public void setHttpVersion(String httpVersion) - { - this.httpVersion = httpVersion; - } - - @Override - public void setMethod(String method) - { - this.method = method; - } - - @Override - public void setRequestURI(URI uri) - { - this.requestURI = uri; - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/JettyUpgradeListener.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/JettyUpgradeListener.java new file mode 100644 index 00000000000..59f30d97e50 --- /dev/null +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/JettyUpgradeListener.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.client; + +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; + +public interface JettyUpgradeListener +{ + /** + * Event that triggers before the Handshake request is sent. + * + * @param request the request + */ + default void onHandshakeRequest(HttpRequest request) + { + } + + /** + * Event that triggers after the Handshake response has been received. + * + * @param request the request that was used + * @param response the response that was received + */ + default void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + } +} diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java similarity index 78% rename from jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java rename to jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index f159c34fbb4..56f74cc4529 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client; @@ -38,34 +38,36 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.ShutdownThread; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.WebSocketBehavior; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.WebSocketSessionListener; import org.eclipse.jetty.websocket.client.impl.JettyClientUpgradeRequest; import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler; import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory; import org.eclipse.jetty.websocket.common.SessionTracker; -import org.eclipse.jetty.websocket.common.WebSocketContainer; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.client.UpgradeListener; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WebSocketClient extends ContainerLifeCycle implements WebSocketPolicy, WebSocketContainer { - private static final Logger LOG = Log.getLogger(WebSocketClient.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketClient.class); private final WebSocketCoreClient coreClient; private final int id = ThreadLocalRandom.current().nextInt(); private final JettyWebSocketFrameHandlerFactory frameHandlerFactory; private final List sessionListeners = new CopyOnWriteArrayList<>(); private final SessionTracker sessionTracker = new SessionTracker(); - private final FrameHandler.ConfigurationCustomizer configurationCustomizer = new FrameHandler.ConfigurationCustomizer(); - private WebSocketComponents components = new WebSocketComponents(); + private final Configuration.ConfigurationCustomizer configurationCustomizer = new Configuration.ConfigurationCustomizer(); + private final WebSocketComponents components = new WebSocketComponents(); + private boolean stopAtShutdown = false; /** * Instantiate a WebSocketClient with defaults @@ -129,7 +131,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketPoli coreClient.addBean(listener); } - JettyClientUpgradeRequest upgradeRequest = new JettyClientUpgradeRequest(this, coreClient, request, toUri, websocket); + JettyClientUpgradeRequest upgradeRequest = new JettyClientUpgradeRequest(coreClient, request, toUri, frameHandlerFactory, websocket); if (upgradeListener != null) { upgradeRequest.addListener(new UpgradeListener() @@ -235,10 +237,23 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketPoli return configurationCustomizer.getMaxTextMessageSize(); } + @Override + public long getMaxFrameSize() + { + return configurationCustomizer.getMaxFrameSize(); + } + + @Override + public boolean isAutoFragment() + { + return configurationCustomizer.isAutoFragment(); + } + @Override public void setIdleTimeout(Duration duration) { configurationCustomizer.setIdleTimeout(duration); + getHttpClient().setIdleTimeout(duration.toMillis()); } @Override @@ -265,6 +280,18 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketPoli configurationCustomizer.setMaxTextMessageSize(size); } + @Override + public void setMaxFrameSize(long maxFrameSize) + { + configurationCustomizer.setMaxFrameSize(maxFrameSize); + } + + @Override + public void setAutoFragment(boolean autoFragment) + { + configurationCustomizer.setAutoFragment(autoFragment); + } + public SocketAddress getBindAddress() { return getHttpClient().getBindAddress(); @@ -326,11 +353,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketPoli return sessionTracker.getSessions(); } - public JettyWebSocketFrameHandler newFrameHandler(Object websocketPojo) - { - return frameHandlerFactory.newJettyFrameHandler(websocketPojo); - } - /** * @return the {@link SslContextFactory} that manages TLS encryption */ @@ -339,6 +361,31 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketPoli return getHttpClient().getSslContextFactory(); } + /** + * Set JVM shutdown behavior. + * @param stop If true, this client instance will be explicitly stopped when the + * JVM is shutdown. Otherwise the application is responsible for maintaining the WebSocketClient lifecycle. + * @see Runtime#addShutdownHook(Thread) + * @see ShutdownThread + */ + public synchronized void setStopAtShutdown(boolean stop) + { + if (stop) + { + if (!stopAtShutdown && !ShutdownThread.isRegistered(this)) + ShutdownThread.register(this); + } + else + ShutdownThread.deregister(this); + + stopAtShutdown = stop; + } + + public boolean isStopAtShutdown() + { + return stopAtShutdown; + } + @Override public String toString() { diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java similarity index 84% rename from jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java rename to jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java index 88516af8589..bdd1a38227d 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client.impl; @@ -231,24 +231,6 @@ public class DelegatedJettyClientUpgradeRequest implements UpgradeRequest // TODO } - @Override - public void setHttpVersion(String httpVersion) - { - // TODO - } - - @Override - public void setMethod(String method) - { - - } - - @Override - public void setRequestURI(URI uri) - { - // TODO - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java similarity index 76% rename from jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java rename to jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java index 79c385491fd..67cad5ee72d 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client.impl; diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java similarity index 62% rename from jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java rename to jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java index 3083d5c789a..85ab93c0851 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client.impl; @@ -24,14 +24,13 @@ import java.util.List; import java.util.stream.Collectors; import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.websocket.api.UpgradeRequest; -import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler; +import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; @@ -39,21 +38,19 @@ import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; public class JettyClientUpgradeRequest extends ClientUpgradeRequest { - private final WebSocketClient containerContext; private final DelegatedJettyClientUpgradeRequest handshakeRequest; private final JettyWebSocketFrameHandler frameHandler; - public JettyClientUpgradeRequest(WebSocketClient clientContainer, WebSocketCoreClient coreClient, UpgradeRequest request, - URI requestURI, Object websocketPojo) + public JettyClientUpgradeRequest(WebSocketCoreClient coreClient, UpgradeRequest request, URI requestURI, JettyWebSocketFrameHandlerFactory frameHandlerFactory, + Object websocketPojo) { super(coreClient, requestURI); - this.containerContext = clientContainer; if (request != null) { // Copy request details into actual request HttpFields fields = getHeaders(); - request.getHeaders().forEach((name, values) -> fields.put(name, values)); + request.getHeaders().forEach(fields::put); // Copy manually created Cookies into place List cookies = request.getCookies(); @@ -85,22 +82,22 @@ public class JettyClientUpgradeRequest extends ClientUpgradeRequest } handshakeRequest = new DelegatedJettyClientUpgradeRequest(this); - frameHandler = containerContext.newFrameHandler(websocketPojo); + frameHandler = frameHandlerFactory.newJettyFrameHandler(websocketPojo); } @Override - protected void customize(EndPoint endp) + protected void customize(EndPoint endPoint) { - super.customize(endp); - handshakeRequest.configure(endp); + super.customize(endPoint); + handshakeRequest.configure(endPoint); } @Override - public void upgrade(HttpResponse response, HttpConnectionOverHTTP httpConnection) + public void upgrade(HttpResponse response, EndPoint endPoint) { frameHandler.setUpgradeRequest(new DelegatedJettyClientUpgradeRequest(this)); frameHandler.setUpgradeResponse(new DelegatedJettyClientUpgradeResponse(response)); - super.upgrade(response, httpConnection); + super.upgrade(response, endPoint); } @Override diff --git a/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/package-info.java b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/package-info.java new file mode 100644 index 00000000000..4c3a3748cd1 --- /dev/null +++ b/jetty-websocket/websocket-jetty-client/src/main/java/org/eclipse/jetty/websocket/client/package-info.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty WebSocket API :: Client + */ +package org.eclipse.jetty.websocket.client; + diff --git a/jetty-websocket/jetty-websocket-client/src/test/java/examples/ClientDemo.java b/jetty-websocket/websocket-jetty-client/src/test/java/examples/ClientDemo.java similarity index 89% rename from jetty-websocket/jetty-websocket-client/src/test/java/examples/ClientDemo.java rename to jetty-websocket/websocket-jetty-client/src/test/java/examples/ClientDemo.java index 1d236ba543d..1d6f333d24e 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/java/examples/ClientDemo.java +++ b/jetty-websocket/websocket-jetty-client/src/test/java/examples/ClientDemo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package examples; @@ -247,10 +247,10 @@ public class ClientDemo long duration = System.currentTimeMillis() - start; System.out.println("--- " + host + " websocket ping statistics using " + clients + " connection" + (clients > 1 ? "s" : "") + " ---"); System.out.printf("%d/%d frames sent/recv, %d/%d mesg sent/recv, time %dms %dm/s %.2fbps%n", framesSent, framesReceived.get(), messagesSent, - messagesReceived.get(), duration, ((1000L * messagesReceived.get()) / duration), (1000.0D * messagesReceived.get() * 8 * size) - / duration / 1024 / 1024); - System.out.printf("rtt min/ave/max = %.3f/%.3f/%.3f ms\n", minDuration.get() / 1000000.0, messagesReceived.get() == 0 ? 0.0 : (totalTime.get() - / messagesReceived.get() / 1000000.0), maxDuration.get() / 1000000.0); + messagesReceived.get(), duration, ((1000L * messagesReceived.get()) / duration), + (1000.0D * messagesReceived.get() * 8 * size) / duration / 1024 / 1024); + System.out.printf("rtt min/ave/max = %.3f/%.3f/%.3f ms\n", minDuration.get() / 1000000.0, + messagesReceived.get() == 0 ? 0.0 : (totalTime.get() / messagesReceived.get() / 1000000.0), maxDuration.get() / 1000000.0); wsclient.stop(); } diff --git a/jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoClient.java b/jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoClient.java similarity index 62% rename from jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoClient.java rename to jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoClient.java index d0d4afcd633..4d64f36cd40 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoClient.java +++ b/jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoClient.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package examples; diff --git a/jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoSocket.java b/jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoSocket.java similarity index 69% rename from jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoSocket.java rename to jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoSocket.java index 9dadc694c9c..ea61cae20c7 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/java/examples/SimpleEchoSocket.java +++ b/jetty-websocket/websocket-jetty-client/src/test/java/examples/SimpleEchoSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package examples; diff --git a/jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/HttpClientInitTest.java b/jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/HttpClientInitTest.java similarity index 77% rename from jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/HttpClientInitTest.java rename to jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/HttpClientInitTest.java index 9dfef772217..abc18c27793 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/HttpClientInitTest.java +++ b/jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/HttpClientInitTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client; diff --git a/jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java b/jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java similarity index 78% rename from jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java rename to jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java index 797ae896534..ed45bb4ab19 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java +++ b/jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client; diff --git a/jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientInitTest.java b/jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientInitTest.java similarity index 75% rename from jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientInitTest.java rename to jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientInitTest.java index 9c89ada16e7..b79c45935c0 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientInitTest.java +++ b/jetty-websocket/websocket-jetty-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientInitTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.client; @@ -39,7 +39,7 @@ public class WebSocketClientInitTest * @throws Exception on test failure */ @Test - public void testInit_HttpClient_StartedOutside() throws Exception + public void testInitHttpClientStartedOutside() throws Exception { HttpClient http = new HttpClient(); http.start(); @@ -56,7 +56,6 @@ public class WebSocketClientInitTest assertThat("HttpClient started", http.isStarted(), is(true)); HttpClient httpBean = ws.getBean(HttpClient.class); - assertThat("HttpClient should not be found in WebSocketClient", httpBean, nullValue()); assertThat("HttpClient bean is managed", ws.isManaged(httpBean), is(false)); assertThat("WebSocketClient should not be found in HttpClient", http.getBean(WebSocketClient.class), nullValue()); } @@ -82,7 +81,7 @@ public class WebSocketClientInitTest * @throws Exception on test failure */ @Test - public void testInit_HttpClient_SyntheticStart() throws Exception + public void testInitHttpClientSyntheticStart() throws Exception { HttpClient http = null; WebSocketClient ws = new WebSocketClient(); diff --git a/jetty-websocket/jetty-websocket-client/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-jetty-client/src/test/resources/jetty-logging.properties similarity index 55% rename from jetty-websocket/jetty-websocket-client/src/test/resources/jetty-logging.properties rename to jetty-websocket/websocket-jetty-client/src/test/resources/jetty-logging.properties index b813365ce20..8816a29ffa1 100644 --- a/jetty-websocket/jetty-websocket-client/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-jetty-client/src/test/resources/jetty-logging.properties @@ -1,5 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN +# Jetty Logging using jetty-slf4j-impl # org.eclipse.jetty.LEVEL=DEBUG # org.eclipse.jetty.io.LEVEL=INFO # org.eclipse.jetty.client.LEVEL=DEBUG @@ -8,11 +7,9 @@ org.eclipse.jetty.LEVEL=WARN # org.eclipse.jetty.websocket.LEVEL=DEBUG # org.eclipse.jetty.websocket.client.LEVEL=DEBUG # org.eclipse.jetty.websocket.client.ClientCloseTest.LEVEL=DEBUG -org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.LEVEL=DEBUG +# org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.io.IOState.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.test.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.Generator.LEVEL=DEBUG -org.eclipse.jetty.websocket.common.Parser.LEVEL=DEBUG -# org.eclipse.jetty.websocket.client.TrackingSocket.LEVEL=DEBUG -### Hide the stacktraces during testing -org.eclipse.jetty.websocket.client.internal.io.UpgradeConnection.STACKS=false +# org.eclipse.jetty.websocket.common.Parser.LEVEL=DEBUG +# org.eclipse.jetty.websocket.client.TrackingSocket.LEVEL=DEBUG \ No newline at end of file diff --git a/jetty-websocket/jetty-websocket-common/pom.xml b/jetty-websocket/websocket-jetty-common/pom.xml similarity index 88% rename from jetty-websocket/jetty-websocket-common/pom.xml rename to jetty-websocket/websocket-jetty-common/pom.xml index bd6c711d235..83c726eb91d 100644 --- a/jetty-websocket/jetty-websocket-common/pom.xml +++ b/jetty-websocket/websocket-jetty-common/pom.xml @@ -7,7 +7,7 @@ 4.0.0 - jetty-websocket-common + websocket-jetty-common Jetty :: Websocket :: org.eclipse.jetty.websocket :: Common @@ -48,7 +48,7 @@ org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api ${project.version} @@ -56,6 +56,11 @@ websocket-core ${project.version} + + org.eclipse.jetty.websocket + websocket-util + ${project.version} + org.eclipse.jetty jetty-util @@ -66,17 +71,13 @@ jetty-io ${project.version} - - org.eclipse.jetty - jetty-client - ${project.version} - test + org.slf4j + slf4j-api org.eclipse.jetty - jetty-server - ${project.version} + jetty-slf4j-impl test diff --git a/jetty-websocket/websocket-jetty-common/src/main/java/module-info.java b/jetty-websocket/websocket-jetty-common/src/main/java/module-info.java new file mode 100644 index 00000000000..3b652531aab --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/main/java/module-info.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; +import org.eclipse.jetty.websocket.common.ExtensionConfigParser; + +module org.eclipse.jetty.websocket.jetty.common +{ + exports org.eclipse.jetty.websocket.common; + + requires transitive org.eclipse.jetty.websocket.core; + requires transitive org.eclipse.jetty.websocket.jetty.api; + requires transitive org.eclipse.jetty.websocket.util; + requires org.slf4j; + + provides ExtensionConfig.Parser with ExtensionConfigParser; +} diff --git a/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/ExtensionConfigParser.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/ExtensionConfigParser.java new file mode 100644 index 00000000000..497174142c5 --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/ExtensionConfigParser.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.common; + +import org.eclipse.jetty.websocket.core.ExtensionConfig; + +public class ExtensionConfigParser implements org.eclipse.jetty.websocket.api.extensions.ExtensionConfig.Parser +{ + /** + * Parse a single parameterized name. + * + * @param parameterizedName the parameterized name + * @return the ExtensionConfig + */ + @Override + public JettyExtensionConfig parse(String parameterizedName) + { + return new JettyExtensionConfig(ExtensionConfig.parse(parameterizedName)); + } +} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyExtensionConfig.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyExtensionConfig.java similarity index 75% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyExtensionConfig.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyExtensionConfig.java index 3a07d11fb8c..44f8e632039 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyExtensionConfig.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyExtensionConfig.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrame.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrame.java similarity index 64% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrame.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrame.java index a1d6ad1aa9f..3aad63570d7 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrame.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrame.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java similarity index 78% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java index 1970d1334e3..96ac6ee8321 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java @@ -1,46 +1,54 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; import java.lang.invoke.MethodHandle; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; -import org.eclipse.jetty.websocket.common.invoke.InvalidSignatureException; -import org.eclipse.jetty.websocket.core.BadPayloadException; -import org.eclipse.jetty.websocket.core.CloseException; +import org.eclipse.jetty.websocket.api.WebSocketContainer; +import org.eclipse.jetty.websocket.api.WriteCallback; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; -import org.eclipse.jetty.websocket.core.MessageTooLargeException; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; -import org.eclipse.jetty.websocket.core.UpgradeException; -import org.eclipse.jetty.websocket.core.WebSocketException; -import org.eclipse.jetty.websocket.core.WebSocketTimeoutException; +import org.eclipse.jetty.websocket.core.exception.BadPayloadException; +import org.eclipse.jetty.websocket.core.exception.CloseException; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.UpgradeException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.messages.MessageSink; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JettyWebSocketFrameHandler implements FrameHandler { @@ -48,13 +56,15 @@ public class JettyWebSocketFrameHandler implements FrameHandler { DEMANDING, SUSPENDING, - SUSPENDED + SUSPENDED, + CLOSED } private final Logger log; private final WebSocketContainer container; private final Object endpointInstance; private final BatchMode batchMode; + private final AtomicBoolean closeNotified = new AtomicBoolean(); private MethodHandle openHandle; private MethodHandle closeHandle; private MethodHandle errorHandle; @@ -68,7 +78,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler private UpgradeRequest upgradeRequest; private UpgradeResponse upgradeResponse; - private final Customizer customizer; + private final Configuration.Customizer customizer; private MessageSink textSink; private MessageSink binarySink; private MessageSink activeMessageSink; @@ -85,9 +95,9 @@ public class JettyWebSocketFrameHandler implements FrameHandler MethodHandle frameHandle, MethodHandle pingHandle, MethodHandle pongHandle, BatchMode batchMode, - Customizer customizer) + Configuration.Customizer customizer) { - this.log = Log.getLogger(endpointInstance.getClass()); + this.log = LoggerFactory.getLogger(endpointInstance.getClass()); this.container = container; this.endpointInstance = endpointInstance; @@ -145,14 +155,14 @@ public class JettyWebSocketFrameHandler implements FrameHandler customizer.customize(coreSession); session = new WebSocketSession(coreSession, this); - frameHandle = JettyWebSocketFrameHandlerFactory.bindTo(frameHandle, session); - openHandle = JettyWebSocketFrameHandlerFactory.bindTo(openHandle, session); - closeHandle = JettyWebSocketFrameHandlerFactory.bindTo(closeHandle, session); - errorHandle = JettyWebSocketFrameHandlerFactory.bindTo(errorHandle, session); - textHandle = JettyWebSocketFrameHandlerFactory.bindTo(textHandle, session); - binaryHandle = JettyWebSocketFrameHandlerFactory.bindTo(binaryHandle, session); - pingHandle = JettyWebSocketFrameHandlerFactory.bindTo(pingHandle, session); - pongHandle = JettyWebSocketFrameHandlerFactory.bindTo(pongHandle, session); + frameHandle = InvokerUtils.bindTo(frameHandle, session); + openHandle = InvokerUtils.bindTo(openHandle, session); + closeHandle = InvokerUtils.bindTo(closeHandle, session); + errorHandle = InvokerUtils.bindTo(errorHandle, session); + textHandle = InvokerUtils.bindTo(textHandle, session); + binaryHandle = InvokerUtils.bindTo(binaryHandle, session); + pingHandle = InvokerUtils.bindTo(pingHandle, session); + pongHandle = InvokerUtils.bindTo(pongHandle, session); Executor executor = container.getExecutor(); @@ -191,7 +201,6 @@ public class JettyWebSocketFrameHandler implements FrameHandler state = SuspendState.SUSPENDED; return; - case SUSPENDED: default: throw new IllegalStateException(); } @@ -277,9 +286,33 @@ public class JettyWebSocketFrameHandler implements FrameHandler } } + private void onCloseFrame(Frame frame, Callback callback) + { + notifyOnClose(CloseStatus.getCloseStatus(frame), callback); + } + @Override public void onClosed(CloseStatus closeStatus, Callback callback) { + synchronized (this) + { + // We are now closed and cannot suspend or resume + state = SuspendState.CLOSED; + } + + notifyOnClose(closeStatus, callback); + container.notifySessionListeners((listener) -> listener.onWebSocketSessionClosed(session)); + } + + private void notifyOnClose(CloseStatus closeStatus, Callback callback) + { + // Make sure onClose is only notified once. + if (!closeNotified.compareAndSet(false, true)) + { + callback.failed(new ClosedChannelException()); + return; + } + try { if (closeHandle != null) @@ -291,8 +324,6 @@ public class JettyWebSocketFrameHandler implements FrameHandler { callback.failed(new WebSocketException(endpointInstance.getClass().getSimpleName() + " CLOSE method error: " + cause.getMessage(), cause)); } - - container.notifySessionListeners((listener) -> listener.onWebSocketSessionClosed(session)); } public String toString() @@ -323,11 +354,6 @@ public class JettyWebSocketFrameHandler implements FrameHandler acceptMessage(frame, callback); } - private void onCloseFrame(Frame frame, Callback callback) - { - callback.succeeded(); - } - private void onContinuationFrame(Frame frame, Callback callback) { acceptMessage(frame, callback); @@ -353,10 +379,8 @@ public class JettyWebSocketFrameHandler implements FrameHandler else { // Automatically respond - Frame pong = new Frame(OpCode.PONG); - if (frame.hasPayload()) - pong.setPayload(frame.getPayload()); - getSession().getRemote().getCoreSession().sendFrame(pong, Callback.NOOP, false); + ByteBuffer payload = BufferUtil.copy(frame.getPayload()); + getSession().getRemote().sendPong(payload, WriteCallback.NOOP); } callback.succeeded(); } @@ -405,18 +429,15 @@ public class JettyWebSocketFrameHandler implements FrameHandler state = SuspendState.SUSPENDING; break; - case SUSPENDED: - case SUSPENDING: - throw new IllegalStateException("Already Suspended"); - default: - throw new IllegalStateException(); + throw new IllegalStateException(state.name()); } } } public void resume() { + boolean needDemand = false; Runnable delayedFrame = null; synchronized (this) { @@ -426,6 +447,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler throw new IllegalStateException("Already Resumed"); case SUSPENDED: + needDemand = true; delayedFrame = delayedOnFrame; delayedOnFrame = null; state = SuspendState.DEMANDING; @@ -438,14 +460,17 @@ public class JettyWebSocketFrameHandler implements FrameHandler break; default: - throw new IllegalStateException(); + throw new IllegalStateException(state.name()); } } - if (delayedFrame != null) - delayedFrame.run(); - else - session.getCoreSession().demand(1); + if (needDemand) + { + if (delayedFrame != null) + delayedFrame.run(); + else + session.getCoreSession().demand(1); + } } private void demand() @@ -459,15 +484,12 @@ public class JettyWebSocketFrameHandler implements FrameHandler demand = true; break; - case SUSPENDED: - throw new IllegalStateException("Suspended"); - case SUSPENDING: state = SuspendState.SUSPENDED; break; default: - throw new IllegalStateException(); + throw new IllegalStateException(state.name()); } } diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerFactory.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerFactory.java similarity index 72% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerFactory.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerFactory.java index c1f0e138acc..13a22ab6d0f 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerFactory.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -24,7 +24,7 @@ import java.io.Reader; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; +import java.lang.invoke.MethodType; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -37,9 +37,9 @@ import java.util.concurrent.Executor; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.Frame; -import org.eclipse.jetty.websocket.api.InvalidWebSocketException; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketConnectionListener; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.api.WebSocketFrameListener; import org.eclipse.jetty.websocket.api.WebSocketListener; import org.eclipse.jetty.websocket.api.WebSocketPartialListener; @@ -50,16 +50,19 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.common.invoke.InvalidSignatureException; -import org.eclipse.jetty.websocket.common.invoke.InvokerUtils; -import org.eclipse.jetty.websocket.common.message.ByteArrayMessageSink; -import org.eclipse.jetty.websocket.common.message.ByteBufferMessageSink; -import org.eclipse.jetty.websocket.common.message.InputStreamMessageSink; -import org.eclipse.jetty.websocket.common.message.PartialBinaryMessageSink; -import org.eclipse.jetty.websocket.common.message.PartialTextMessageSink; -import org.eclipse.jetty.websocket.common.message.ReaderMessageSink; -import org.eclipse.jetty.websocket.common.message.StringMessageSink; -import org.eclipse.jetty.websocket.common.util.ReflectUtils; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.InvalidWebSocketException; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.messages.ByteArrayMessageSink; +import org.eclipse.jetty.websocket.util.messages.ByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.InputStreamMessageSink; +import org.eclipse.jetty.websocket.util.messages.MessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.PartialStringMessageSink; +import org.eclipse.jetty.websocket.util.messages.ReaderMessageSink; +import org.eclipse.jetty.websocket.util.messages.StringMessageSink; /** * Factory to create {@link JettyWebSocketFrameHandler} instances suitable for @@ -120,16 +123,16 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle { JettyWebSocketFrameHandlerMetadata metadata = getMetadata(endpointInstance.getClass()); - final MethodHandle openHandle = bindTo(metadata.getOpenHandle(), endpointInstance); - final MethodHandle closeHandle = bindTo(metadata.getCloseHandle(), endpointInstance); - final MethodHandle errorHandle = bindTo(metadata.getErrorHandle(), endpointInstance); - final MethodHandle textHandle = bindTo(metadata.getTextHandle(), endpointInstance); - final MethodHandle binaryHandle = bindTo(metadata.getBinaryHandle(), endpointInstance); + final MethodHandle openHandle = InvokerUtils.bindTo(metadata.getOpenHandle(), endpointInstance); + final MethodHandle closeHandle = InvokerUtils.bindTo(metadata.getCloseHandle(), endpointInstance); + final MethodHandle errorHandle = InvokerUtils.bindTo(metadata.getErrorHandle(), endpointInstance); + final MethodHandle textHandle = InvokerUtils.bindTo(metadata.getTextHandle(), endpointInstance); + final MethodHandle binaryHandle = InvokerUtils.bindTo(metadata.getBinaryHandle(), endpointInstance); final Class textSinkClass = metadata.getTextSink(); final Class binarySinkClass = metadata.getBinarySink(); - final MethodHandle frameHandle = bindTo(metadata.getFrameHandle(), endpointInstance); - final MethodHandle pingHandle = bindTo(metadata.getPingHandle(), endpointInstance); - final MethodHandle pongHandle = bindTo(metadata.getPongHandle(), endpointInstance); + final MethodHandle frameHandle = InvokerUtils.bindTo(metadata.getFrameHandle(), endpointInstance); + final MethodHandle pingHandle = InvokerUtils.bindTo(metadata.getPingHandle(), endpointInstance); + final MethodHandle pongHandle = InvokerUtils.bindTo(metadata.getPongHandle(), endpointInstance); BatchMode batchMode = metadata.getBatchMode(); JettyWebSocketFrameHandler frameHandler = new JettyWebSocketFrameHandler( @@ -154,46 +157,27 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle try { - try - { - Constructor sinkConstructor = sinkClass.getConstructor(Executor.class, MethodHandle.class, Session.class); - MessageSink messageSink = (MessageSink)sinkConstructor.newInstance(executor, msgHandle, session); - return messageSink; - } - catch (NoSuchMethodException e) - { - try - { - Constructor sinkConstructor = sinkClass.getConstructor(Executor.class, MethodHandle.class); - MessageSink messageSink = (MessageSink)sinkConstructor.newInstance(executor, msgHandle); - return messageSink; - } - catch (NoSuchMethodException e2) - { - e.addSuppressed(e2); - throw new RuntimeException("Missing expected MessageSink constructor found at: " + sinkClass.getName(), e); - } - } + MethodHandles.Lookup lookup = JettyWebSocketFrameHandlerFactory.getServerMethodHandleLookup(); + MethodHandle ctorHandle = lookup.findConstructor(sinkClass, + MethodType.methodType(void.class, CoreSession.class, MethodHandle.class)); + return (MessageSink)ctorHandle.invoke(session.getCoreSession(), msgHandle); + } + catch (NoSuchMethodException e) + { + throw new RuntimeException("Missing expected MessageSink constructor found at: " + sinkClass.getName(), e); } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { throw new RuntimeException("Unable to create MessageSink: " + sinkClass.getName(), e); } - } - - public static MethodHandle bindTo(MethodHandle methodHandle, Object... objs) - { - if (methodHandle == null) - return null; - MethodHandle ret = methodHandle; - for (Object obj : objs) + catch (RuntimeException e) { - if (ret.type().parameterType(0).isAssignableFrom(obj.getClass())) - { - ret = ret.bindTo(obj); - } + throw e; + } + catch (Throwable t) + { + throw new RuntimeException(t); } - return ret; } private MethodHandle toMethodHandle(MethodHandles.Lookup lookup, Method method) @@ -211,8 +195,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle private JettyWebSocketFrameHandlerMetadata createListenerMetadata(Class endpointClass) { JettyWebSocketFrameHandlerMetadata metadata = new JettyWebSocketFrameHandlerMetadata(); - - MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandles.Lookup lookup = JettyWebSocketFrameHandlerFactory.getApplicationMethodHandleLookup(endpointClass); Method openMethod = ReflectUtils.findMethod(endpointClass, "onWebSocketConnect", Session.class); MethodHandle open = toMethodHandle(lookup, openMethod); @@ -255,11 +238,11 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle { Method textMethod = ReflectUtils.findMethod(endpointClass, "onWebSocketPartialText", String.class, boolean.class); MethodHandle text = toMethodHandle(lookup, textMethod); - metadata.setTextHandler(PartialTextMessageSink.class, text, textMethod); + metadata.setTextHandler(PartialStringMessageSink.class, text, textMethod); Method binaryMethod = ReflectUtils.findMethod(endpointClass, "onWebSocketPartialBinary", ByteBuffer.class, boolean.class); MethodHandle binary = toMethodHandle(lookup, binaryMethod); - metadata.setBinaryHandle(PartialBinaryMessageSink.class, binary, binaryMethod); + metadata.setBinaryHandle(PartialByteBufferMessageSink.class, binary, binaryMethod); } // Frame Listener @@ -291,6 +274,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle metadata.setIdleTimeout(Duration.ofMillis(max)); metadata.setBatchMode(anno.batchMode()); + MethodHandles.Lookup lookup = getApplicationMethodHandleLookup(endpointClass); Method onmethod; // OnWebSocketConnect [0..1] @@ -299,7 +283,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle { assertSignatureValid(endpointClass, onmethod, OnWebSocketConnect.class); final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class).required(); - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(endpointClass, onmethod, SESSION); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, endpointClass, onmethod, SESSION); metadata.setOpenHandler(methodHandle, onmethod); } @@ -311,7 +295,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class); final InvokerUtils.Arg STATUS_CODE = new InvokerUtils.Arg(int.class); final InvokerUtils.Arg REASON = new InvokerUtils.Arg(String.class); - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(endpointClass, onmethod, SESSION, STATUS_CODE, REASON); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, endpointClass, onmethod, SESSION, STATUS_CODE, REASON); // TODO: need mutation of args? ... // Session + CloseInfo -> // setOnClose((closeInfo) ->{ @@ -328,7 +312,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle assertSignatureValid(endpointClass, onmethod, OnWebSocketError.class); final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class); final InvokerUtils.Arg CAUSE = new InvokerUtils.Arg(Throwable.class).required(); - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(endpointClass, onmethod, SESSION, CAUSE); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, endpointClass, onmethod, SESSION, CAUSE); metadata.setErrorHandler(methodHandle, onmethod); } @@ -339,7 +323,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle assertSignatureValid(endpointClass, onmethod, OnWebSocketFrame.class); final InvokerUtils.Arg SESSION = new InvokerUtils.Arg(Session.class); final InvokerUtils.Arg FRAME = new InvokerUtils.Arg(Frame.class).required(); - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(endpointClass, onmethod, SESSION, FRAME); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, endpointClass, onmethod, SESSION, FRAME); metadata.setFrameHandler(methodHandle, onmethod); } @@ -381,7 +365,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle { assertSignatureValid(endpointClass, onMsg, OnWebSocketMessage.class); - MethodHandle methodHandle = InvokerUtils.optionalMutatedInvoker(endpointClass, onMsg, InvokerUtils.PARAM_IDENTITY, textCallingArgs); + MethodHandle methodHandle = InvokerUtils.optionalMutatedInvoker(lookup, endpointClass, onMsg, textCallingArgs); if (methodHandle != null) { // Normal Text Message @@ -390,7 +374,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle continue onmessageloop; } - methodHandle = InvokerUtils.optionalMutatedInvoker(endpointClass, onMsg, InvokerUtils.PARAM_IDENTITY, binaryBufferCallingArgs); + methodHandle = InvokerUtils.optionalMutatedInvoker(lookup, endpointClass, onMsg, binaryBufferCallingArgs); if (methodHandle != null) { // ByteBuffer Binary Message @@ -399,7 +383,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle continue onmessageloop; } - methodHandle = InvokerUtils.optionalMutatedInvoker(endpointClass, onMsg, InvokerUtils.PARAM_IDENTITY, binaryArrayCallingArgs); + methodHandle = InvokerUtils.optionalMutatedInvoker(lookup, endpointClass, onMsg, binaryArrayCallingArgs); if (methodHandle != null) { // byte[] Binary Message @@ -408,7 +392,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle continue onmessageloop; } - methodHandle = InvokerUtils.optionalMutatedInvoker(endpointClass, onMsg, InvokerUtils.PARAM_IDENTITY, inputStreamCallingArgs); + methodHandle = InvokerUtils.optionalMutatedInvoker(lookup, endpointClass, onMsg, inputStreamCallingArgs); if (methodHandle != null) { // InputStream Binary Message @@ -417,7 +401,7 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle continue onmessageloop; } - methodHandle = InvokerUtils.optionalMutatedInvoker(endpointClass, onMsg, InvokerUtils.PARAM_IDENTITY, readerCallingArgs); + methodHandle = InvokerUtils.optionalMutatedInvoker(lookup, endpointClass, onMsg, readerCallingArgs); if (methodHandle != null) { // Reader Text Message @@ -473,6 +457,55 @@ public class JettyWebSocketFrameHandlerFactory extends ContainerLifeCycle throw new InvalidSignatureException(err.toString()); } + /** + *

        + * Gives a {@link MethodHandles.Lookup} instance to be used to find methods in server classes. + * For lookups on application classes use {@link #getApplicationMethodHandleLookup(Class)} instead. + *

        + *

        + * This uses the caller sensitive {@link MethodHandles#lookup()}, this will allow MethodHandle access + * to server classes we need to use and will give access permissions to private methods as well. + *

        + * + * @return a lookup object to be used to find methods on server classes. + */ + public static MethodHandles.Lookup getServerMethodHandleLookup() + { + return MethodHandles.lookup(); + } + + /** + *

        + * Gives a {@link MethodHandles.Lookup} instance to be used to find public methods in application classes. + * For lookups on server classes use {@link #getServerMethodHandleLookup()} instead. + *

        + *

        + * This uses {@link MethodHandles#publicLookup()} as we only need access to public method of the lookupClass. + * To look up a method on the lookupClass, it must be public and the class must be accessible from this + * module, so if the lookupClass is in a JPMS module it must be exported so that the public methods + * of the lookupClass are accessible outside of the module. + *

        + *

        + * The {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} allows us to search specifically + * in the endpoint Class to avoid any potential linkage errors which could occur if the same + * class is present in multiple web apps. Unlike using {@link MethodHandles#publicLookup()} + * using {@link MethodHandles#lookup()} with {@link java.lang.invoke.MethodHandles.Lookup#in(Class)} + * will cause the lookup to lose its public access to the lookup class if they are in different modules. + *

        + *

        + * {@link MethodHandles#privateLookupIn(Class, MethodHandles.Lookup)} is also unsuitable because it + * requires the caller module to read the target module, and the target module to open reflective + * access to the lookupClasses private methods. This is possible but requires extra configuration + * to provide private access which is not necessary for the purpose of accessing the public methods. + *

        + * @param lookupClass the desired lookup class for the new lookup object. + * @return a lookup object to be used to find methods on the lookupClass. + */ + public static MethodHandles.Lookup getApplicationMethodHandleLookup(Class lookupClass) + { + return MethodHandles.publicLookup().in(lookupClass); + } + @Override public void dump(Appendable out, String indent) throws IOException { diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerMetadata.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerMetadata.java similarity index 80% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerMetadata.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerMetadata.java index a99c2877d7a..2e9b6c2ef0f 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerMetadata.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerMetadata.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -22,9 +22,10 @@ import java.lang.invoke.MethodHandle; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.InvalidWebSocketException; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.util.messages.MessageSink; -public class JettyWebSocketFrameHandlerMetadata extends FrameHandler.ConfigurationCustomizer +public class JettyWebSocketFrameHandlerMetadata extends Configuration.ConfigurationCustomizer { private MethodHandle openHandle; private MethodHandle closeHandle; diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketRemoteEndpoint.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketRemoteEndpoint.java similarity index 72% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketRemoteEndpoint.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketRemoteEndpoint.java index ca8c3b37fd9..cd06286f3e3 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketRemoteEndpoint.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketRemoteEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -22,27 +22,32 @@ import java.io.IOException; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.util.Objects; +import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.websocket.api.BatchMode; +import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WriteCallback; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; -import org.eclipse.jetty.websocket.core.ProtocolException; +import org.eclipse.jetty.websocket.core.exception.ProtocolException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.nio.charset.StandardCharsets.UTF_8; public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket.api.RemoteEndpoint { - private final FrameHandler.CoreSession coreSession; + private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketRemoteEndpoint.class); + + private final CoreSession coreSession; private byte messageType = -1; - private final SharedBlockingCallback blocker = new SharedBlockingCallback(); private BatchMode batchMode; - public JettyWebSocketRemoteEndpoint(FrameHandler.CoreSession coreSession, BatchMode batchMode) + public JettyWebSocketRemoteEndpoint(CoreSession coreSession, BatchMode batchMode) { this.coreSession = Objects.requireNonNull(coreSession); this.batchMode = batchMode; @@ -55,14 +60,7 @@ public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket */ public void close() { - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.close(b); - } - catch (IOException e) - { - coreSession.close(Callback.NOOP); - } + close(StatusCode.NO_CODE, null); } /** @@ -74,13 +72,15 @@ public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket */ public void close(int statusCode, String reason) { - try (SharedBlockingCallback.Blocker b = blocker.acquire()) + try { + FutureCallback b = new FutureCallback(); coreSession.close(statusCode, reason, b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } catch (IOException e) { - coreSession.close(Callback.NOOP); + LOG.trace("IGNORED", e); } } @@ -114,11 +114,9 @@ public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket @Override public void sendPartialBytes(ByteBuffer fragment, boolean isLast) throws IOException { - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - sendPartialBytes(fragment, isLast, b); - b.block(); - } + FutureCallback b = new FutureCallback(); + sendPartialBytes(fragment, isLast, b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } @Override @@ -158,11 +156,9 @@ public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket @Override public void sendPartialString(String fragment, boolean isLast) throws IOException { - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - sendPartialText(fragment, isLast, b); - b.block(); - } + FutureCallback b = new FutureCallback(); + sendPartialText(fragment, isLast, b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } @Override @@ -227,16 +223,9 @@ public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket private void sendBlocking(Frame frame) throws IOException { - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.sendFrame(frame, b, false); - b.block(); - } - } - - protected FrameHandler.CoreSession getCoreSession() - { - return coreSession; + FutureCallback b = new FutureCallback(); + coreSession.sendFrame(frame, b, false); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); } @Override @@ -265,10 +254,14 @@ public class JettyWebSocketRemoteEndpoint implements org.eclipse.jetty.websocket @Override public void flush() throws IOException { - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.flush(b); - b.block(); - } + FutureCallback b = new FutureCallback(); + coreSession.flush(b); + b.block(getBlockingTimeout(), TimeUnit.MILLISECONDS); + } + + private long getBlockingTimeout() + { + long idleTimeout = coreSession.getIdleTimeout().toMillis(); + return (idleTimeout > 0) ? idleTimeout + 1000 : idleTimeout; } } diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java similarity index 50% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java index 4bcbbb0a26f..e963800ae9f 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -23,8 +23,8 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketSessionListener; public class SessionTracker extends AbstractLifeCycle implements WebSocketSessionListener @@ -39,7 +39,6 @@ public class SessionTracker extends AbstractLifeCycle implements WebSocketSessio @Override public void onWebSocketSessionOpened(Session session) { - LifeCycle.start(session); sessions.add(session); } @@ -47,7 +46,6 @@ public class SessionTracker extends AbstractLifeCycle implements WebSocketSessio public void onWebSocketSessionClosed(Session session) { sessions.remove(session); - LifeCycle.stop(session); } @Override @@ -55,8 +53,10 @@ public class SessionTracker extends AbstractLifeCycle implements WebSocketSessio { for (Session session : sessions) { - LifeCycle.stop(session); + // SHUTDOWN is abnormal close status so it will hard close connection after sent. + session.close(StatusCode.SHUTDOWN, "Container being shut down"); } + super.doStop(); } } diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java similarity index 71% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java rename to jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java index e136ac32562..6f1c2a5988a 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -23,30 +23,27 @@ import java.net.SocketAddress; import java.time.Duration; import java.util.Objects; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.CloseStatus; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.SuspendToken; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.api.WebSocketBehavior; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class WebSocketSession extends AbstractLifeCycle implements Session, SuspendToken, Dumpable +public class WebSocketSession implements Session, SuspendToken, Dumpable { - private static final Logger LOG = Log.getLogger(WebSocketSession.class); - private final FrameHandler.CoreSession coreSession; + private static final Logger LOG = LoggerFactory.getLogger(WebSocketSession.class); + private final CoreSession coreSession; private final JettyWebSocketFrameHandler frameHandler; private final JettyWebSocketRemoteEndpoint remoteEndpoint; private final UpgradeRequest upgradeRequest; private final UpgradeResponse upgradeResponse; - public WebSocketSession(FrameHandler.CoreSession coreSession, JettyWebSocketFrameHandler frameHandler) + public WebSocketSession(CoreSession coreSession, JettyWebSocketFrameHandler frameHandler) { this.frameHandler = Objects.requireNonNull(frameHandler); this.coreSession = Objects.requireNonNull(coreSession); @@ -117,6 +114,18 @@ public class WebSocketSession extends AbstractLifeCycle implements Session, Susp return coreSession.getMaxTextMessageSize(); } + @Override + public long getMaxFrameSize() + { + return coreSession.getMaxFrameSize(); + } + + @Override + public boolean isAutoFragment() + { + return coreSession.isAutoFragment(); + } + @Override public void setIdleTimeout(Duration duration) { @@ -147,6 +156,18 @@ public class WebSocketSession extends AbstractLifeCycle implements Session, Susp coreSession.setMaxTextMessageSize(size); } + @Override + public void setMaxFrameSize(long maxFrameSize) + { + coreSession.setMaxFrameSize(maxFrameSize); + } + + @Override + public void setAutoFragment(boolean autoFragment) + { + coreSession.setAutoFragment(autoFragment); + } + @Override public String getProtocolVersion() { @@ -162,7 +183,7 @@ public class WebSocketSession extends AbstractLifeCycle implements Session, Susp @Override public boolean isOpen() { - return remoteEndpoint.getCoreSession().isOutputOpen(); + return coreSession.isOutputOpen(); } @Override @@ -214,30 +235,11 @@ public class WebSocketSession extends AbstractLifeCycle implements Session, Susp frameHandler.resume(); } - public FrameHandler.CoreSession getCoreSession() + public CoreSession getCoreSession() { return coreSession; } - @Override - protected void doStop() throws Exception - { - coreSession.close(StatusCode.SHUTDOWN, "Container being shut down", new Callback() - { - @Override - public void succeeded() - { - coreSession.abort(); - } - - @Override - public void failed(Throwable x) - { - coreSession.abort(); - } - }); - } - @Override public void dump(Appendable out, String indent) throws IOException { diff --git a/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/package-info.java b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/package-info.java new file mode 100644 index 00000000000..11a23509f73 --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/main/java/org/eclipse/jetty/websocket/common/package-info.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty WebSocket Common : Implementation [Internal Use Only] + *

        + * A core set of internal implementation classes for the Jetty WebSocket API. + *

        + *

        + * Note: do not reference or use classes present in this package space in your code.
        + * Restrict your usage to the Jetty WebSocket API classes, the Jetty WebSocket Client API, + * or the Jetty WebSocket Servlet API. + *

        + */ +package org.eclipse.jetty.websocket.common; + diff --git a/jetty-websocket/jetty-websocket-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.api.extensions.ExtensionConfig$Parser b/jetty-websocket/websocket-jetty-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.api.extensions.ExtensionConfig$Parser similarity index 100% rename from jetty-websocket/jetty-websocket-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.api.extensions.ExtensionConfig$Parser rename to jetty-websocket/websocket-jetty-common/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.api.extensions.ExtensionConfig$Parser diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/DummyContainer.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/DummyContainer.java similarity index 69% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/DummyContainer.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/DummyContainer.java index e90f6452e98..1399ba0daf8 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/DummyContainer.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/DummyContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -27,6 +27,7 @@ import java.util.function.Consumer; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.api.WebSocketSessionListener; public class DummyContainer extends ContainerLifeCycle implements WebSocketContainer diff --git a/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/EndPoints.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/EndPoints.java new file mode 100644 index 00000000000..373e0dd7ccc --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/EndPoints.java @@ -0,0 +1,512 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.common; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.Frame; +import org.eclipse.jetty.websocket.api.RemoteEndpoint; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketFrameListener; +import org.eclipse.jetty.websocket.api.WebSocketListener; +import org.eclipse.jetty.websocket.api.WebSocketPartialListener; +import org.eclipse.jetty.websocket.api.WebSocketPingPongListener; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.util.TextUtil; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; + +public class EndPoints +{ + private EndPoints() + { + } + + public static class ListenerBasicSocket implements WebSocketListener + { + public EventQueue events = new EventQueue(); + + @Override + public void onWebSocketBinary(byte[] payload, int offset, int len) + { + events.add("onWebSocketBinary([%d], %d, %d)", payload.length, offset, len); + } + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); + } + + @Override + public void onWebSocketConnect(Session session) + { + events.add("onWebSocketConnect(%s)", session); + } + + @Override + public void onWebSocketError(Throwable cause) + { + events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); + } + + @Override + public void onWebSocketText(String message) + { + events.add("onWebSocketText(%s)", TextUtil.quote(message)); + } + } + + public static class ListenerFrameSocket implements WebSocketFrameListener + { + public EventQueue events = new EventQueue(); + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); + } + + @Override + public void onWebSocketConnect(Session session) + { + events.add("onWebSocketConnect(%s)", session); + } + + @Override + public void onWebSocketError(Throwable cause) + { + events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); + } + + @Override + public void onWebSocketFrame(Frame frame) + { + events.add("onWebSocketFrame(%s)", frame.toString()); + } + } + + public static class ListenerPartialSocket implements WebSocketPartialListener + { + public EventQueue events = new EventQueue(); + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); + } + + @Override + public void onWebSocketConnect(Session session) + { + events.add("onWebSocketConnect(%s)", session); + } + + @Override + public void onWebSocketError(Throwable cause) + { + events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); + } + + @Override + public void onWebSocketPartialText(String payload, boolean fin) + { + events.add("onWebSocketPartialText(%s, %b)", TextUtil.quote(payload), fin); + } + + @Override + public void onWebSocketPartialBinary(ByteBuffer payload, boolean fin) + { + events.add("onWebSocketPartialBinary(%s, %b)", BufferUtil.toDetailString(payload), fin); + } + } + + public static class ListenerPingPongSocket implements WebSocketPingPongListener + { + public EventQueue events = new EventQueue(); + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason)); + } + + @Override + public void onWebSocketConnect(Session session) + { + events.add("onWebSocketConnect(%s)", session); + } + + @Override + public void onWebSocketError(Throwable cause) + { + events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage())); + } + + @Override + public void onWebSocketPing(ByteBuffer payload) + { + events.add("onWebSocketPing(%s)", BufferUtil.toDetailString(payload)); + } + + @Override + public void onWebSocketPong(ByteBuffer payload) + { + events.add("onWebSocketPong(%s)", BufferUtil.toDetailString(payload)); + } + } + + /** + * Invalid Socket: Annotate 2 methods with interest in Binary Messages. + */ + @WebSocket + public static class BadDuplicateBinarySocket + { + /** + * First method + * + * @param payload the payload + * @param offset the offset + * @param len the len + */ + @OnWebSocketMessage + public void binMe(byte[] payload, int offset, int len) + { + /* ignore */ + } + + /** + * Second method (also binary) + * + * @param stream the input stream + */ + @OnWebSocketMessage + public void streamMe(InputStream stream) + { + /* ignore */ + } + } + + @WebSocket + public static class AnnotatedBinaryArraySocket + { + public EventQueue events = new EventQueue(); + + @OnWebSocketMessage + public void onBinary(byte[] payload, int offset, int length) + { + events.add("onBinary([%d],%d,%d)", payload.length, offset, length); + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); + } + + @OnWebSocketConnect + public void onConnect(Session sess) + { + events.add("onConnect(%s)", sess); + } + } + + @WebSocket + public static class AnnotatedBinaryStreamSocket + { + public EventQueue events = new EventQueue(); + + @OnWebSocketMessage + public void onBinary(InputStream stream) + { + assertThat("InputStream", stream, notNullValue()); + events.add("onBinary(%s)", stream); + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); + } + + @OnWebSocketConnect + public void onConnect(Session sess) + { + events.add("onConnect(%s)", sess); + } + } + + @WebSocket + public static class AnnotatedTextSocket + { + public EventQueue events = new EventQueue(); + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); + } + + @OnWebSocketConnect + public void onConnect(Session sess) + { + events.add("onConnect(%s)", sess); + } + + @OnWebSocketError + public void onError(Throwable cause) + { + events.add("onError(%s: %s)", cause.getClass().getSimpleName(), cause.getMessage()); + } + + @OnWebSocketMessage + public void onText(String message) + { + events.add("onText(%s)", TextUtil.quote(message)); + } + } + + @WebSocket + public static class AnnotatedTextStreamSocket + { + public EventQueue events = new EventQueue(); + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason)); + } + + @OnWebSocketConnect + public void onConnect(Session sess) + { + events.add("onConnect(%s)", sess); + } + + @OnWebSocketMessage + public void onText(Reader reader) + { + events.add("onText(%s)", reader); + } + } + + /** + * Invalid Socket: Annotate a message interest on a method with a return type. + */ + @WebSocket + public static class BadBinarySignatureSocket + { + /** + * Declaring a non-void return type + * + * @param session the session + * @param buf the buffer + * @param offset the offset + * @param len the length + * @return the response boolean + */ + @OnWebSocketMessage + public boolean onBinary(Session session, byte[] buf, int offset, int len) + { + return false; + } + } + + @WebSocket + public static class BadDuplicateFrameSocket + { + /** + * The get a frame + * + * @param frame the frame + */ + @OnWebSocketFrame + public void frameMe(org.eclipse.jetty.websocket.core.Frame frame) + { + /* ignore */ + } + + /** + * This is a duplicate frame type (should throw an exception attempting to use) + * + * @param frame the frame + */ + @OnWebSocketFrame + public void watchMe(org.eclipse.jetty.websocket.core.Frame frame) + { + /* ignore */ + } + } + + /** + * Invalid Socket: Annotate a message interest on a static method + */ + @WebSocket + public static class BadTextSignatureSocket + { + /** + * Declaring a static method + * + * @param session the session + * @param text the text message + */ + @OnWebSocketMessage + public static void onText(Session session, String text) + { + /* do nothing */ + } + } + + @WebSocket + public static class FrameSocket + { + /** + * A frame + * + * @param frame the frame + */ + @OnWebSocketFrame + public void frameMe(Frame frame) + { + /* ignore */ + } + } + + /** + * Test of constructing a new WebSocket based on a base class + */ + @WebSocket + public static class MyEchoBinarySocket extends MyEchoSocket + { + @OnWebSocketMessage + public void echoBin(byte[] buf, int offset, int length) + { + try + { + getRemote().sendBytes(ByteBuffer.wrap(buf, offset, length)); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + /** + * The most common websocket implementation. + *

        + * This version tracks the connection per socket instance and will + */ + @WebSocket + public static class MyEchoSocket + { + private Session session; + private RemoteEndpoint remote; + + public RemoteEndpoint getRemote() + { + return remote; + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + this.session = null; + } + + @OnWebSocketConnect + public void onConnect(Session session) + { + this.session = session; + this.remote = session.getRemote(); + } + + @OnWebSocketMessage + public void onText(String message) + { + if (session == null) + { + // no connection, do nothing. + // this is possible due to async behavior + return; + } + + try + { + remote.sendString(message); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + /** + * Example of a stateless websocket implementation. + *

        + * Useful for websockets that only reply to incoming requests. + *

        + * Note: that for this style of websocket to be viable on the server side be sure that you only create 1 instance of this socket, as more instances would be + * wasteful of resources and memory. + */ + @WebSocket + public static class MyStatelessEchoSocket + { + @OnWebSocketMessage + public void onText(Session session, String text) + { + session.getRemote().sendString(text, null); + } + } + + /** + * The most basic websocket declaration. + */ + @WebSocket + public static class NoopSocket + { + /* intentionally do nothing */ + } + + /** + * (Test Case) + *

        + * Intentionally not specifying the @WebSocket annotation here + */ + public static class NotASocket + { + @OnWebSocketConnect + public void onConnect(Session session) + { + /* do nothing */ + } + } +} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/EventQueue.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/EventQueue.java similarity index 56% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/EventQueue.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/EventQueue.java index b50f0154c5d..8358dfe595d 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/EventQueue.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/EventQueue.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerTest.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerTest.java similarity index 87% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerTest.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerTest.java index 6ac2ec2d348..036fa6ea5da 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerTest.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -32,14 +32,10 @@ import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketConnectionListener; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; -import org.eclipse.jetty.websocket.common.endpoints.listeners.ListenerBasicSocket; -import org.eclipse.jetty.websocket.common.endpoints.listeners.ListenerFrameSocket; -import org.eclipse.jetty.websocket.common.endpoints.listeners.ListenerPartialSocket; -import org.eclipse.jetty.websocket.common.endpoints.listeners.ListenerPingPongSocket; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -67,7 +63,7 @@ public class JettyWebSocketFrameHandlerTest } private JettyWebSocketFrameHandlerFactory endpointFactory = new JettyWebSocketFrameHandlerFactory(container); - private FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty() + private CoreSession coreSession = new CoreSession.Empty() { @Override public Behavior getBehavior() @@ -147,7 +143,7 @@ public class JettyWebSocketFrameHandlerTest } @Test - public void testAnnotatedStreamedText_Single() throws Exception + public void testAnnotatedStreamedTextSingle() throws Exception { assertTimeout(Duration.ofMillis(1000), () -> { @@ -169,7 +165,7 @@ public class JettyWebSocketFrameHandlerTest } @Test - public void testAnnotatedStreamedText_MultipleParts() throws Exception + public void testAnnotatedStreamedTextMultipleParts() throws Exception { assertTimeout(Duration.ofMillis(1000), () -> { @@ -197,7 +193,7 @@ public class JettyWebSocketFrameHandlerTest public void testListenerPartialSocket() throws Exception { // Setup - ListenerPartialSocket socket = new ListenerPartialSocket(); + EndPoints.ListenerPartialSocket socket = new EndPoints.ListenerPartialSocket(); JettyWebSocketFrameHandler localEndpoint = newLocalFrameHandler(socket); // Trigger Events @@ -228,7 +224,7 @@ public class JettyWebSocketFrameHandlerTest public void testListenerBasicSocket() throws Exception { // Setup - ListenerBasicSocket socket = new ListenerBasicSocket(); + EndPoints.ListenerBasicSocket socket = new EndPoints.ListenerBasicSocket(); JettyWebSocketFrameHandler localEndpoint = newLocalFrameHandler(socket); // Trigger Events @@ -251,10 +247,10 @@ public class JettyWebSocketFrameHandlerTest } @Test - public void testListenerBasicSocket_Error() throws Exception + public void testListenerBasicSocketError() throws Exception { // Setup - ListenerBasicSocket socket = new ListenerBasicSocket(); + EndPoints.ListenerBasicSocket socket = new EndPoints.ListenerBasicSocket(); JettyWebSocketFrameHandler localEndpoint = newLocalFrameHandler(socket); // Trigger Events @@ -274,7 +270,7 @@ public class JettyWebSocketFrameHandlerTest public void testListenerFrameSocket() throws Exception { // Setup - ListenerFrameSocket socket = new ListenerFrameSocket(); + EndPoints.ListenerFrameSocket socket = new EndPoints.ListenerFrameSocket(); JettyWebSocketFrameHandler localEndpoint = newLocalFrameHandler(socket); // Trigger Events @@ -304,7 +300,7 @@ public class JettyWebSocketFrameHandlerTest public void testListenerPingPongSocket() throws Exception { // Setup - ListenerPingPongSocket socket = new ListenerPingPongSocket(); + EndPoints.ListenerPingPongSocket socket = new EndPoints.ListenerPingPongSocket(); JettyWebSocketFrameHandler localEndpoint = newLocalFrameHandler(socket); // Trigger Events diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/LocalEndpointMetadataTest.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/LocalEndpointMetadataTest.java similarity index 78% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/LocalEndpointMetadataTest.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/LocalEndpointMetadataTest.java index 58c6a09f2d3..9c02961fa26 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/LocalEndpointMetadataTest.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/LocalEndpointMetadataTest.java @@ -1,43 +1,30 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; import org.eclipse.jetty.websocket.api.InvalidWebSocketException; -import org.eclipse.jetty.websocket.common.endpoints.annotated.AnnotatedBinaryArraySocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.AnnotatedBinaryStreamSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.AnnotatedTextSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.AnnotatedTextStreamSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.BadBinarySignatureSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.BadDuplicateBinarySocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.BadDuplicateFrameSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.BadTextSignatureSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.FrameSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.MyEchoBinarySocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.MyEchoSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.MyStatelessEchoSocket; -import org.eclipse.jetty.websocket.common.endpoints.annotated.NoopSocket; -import org.eclipse.jetty.websocket.common.endpoints.listeners.ListenerBasicSocket; -import org.eclipse.jetty.websocket.common.endpoints.listeners.ListenerFrameSocket; -import org.eclipse.jetty.websocket.common.message.ByteArrayMessageSink; -import org.eclipse.jetty.websocket.common.message.InputStreamMessageSink; -import org.eclipse.jetty.websocket.common.message.ReaderMessageSink; -import org.eclipse.jetty.websocket.common.message.StringMessageSink; +import org.eclipse.jetty.websocket.util.DuplicateAnnotationException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; +import org.eclipse.jetty.websocket.util.messages.ByteArrayMessageSink; +import org.eclipse.jetty.websocket.util.messages.InputStreamMessageSink; +import org.eclipse.jetty.websocket.util.messages.ReaderMessageSink; +import org.eclipse.jetty.websocket.util.messages.StringMessageSink; import org.hamcrest.Matcher; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -83,7 +70,7 @@ public class LocalEndpointMetadataTest public void testAnnotatedBadDuplicateBinarySocket() throws Exception { // Should toss exception - Exception e = assertThrows(InvalidWebSocketException.class, () -> createMetadata(BadDuplicateBinarySocket.class)); + Exception e = assertThrows(InvalidWebSocketException.class, () -> createMetadata(EndPoints.BadDuplicateBinarySocket.class)); assertThat(e.getMessage(), allOf(containsString("Cannot replace previously assigned"), containsString("BINARY Handler"))); } @@ -94,7 +81,7 @@ public class LocalEndpointMetadataTest public void testAnnotatedBadDuplicateFrameSocket() throws Exception { // Should toss exception - Exception e = assertThrows(InvalidWebSocketException.class, () -> createMetadata(BadDuplicateFrameSocket.class)); + Exception e = assertThrows(DuplicateAnnotationException.class, () -> createMetadata(EndPoints.BadDuplicateFrameSocket.class)); assertThat(e.getMessage(), containsString("Duplicate @OnWebSocketFrame")); } @@ -102,10 +89,10 @@ public class LocalEndpointMetadataTest * Test Case for bad declaration a method with a non-void return type */ @Test - public void testAnnotatedBadSignature_NonVoidReturn() throws Exception + public void testAnnotatedBadSignatureNonVoidReturn() throws Exception { // Should toss exception - Exception e = assertThrows(InvalidWebSocketException.class, () -> createMetadata(BadBinarySignatureSocket.class)); + Exception e = assertThrows(InvalidSignatureException.class, () -> createMetadata(EndPoints.BadBinarySignatureSocket.class)); assertThat(e.getMessage(), containsString("must be void")); } @@ -113,10 +100,10 @@ public class LocalEndpointMetadataTest * Test Case for bad declaration a method with a public static method */ @Test - public void testAnnotatedBadSignature_Static() throws Exception + public void testAnnotatedBadSignatureStatic() throws Exception { // Should toss exception - Exception e = assertThrows(InvalidWebSocketException.class, () -> createMetadata(BadTextSignatureSocket.class)); + Exception e = assertThrows(InvalidSignatureException.class, () -> createMetadata(EndPoints.BadTextSignatureSocket.class)); assertThat(e.getMessage(), containsString("must not be static")); } @@ -126,9 +113,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedBinaryArraySocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(AnnotatedBinaryArraySocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.AnnotatedBinaryArraySocket.class); - String classId = AnnotatedBinaryArraySocket.class.getSimpleName(); + String classId = EndPoints.AnnotatedBinaryArraySocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), EXISTS); assertThat(classId + ".binarySink", metadata.getBinarySink(), equalTo(ByteArrayMessageSink.class)); @@ -151,9 +138,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedBinaryStreamSocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(AnnotatedBinaryStreamSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.AnnotatedBinaryStreamSocket.class); - String classId = AnnotatedBinaryStreamSocket.class.getSimpleName(); + String classId = EndPoints.AnnotatedBinaryStreamSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), EXISTS); assertThat(classId + ".binarySink", metadata.getBinarySink(), equalTo(InputStreamMessageSink.class)); @@ -176,9 +163,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedMyEchoBinarySocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(MyEchoBinarySocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.MyEchoBinarySocket.class); - String classId = MyEchoBinarySocket.class.getSimpleName(); + String classId = EndPoints.MyEchoBinarySocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), EXISTS); assertThat(classId + ".binarySink", metadata.getBinarySink(), equalTo(ByteArrayMessageSink.class)); @@ -201,9 +188,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedMyEchoSocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(MyEchoSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.MyEchoSocket.class); - String classId = MyEchoSocket.class.getSimpleName(); + String classId = EndPoints.MyEchoSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); @@ -226,9 +213,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedMyStatelessEchoSocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(MyStatelessEchoSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.MyStatelessEchoSocket.class); - String classId = MyStatelessEchoSocket.class.getSimpleName(); + String classId = EndPoints.MyStatelessEchoSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); @@ -251,9 +238,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedNoop() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(NoopSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.NoopSocket.class); - String classId = NoopSocket.class.getSimpleName(); + String classId = EndPoints.NoopSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); @@ -276,9 +263,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedOnFrame() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(FrameSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.FrameSocket.class); - String classId = FrameSocket.class.getSimpleName(); + String classId = EndPoints.FrameSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); @@ -301,9 +288,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedTextSocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(AnnotatedTextSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.AnnotatedTextSocket.class); - String classId = AnnotatedTextSocket.class.getSimpleName(); + String classId = EndPoints.AnnotatedTextSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); @@ -326,9 +313,9 @@ public class LocalEndpointMetadataTest @Test public void testAnnotatedTextStreamSocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(AnnotatedTextStreamSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.AnnotatedTextStreamSocket.class); - String classId = AnnotatedTextStreamSocket.class.getSimpleName(); + String classId = EndPoints.AnnotatedTextStreamSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); @@ -351,9 +338,9 @@ public class LocalEndpointMetadataTest @Test public void testListenerBasicSocket() { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(ListenerBasicSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.ListenerBasicSocket.class); - String classId = ListenerBasicSocket.class.getSimpleName(); + String classId = EndPoints.ListenerBasicSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), EXISTS); assertThat(classId + ".binarySink", metadata.getBinarySink(), equalTo(ByteArrayMessageSink.class)); @@ -376,9 +363,9 @@ public class LocalEndpointMetadataTest @Test public void testListenerFrameSocket() throws Exception { - JettyWebSocketFrameHandlerMetadata metadata = createMetadata(ListenerFrameSocket.class); + JettyWebSocketFrameHandlerMetadata metadata = createMetadata(EndPoints.ListenerFrameSocket.class); - String classId = ListenerFrameSocket.class.getSimpleName(); + String classId = EndPoints.ListenerFrameSocket.class.getSimpleName(); assertThat(classId + ".binaryHandle", metadata.getBinaryHandle(), nullValue()); assertThat(classId + ".binarySink", metadata.getBinarySink(), nullValue()); diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageInputStreamTest.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/MessageInputStreamTest.java similarity index 82% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageInputStreamTest.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/MessageInputStreamTest.java index 84134e2d322..b7fe9197f99 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageInputStreamTest.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/MessageInputStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -26,16 +26,19 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.websocket.common.message.MessageInputStream; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.util.messages.MessageInputStream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTimeout; public class MessageInputStreamTest @@ -166,7 +169,7 @@ public class MessageInputStreamTest { // wait for a little bit before sending input closed TimeUnit.MILLISECONDS.sleep(400); - stream.close(); + stream.accept(new Frame(OpCode.TEXT, true, BufferUtil.EMPTY_BUFFER), Callback.NOOP); } catch (Throwable t) { @@ -177,11 +180,22 @@ public class MessageInputStreamTest // Read byte from stream. int b = stream.read(); - // Should be a -1, indicating the end of the stream. - // Test it + // Should be a -1, indicating the end of the stream. assertThat("Error when closing", hadError.get(), is(false)); assertThat("Initial byte (Should be EOF)", b, is(-1)); + + // Close the stream. + stream.close(); + + // Any frame content after stream is closed should be discarded, and the callback succeeded. + FutureCallback callback = new FutureCallback(); + stream.accept(new Frame(OpCode.TEXT, true, BufferUtil.toBuffer("hello world")), callback); + callback.block(5, TimeUnit.SECONDS); + + // Any read after the stream is closed leads to an IOException. + IOException error = assertThrows(IOException.class, stream::read); + assertThat(error.getMessage(), is("Closed")); } }); } diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageOutputStreamTest.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/MessageOutputStreamTest.java similarity index 69% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageOutputStreamTest.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/MessageOutputStreamTest.java index 55d491b6ef3..f090d20a4de 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/MessageOutputStreamTest.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/MessageOutputStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; @@ -23,12 +23,12 @@ import java.util.Arrays; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.common.message.MessageOutputStream; +import org.eclipse.jetty.websocket.util.messages.MessageOutputStream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.endsWith; @@ -36,7 +36,7 @@ import static org.hamcrest.Matchers.is; public class MessageOutputStreamTest { - private static final Logger LOG = Log.getLogger(MessageOutputStreamTest.class); + private static final Logger LOG = LoggerFactory.getLogger(MessageOutputStreamTest.class); private static final int OUTPUT_BUFFER_SIZE = 4096; public TestableLeakTrackingBufferPool bufferPool = new TestableLeakTrackingBufferPool("Test"); @@ -53,12 +53,13 @@ public class MessageOutputStreamTest public void setupTest() throws Exception { sessionCapture = new OutgoingMessageCapture(); + sessionCapture.setOutputBufferSize(OUTPUT_BUFFER_SIZE); } @Test public void testMultipleWrites() throws Exception { - try (MessageOutputStream stream = new MessageOutputStream(sessionCapture, OUTPUT_BUFFER_SIZE, bufferPool)) + try (MessageOutputStream stream = new MessageOutputStream(sessionCapture, bufferPool)) { stream.write("Hello".getBytes("UTF-8")); stream.write(" ".getBytes("UTF-8")); @@ -74,7 +75,7 @@ public class MessageOutputStreamTest @Test public void testSingleWrite() throws Exception { - try (MessageOutputStream stream = new MessageOutputStream(sessionCapture, OUTPUT_BUFFER_SIZE, bufferPool)) + try (MessageOutputStream stream = new MessageOutputStream(sessionCapture, bufferPool)) { stream.write("Hello World".getBytes("UTF-8")); } @@ -86,7 +87,7 @@ public class MessageOutputStreamTest } @Test - public void testWriteLarge_RequiringMultipleBuffers() throws Exception + public void testWriteLargeRequiringMultipleBuffers() throws Exception { int bufsize = (int)(OUTPUT_BUFFER_SIZE * 2.5); byte[] buf = new byte[bufsize]; @@ -94,7 +95,7 @@ public class MessageOutputStreamTest Arrays.fill(buf, (byte)'x'); buf[bufsize - 1] = (byte)'o'; // mark last entry for debugging - try (MessageOutputStream stream = new MessageOutputStream(sessionCapture, OUTPUT_BUFFER_SIZE, bufferPool)) + try (MessageOutputStream stream = new MessageOutputStream(sessionCapture, bufferPool)) { stream.write(buf); } diff --git a/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/OutgoingMessageCapture.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/OutgoingMessageCapture.java new file mode 100644 index 00000000000..366827f169f --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/OutgoingMessageCapture.java @@ -0,0 +1,176 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.common; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.nio.ByteBuffer; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +import org.eclipse.jetty.toolchain.test.Hex; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CloseStatus; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.util.messages.ByteBufferMessageSink; +import org.eclipse.jetty.websocket.util.messages.MessageSink; +import org.eclipse.jetty.websocket.util.messages.StringMessageSink; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OutgoingMessageCapture extends CoreSession.Empty implements CoreSession +{ + private static final Logger LOG = LoggerFactory.getLogger(OutgoingMessageCapture.class); + + public BlockingQueue textMessages = new LinkedBlockingDeque<>(); + public BlockingQueue binaryMessages = new LinkedBlockingDeque<>(); + public BlockingQueue events = new LinkedBlockingDeque<>(); + + private final MethodHandle wholeTextHandle; + private final MethodHandle wholeBinaryHandle; + private MessageSink messageSink; + private long maxMessageSize = 2 * 1024 * 1024; + + public OutgoingMessageCapture() + { + MethodHandles.Lookup lookup = JettyWebSocketFrameHandlerFactory.getApplicationMethodHandleLookup(this.getClass()); + try + { + MethodHandle text = lookup.findVirtual(this.getClass(), "onWholeText", MethodType.methodType(Void.TYPE, String.class)); + this.wholeTextHandle = text.bindTo(this); + + MethodHandle binary = lookup.findVirtual(this.getClass(), "onWholeBinary", MethodType.methodType(Void.TYPE, ByteBuffer.class)); + this.wholeBinaryHandle = binary.bindTo(this); + } + catch (NoSuchMethodException | IllegalAccessException e) + { + throw new IllegalStateException("Unable to setup OutgoingMessageCapture", e); + } + } + + @Override + public void sendFrame(Frame frame, Callback callback, boolean batch) + { + switch (frame.getOpCode()) + { + case OpCode.CLOSE: + { + CloseStatus closeStatus = new CloseStatus(frame.getPayload()); + String event = String.format("CLOSE:%s:%s", CloseStatus.codeString(closeStatus.getCode()), closeStatus.getReason()); + LOG.debug(event); + events.offer(event); + break; + } + case OpCode.PING: + { + String event = String.format("PING:%s", dataHint(frame.getPayload())); + LOG.debug(event); + events.offer(event); + break; + } + case OpCode.PONG: + { + String event = String.format("PONG:%s", dataHint(frame.getPayload())); + LOG.debug(event); + events.offer(event); + break; + } + case OpCode.TEXT: + { + String event = String.format("TEXT:fin=%b:len=%d", frame.isFin(), frame.getPayloadLength()); + LOG.debug(event); + events.offer(event); + messageSink = new StringMessageSink(this, wholeTextHandle); + break; + } + case OpCode.BINARY: + { + String event = String.format("BINARY:fin=%b:len=%d", frame.isFin(), frame.getPayloadLength()); + LOG.debug(event); + events.offer(event); + messageSink = new ByteBufferMessageSink(this, wholeBinaryHandle); + break; + } + case OpCode.CONTINUATION: + { + String event = String.format("CONTINUATION:fin=%b:len=%d", frame.isFin(), frame.getPayloadLength()); + LOG.debug(event); + events.offer(event); + break; + } + } + + if (OpCode.isDataFrame(frame.getOpCode())) + { + messageSink.accept(Frame.copy(frame), callback); + if (frame.isFin()) + { + messageSink = null; + } + } + else + { + callback.succeeded(); + } + } + + @SuppressWarnings("unused") + public void onWholeText(String msg) + { + this.textMessages.offer(msg); + } + + @SuppressWarnings("unused") + public void onWholeBinary(ByteBuffer buf) + { + ByteBuffer copy = null; + if (buf != null) + { + copy = ByteBuffer.allocate(buf.remaining()); + copy.put(buf); + copy.flip(); + } + this.binaryMessages.offer(copy); + } + + private String dataHint(ByteBuffer payload) + { + if (payload == null) + return ""; + + StringBuilder hint = new StringBuilder(); + hint.append('['); + ByteBuffer sliced = payload.slice(); + if (sliced.remaining() > 20) + { + sliced.limit(20); + hint.append(Hex.asHex(sliced)); + hint.append("..."); + } + else + { + hint.append(Hex.asHex(sliced)); + } + hint.append(']'); + return hint.toString(); + } +} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/TestableLeakTrackingBufferPool.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/TestableLeakTrackingBufferPool.java similarity index 54% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/TestableLeakTrackingBufferPool.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/TestableLeakTrackingBufferPool.java index 564e131a564..5e3f4c16df2 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/TestableLeakTrackingBufferPool.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/TestableLeakTrackingBufferPool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common; diff --git a/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java new file mode 100644 index 00000000000..6a38561e47f --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AdapterEchoSocket.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.common.endpoints.adapters; + +import java.io.IOException; + +import org.eclipse.jetty.websocket.api.WebSocketAdapter; + +/** + * Example EchoSocket using Adapter. + */ +public class AdapterEchoSocket extends WebSocketAdapter +{ + @Override + public void onWebSocketText(String message) + { + if (isConnected()) + { + try + { + System.out.printf("Echoing back message [%s]%n", message); + // echo the message back + getRemote().sendString(message); + } + catch (IOException e) + { + e.printStackTrace(System.err); + } + } + } +} diff --git a/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java new file mode 100644 index 00000000000..d34e8177fe6 --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.common.endpoints.adapters; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +/** + * Example EchoSocket using Annotations. + */ +@WebSocket(maxTextMessageSize = 64 * 1024) +public class AnnotatedEchoSocket +{ + @OnWebSocketMessage + public void onText(Session session, String message) + { + if (session.isOpen()) + { + System.out.printf("Echoing back message [%s]%n", message); + // echo the message back + session.getRemote().sendString(message, null); + } + } +} diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java similarity index 59% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java index 68ec37c57cb..c65d1bf9914 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/endpoints/adapters/ListenerEchoSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common.endpoints.adapters; diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtilsTest.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtilsTest.java similarity index 81% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtilsTest.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtilsTest.java index 3e62ab1c5cb..315d7ee4fe7 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtilsTest.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/InvokerUtilsTest.java @@ -1,29 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common.invoke; import java.io.File; import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.websocket.common.util.ReflectUtils; +import org.eclipse.jetty.websocket.util.InvokerUtils; +import org.eclipse.jetty.websocket.util.ReflectUtils; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -149,11 +151,13 @@ public class InvokerUtilsTest throw new AssertionError("Unable to find method: " + name); } + private static MethodHandles.Lookup lookup = MethodHandles.lookup(); + @Test public void testSimpleInvoker() throws Throwable { Method method = ReflectUtils.findMethod(Simple.class, "onMessage", String.class); - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(Simple.class, method, new InvokerUtils.Arg(String.class)); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, Simple.class, method, new InvokerUtils.Arg(String.class)); Simple simple = new Simple(); String result = (String)methodHandle.invoke(simple, "Hello World"); @@ -170,7 +174,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle2 = InvokerUtils.mutatedInvoker(KeyValue.class, method2, callingArgs); + MethodHandle methodHandle2 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method2, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle2.invoke(obj, "Year", 1972); @@ -187,7 +191,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, "Age", 45); @@ -195,7 +199,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_AtEnd() throws Throwable + public void testKeyValueExtraArgsAtEnd() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -205,7 +209,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(Boolean.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, "Age", 45, Boolean.TRUE); @@ -213,7 +217,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_InMiddle() throws Throwable + public void testKeyValueExtraArgsInMiddle() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -223,7 +227,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, "Year", 888888L, 2017); @@ -231,7 +235,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_AtStart() throws Throwable + public void testKeyValueExtraArgsAtStart() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -241,7 +245,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, new Simple(), "Count", 1776); @@ -249,7 +253,7 @@ public class InvokerUtilsTest } @Test - public void testKeyValue_ExtraArgs_Mixed() throws Throwable + public void testKeyValueExtraArgsMixed() throws Throwable { Method method1 = ReflectUtils.findMethod(KeyValue.class, "onEntry", String.class, int.class); @@ -261,7 +265,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(Long.class) }; - MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(KeyValue.class, method1, callingArgs); + MethodHandle methodHandle1 = InvokerUtils.mutatedInvoker(lookup, KeyValue.class, method1, callingArgs); KeyValue obj = new KeyValue(); String result = (String)methodHandle1.invoke(obj, new Simple(), "Amount", Boolean.TRUE, 200, 9999L); @@ -269,7 +273,7 @@ public class InvokerUtilsTest } @Test - public void testNamed_AllParams() throws Throwable + public void testNamedAllParams() throws Throwable { Method method = ReflectUtils.findMethod(NamedParams.class, "onMessage", String.class, String.class, int.class); @@ -279,7 +283,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(int.class, "cost") }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(NamedParams.class, method, new NameParamIdentifier(), callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, NamedParams.class, method, new NameParamIdentifier(), null, callingArgs); NamedParams obj = new NamedParams(); String result = (String)methodHandle.invoke(obj, "Apple", "Red", 10); @@ -287,7 +291,7 @@ public class InvokerUtilsTest } @Test - public void testNamed_AllParams_Mixed() throws Throwable + public void testNamedAllParamsMixed() throws Throwable { Method method = ReflectUtils.findMethod(NamedParams.class, "onMessage", String.class, String.class, int.class); @@ -297,7 +301,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class, "color") }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(NamedParams.class, method, new NameParamIdentifier(), callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, NamedParams.class, method, new NameParamIdentifier(), null, callingArgs); NamedParams obj = new NamedParams(); String result = (String)methodHandle.invoke(obj, 20, "Banana", "Yellow"); @@ -305,20 +309,20 @@ public class InvokerUtilsTest } @Test - public void testEmpty_Call_None() throws Throwable + public void testEmptyCallNone() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigEmpty"); InvokerUtils.Arg[] callingArgs = new InvokerUtils.Arg[]{}; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples); assertThat("Result", result, is("sigEmpty<>")); } @Test - public void testEmpty_Call_File() throws Throwable + public void testEmptyCallFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigEmpty"); @@ -327,13 +331,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus")); assertThat("Result", result, is("sigEmpty<>")); } @Test - public void testEmpty_Call_NullFile() throws Throwable + public void testEmptyCallNullFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigEmpty"); @@ -342,13 +346,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, null); assertThat("Result", result, is("sigEmpty<>")); } @Test - public void testString_Call_String() throws Throwable + public void testStringCallString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStr"); @@ -357,13 +361,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Hello"); assertThat("Result", result, is("sigStr")); } @Test - public void testString_Call_File_String() throws Throwable + public void testStringCallFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStr"); @@ -373,13 +377,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus"), "Hiya"); assertThat("Result", result, is("sigStr")); } @Test - public void testString_Call_String_File() throws Throwable + public void testStringCallStringFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStr"); @@ -389,13 +393,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Greetings", new File("bogus")); assertThat("Result", result, is("sigStr")); } @Test - public void testStringFile_Call_String_File() throws Throwable + public void testStringFileCallStringFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStrFile"); @@ -405,13 +409,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Name", new File("bogus1")); assertThat("Result", result, is("sigStrFile")); } @Test - public void testStringFile_Call_File_String() throws Throwable + public void testStringFileCallFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigStrFile"); @@ -421,13 +425,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus2"), "Alt"); assertThat("Result", result, is("sigStrFile")); } @Test - public void testFileString_Call_String_File() throws Throwable + public void testFileStringCallStringFile() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStr"); @@ -437,13 +441,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(File.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, "Bob", new File("bogus3")); assertThat("Result", result, is("sigFileStr")); } @Test - public void testFileString_Call_File_String() throws Throwable + public void testFileStringCallFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStr"); @@ -453,13 +457,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("bogus4"), "Dobalina"); assertThat("Result", result, is("sigFileStr")); } @Test - public void testFileStringFin_Call_File_String_BoolTag() throws Throwable + public void testFileStringFinCallFileStringBoolTag() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -470,13 +474,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(boolean.class, "fin") }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, new NameParamIdentifier(), callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); String result = (String)methodHandle.invoke(samples, new File("foo"), "bar", true); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_File_String_Bool() throws Throwable + public void testFileStringFinCallFileStringBool() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -487,13 +491,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(boolean.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, new File("baz"), "flem", false); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_BoolTag_File_String() throws Throwable + public void testFileStringFinCallBoolTagFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -504,13 +508,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, new NameParamIdentifier(), callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); String result = (String)methodHandle.invoke(samples, false, new File("foo"), "bar"); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_Bool_File_String() throws Throwable + public void testFileStringFinCallBoolFileString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -521,13 +525,13 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, callingArgs); String result = (String)methodHandle.invoke(samples, true, new File("foo"), "bar"); assertThat("Result", result, is("sigFileStrFin")); } @Test - public void testFileStringFin_Call_BoolTag_Null_String() throws Throwable + public void testFileStringFinCallBoolTagNullString() throws Throwable { SampleSignatures samples = new SampleSignatures(); Method method = findMethodByName(samples, "sigFileStrFin"); @@ -538,7 +542,7 @@ public class InvokerUtilsTest new InvokerUtils.Arg(String.class) }; - MethodHandle methodHandle = InvokerUtils.mutatedInvoker(SampleSignatures.class, method, new NameParamIdentifier(), callingArgs); + MethodHandle methodHandle = InvokerUtils.mutatedInvoker(lookup, SampleSignatures.class, method, new NameParamIdentifier(), null, callingArgs); String result = (String)methodHandle.invoke(samples, true, null, "bar"); assertThat("Result", result, is("sigFileStrFin<,bar,true>")); } diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/NameParamIdentifier.java b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/NameParamIdentifier.java similarity index 51% rename from jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/NameParamIdentifier.java rename to jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/NameParamIdentifier.java index ff2e49181ff..5caedfa43cb 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/NameParamIdentifier.java +++ b/jetty-websocket/websocket-jetty-common/src/test/java/org/eclipse/jetty/websocket/common/invoke/NameParamIdentifier.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.common.invoke; @@ -22,9 +22,10 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.eclipse.jetty.util.annotation.Name; +import org.eclipse.jetty.websocket.util.InvokerUtils; /** - * Simple {@link org.eclipse.jetty.websocket.common.invoke.InvokerUtils.ParamIdentifier} + * Simple {@link InvokerUtils.ParamIdentifier} * that observes {@link Name} tagged method parameters. */ public class NameParamIdentifier implements InvokerUtils.ParamIdentifier diff --git a/jetty-websocket/websocket-jetty-common/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-jetty-common/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..376b9b6babb --- /dev/null +++ b/jetty-websocket/websocket-jetty-common/src/test/resources/jetty-logging.properties @@ -0,0 +1 @@ +# Jetty Logging using jetty-slf4j-impl diff --git a/jetty-websocket/jetty-websocket-server/pom.xml b/jetty-websocket/websocket-jetty-server/pom.xml similarity index 87% rename from jetty-websocket/jetty-websocket-server/pom.xml rename to jetty-websocket/websocket-jetty-server/pom.xml index 80303e8640b..811fa6c6f89 100644 --- a/jetty-websocket/jetty-websocket-server/pom.xml +++ b/jetty-websocket/websocket-jetty-server/pom.xml @@ -7,7 +7,7 @@ 4.0.0 - jetty-websocket-server + websocket-jetty-server Jetty :: Websocket :: org.eclipse.jetty.websocket :: Server @@ -38,12 +38,12 @@ org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api ${project.version} org.eclipse.jetty.websocket - jetty-websocket-common + websocket-jetty-common ${project.version} @@ -55,6 +55,15 @@ org.eclipse.jetty.toolchain jetty-servlet-api + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-websocket/websocket-jetty-server/src/main/config/modules/websocket-jetty.mod b/jetty-websocket/websocket-jetty-server/src/main/config/modules/websocket-jetty.mod new file mode 100644 index 00000000000..1f3f6189a64 --- /dev/null +++ b/jetty-websocket/websocket-jetty-server/src/main/config/modules/websocket-jetty.mod @@ -0,0 +1,24 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Enable the Jetty WebSocket API for deployed web applications. + +[tags] +websocket + +[depend] +client +annotations + +[lib] +lib/websocket/websocket-core-${jetty.version}.jar +lib/websocket/websocket-servlet-${jetty.version}.jar +lib/websocket/websocket-util-${jetty.version}.jar +lib/websocket/websocket-jetty-api-${jetty.version}.jar +lib/websocket/websocket-jetty-common-${jetty.version}.jar +lib/websocket/websocket-jetty-server-${jetty.version}.jar + +[jpms] +# The implementation needs to access method handles in +# classes that are in the web application classloader. +add-reads: org.eclipse.jetty.websocket.jetty.common=ALL-UNNAMED diff --git a/jetty-websocket/websocket-jetty-server/src/main/java/module-info.java b/jetty-websocket/websocket-jetty-server/src/main/java/module-info.java new file mode 100644 index 00000000000..9686cfd3f61 --- /dev/null +++ b/jetty-websocket/websocket-jetty-server/src/main/java/module-info.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +import javax.servlet.ServletContainerInitializer; + +import org.eclipse.jetty.webapp.Configuration; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; + +module org.eclipse.jetty.websocket.jetty.server +{ + exports org.eclipse.jetty.websocket.server; + exports org.eclipse.jetty.websocket.server.config; + + requires jetty.servlet.api; + requires org.eclipse.jetty.websocket.jetty.common; + requires transitive org.eclipse.jetty.webapp; + requires transitive org.eclipse.jetty.websocket.jetty.api; + requires transitive org.eclipse.jetty.websocket.servlet; + requires org.slf4j; + + // Only required if using JMX. + requires static org.eclipse.jetty.jmx; + + provides ServletContainerInitializer with JettyWebSocketServletContainerInitializer; + provides Configuration with JettyWebSocketConfiguration; +} diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeRequest.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeRequest.java similarity index 90% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeRequest.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeRequest.java index 0a9c0872513..052b458c95f 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeRequest.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server; diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeResponse.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeResponse.java similarity index 77% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeResponse.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeResponse.java index 1933ede2809..dcd144613a0 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeResponse.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyServerUpgradeResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server; diff --git a/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketCreator.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketCreator.java new file mode 100644 index 00000000000..af7c3e7bb18 --- /dev/null +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketCreator.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.server; + +/** + * Abstract WebSocket creator interface. + *

        + * Should you desire filtering of the WebSocket object creation due to criteria such as origin or sub-protocol, then you will be required to implement a custom + * WebSocketCreator implementation. + *

        + */ +public interface JettyWebSocketCreator +{ + /** + * Create a websocket from the incoming request. + * + * @param req the request details + * @param resp the response details + * @return a websocket object to use, or null if no websocket should be created from this request. + */ + Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp); +} diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServerContainer.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServerContainer.java similarity index 79% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServerContainer.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServerContainer.java index b6b7938f11f..faf36ac1a02 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServerContainer.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServerContainer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server; @@ -30,21 +30,21 @@ import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketBehavior; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.WebSocketSessionListener; import org.eclipse.jetty.websocket.common.SessionTracker; -import org.eclipse.jetty.websocket.common.WebSocketContainer; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.server.internal.JettyServerFrameHandlerFactory; import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory; import org.eclipse.jetty.websocket.servlet.WebSocketMapping; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JettyWebSocketServerContainer extends ContainerLifeCycle implements WebSocketContainer, WebSocketPolicy, LifeCycle.Listener { @@ -76,19 +76,19 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements WebSocketComponents.ensureWebSocketComponents(servletContext), executor); servletContext.setAttribute(JETTY_WEBSOCKET_CONTAINER_ATTRIBUTE, container); contextHandler.addManaged(container); - contextHandler.addLifeCycleListener(container); + contextHandler.addEventListener(container); } return container; } - private static final Logger LOG = Log.getLogger(JettyWebSocketServerContainer.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketServerContainer.class); private final WebSocketMapping webSocketMapping; private final WebSocketComponents webSocketComponents; private final FrameHandlerFactory frameHandlerFactory; private final Executor executor; - private final FrameHandler.ConfigurationCustomizer customizer = new FrameHandler.ConfigurationCustomizer(); + private final Configuration.ConfigurationCustomizer customizer = new Configuration.ConfigurationCustomizer(); private final List sessionListeners = new ArrayList<>(); private final SessionTracker sessionTracker = new SessionTracker(); @@ -112,7 +112,7 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements { factory = new JettyServerFrameHandlerFactory(this); contextHandler.addManaged(factory); - contextHandler.addLifeCycleListener(factory); + contextHandler.addEventListener(factory); } frameHandlerFactory = factory; @@ -206,6 +206,18 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements return customizer.getMaxTextMessageSize(); } + @Override + public long getMaxFrameSize() + { + return customizer.getMaxFrameSize(); + } + + @Override + public boolean isAutoFragment() + { + return customizer.isAutoFragment(); + } + @Override public void setIdleTimeout(Duration duration) { @@ -235,4 +247,16 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements { customizer.setMaxTextMessageSize(size); } + + @Override + public void setMaxFrameSize(long maxFrameSize) + { + customizer.setMaxFrameSize(maxFrameSize); + } + + @Override + public void setAutoFragment(boolean autoFragment) + { + customizer.setAutoFragment(autoFragment); + } } diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServlet.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServlet.java similarity index 56% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServlet.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServlet.java index 2731cb63bef..b2880acbb31 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServlet.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server; diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java similarity index 76% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java index 0c424b494d0..c27d5245bca 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/JettyWebSocketServletFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server; @@ -22,7 +22,6 @@ import java.time.Duration; import java.util.Set; import org.eclipse.jetty.http.pathmap.PathSpec; -import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; @@ -50,44 +49,25 @@ public class JettyWebSocketServletFactory implements WebSocketPolicy return WebSocketBehavior.SERVER; } - /** - * If true, frames are automatically fragmented to respect the maximum frame size. - * - * @return whether to automatically fragment incoming WebSocket Frames. - */ + @Override public boolean isAutoFragment() { return factory.isAutoFragment(); } - /** - * If set to true, frames are automatically fragmented to respect the maximum frame size. - * - * @param autoFragment whether to automatically fragment incoming WebSocket Frames. - */ + @Override public void setAutoFragment(boolean autoFragment) { factory.setAutoFragment(autoFragment); } - /** - * The maximum payload size of any WebSocket Frame which can be received. - * - * @return the maximum size of a WebSocket Frame. - */ + @Override public long getMaxFrameSize() { return factory.getMaxFrameSize(); } - /** - * The maximum payload size of any WebSocket Frame which can be received. - *

        - * WebSocket Frames over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE} - *

        - * - * @param maxFrameSize the maximum allowed size of a WebSocket Frame. - */ + @Override public void setMaxFrameSize(long maxFrameSize) { factory.setMaxFrameSize(maxFrameSize); diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketConfiguration.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketConfiguration.java similarity index 71% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketConfiguration.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketConfiguration.java index c6c095c5f27..c0a54dddef8 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketConfiguration.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.config; @@ -21,8 +21,6 @@ package org.eclipse.jetty.websocket.server.config; import java.util.ServiceLoader; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.FragmentConfiguration; @@ -30,6 +28,8 @@ import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppConfiguration; import org.eclipse.jetty.webapp.WebInfConfiguration; import org.eclipse.jetty.webapp.WebXmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

        Websocket Configuration

        @@ -43,7 +43,7 @@ import org.eclipse.jetty.webapp.WebXmlConfiguration; */ public class JettyWebSocketConfiguration extends AbstractConfiguration { - private static final Logger LOG = Log.getLogger(JettyWebSocketConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketConfiguration.class); public JettyWebSocketConfiguration() { @@ -78,7 +78,7 @@ public class JettyWebSocketConfiguration extends AbstractConfiguration } catch (Throwable e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); return false; } } diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java similarity index 78% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java index 6e817fed257..82c3f79383a 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.config; @@ -25,19 +25,19 @@ import javax.servlet.ServletContext; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.listener.ContainerInitializer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer; import org.eclipse.jetty.websocket.servlet.WebSocketMapping; import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ServletContext configuration for Jetty Native WebSockets API. */ public class JettyWebSocketServletContainerInitializer implements ServletContainerInitializer { - private static final Logger LOG = Log.getLogger(JettyWebSocketServletContainerInitializer.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketServletContainerInitializer.class); public interface Configurator { @@ -87,7 +87,7 @@ public class JettyWebSocketServletContainerInitializer implements ServletContain * @param context the context to work with * @return the default {@link JettyWebSocketServerContainer} */ - public static JettyWebSocketServerContainer initialize(ServletContextHandler context) + private static JettyWebSocketServerContainer initialize(ServletContextHandler context) { WebSocketComponents components = WebSocketComponents.ensureWebSocketComponents(context.getServletContext()); FilterHolder filterHolder = WebSocketUpgradeFilter.ensureFilter(context.getServletContext()); diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/JettyServerFrameHandlerFactory.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/JettyServerFrameHandlerFactory.java similarity index 71% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/JettyServerFrameHandlerFactory.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/JettyServerFrameHandlerFactory.java index 4262fe00299..6c3acd2ea91 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/JettyServerFrameHandlerFactory.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/JettyServerFrameHandlerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.internal; @@ -23,9 +23,9 @@ import javax.servlet.ServletContext; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler; import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory; -import org.eclipse.jetty.websocket.common.WebSocketContainer; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java similarity index 79% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java index 57a69c63b62..fb72a261005 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.internal; @@ -197,24 +197,6 @@ public class UpgradeRequestAdapter implements UpgradeRequest throw new UnsupportedOperationException("Not supported from Servlet API"); } - @Override - public void setHttpVersion(String httpVersion) - { - throw new UnsupportedOperationException("Not supported from Servlet API"); - } - - @Override - public void setMethod(String method) - { - throw new UnsupportedOperationException("Not supported from Servlet API"); - } - - @Override - public void setRequestURI(URI uri) - { - throw new UnsupportedOperationException("Not supported from Servlet API"); - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeResponseAdapter.java b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeResponseAdapter.java similarity index 78% rename from jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeResponseAdapter.java rename to jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeResponseAdapter.java index c3de87cac3c..4e9eefed389 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeResponseAdapter.java +++ b/jetty-websocket/websocket-jetty-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeResponseAdapter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.internal; diff --git a/jetty-websocket/jetty-websocket-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/jetty-websocket/websocket-jetty-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer similarity index 100% rename from jetty-websocket/jetty-websocket-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer rename to jetty-websocket/websocket-jetty-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer diff --git a/jetty-websocket/jetty-websocket-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration b/jetty-websocket/websocket-jetty-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration similarity index 100% rename from jetty-websocket/jetty-websocket-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration rename to jetty-websocket/websocket-jetty-server/src/main/resources/META-INF/services/org.eclipse.jetty.webapp.Configuration diff --git a/jetty-websocket/jetty-websocket-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserDebugTool.java b/jetty-websocket/websocket-jetty-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserDebugTool.java similarity index 84% rename from jetty-websocket/jetty-websocket-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserDebugTool.java rename to jetty-websocket/websocket-jetty-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserDebugTool.java index fd15de1cef5..88ea1275982 100644 --- a/jetty-websocket/jetty-websocket-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserDebugTool.java +++ b/jetty-websocket/websocket-jetty-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserDebugTool.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.browser; @@ -35,8 +35,6 @@ import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; @@ -46,6 +44,8 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Tool to help debug websocket circumstances reported around browsers. @@ -55,7 +55,7 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI */ public class BrowserDebugTool { - private static final Logger LOG = Log.getLogger(BrowserDebugTool.class); + private static final Logger LOG = LoggerFactory.getLogger(BrowserDebugTool.class); public static void main(String[] args) { @@ -78,7 +78,7 @@ public class BrowserDebugTool } catch (Throwable t) { - LOG.warn(t); + LOG.warn("Unable to start {}", BrowserDebugTool.class.getName(), t); } } @@ -93,6 +93,12 @@ public class BrowserDebugTool public void prepare(int port) { server = new Server(); + + // Setup JMX + // MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); + // server.addBean(mbContainer, true); + + // Setup Connector connector = new ServerConnector(server); connector.setPort(port); server.addConnector(connector); diff --git a/jetty-websocket/jetty-websocket-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserSocket.java b/jetty-websocket/websocket-jetty-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserSocket.java similarity index 90% rename from jetty-websocket/jetty-websocket-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserSocket.java rename to jetty-websocket/websocket-jetty-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserSocket.java index 848e92a6f47..14264e68a22 100644 --- a/jetty-websocket/jetty-websocket-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserSocket.java +++ b/jetty-websocket/websocket-jetty-server/src/test/java/org/eclipse/jetty/websocket/server/browser/BrowserSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.server.browser; @@ -33,8 +33,6 @@ import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; @@ -42,6 +40,8 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @WebSocket public class BrowserSocket @@ -81,7 +81,7 @@ public class BrowserSocket } } - private static final Logger LOG = Log.getLogger(BrowserSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(BrowserSocket.class); private Session session; private final String userAgent; @@ -198,7 +198,7 @@ public class BrowserSocket } catch (IOException e) { - LOG.warn(e); + LOG.warn("Unable to send ping", e); } break; } diff --git a/jetty-websocket/jetty-websocket-server/src/test/resources/browser-debug-tool/index.html b/jetty-websocket/websocket-jetty-server/src/test/resources/browser-debug-tool/index.html similarity index 100% rename from jetty-websocket/jetty-websocket-server/src/test/resources/browser-debug-tool/index.html rename to jetty-websocket/websocket-jetty-server/src/test/resources/browser-debug-tool/index.html diff --git a/jetty-websocket/jetty-websocket-server/src/test/resources/browser-debug-tool/main.css b/jetty-websocket/websocket-jetty-server/src/test/resources/browser-debug-tool/main.css similarity index 100% rename from jetty-websocket/jetty-websocket-server/src/test/resources/browser-debug-tool/main.css rename to jetty-websocket/websocket-jetty-server/src/test/resources/browser-debug-tool/main.css diff --git a/jetty-websocket/jetty-websocket-server/src/test/resources/browser-debug-tool/websocket.js b/jetty-websocket/websocket-jetty-server/src/test/resources/browser-debug-tool/websocket.js similarity index 100% rename from jetty-websocket/jetty-websocket-server/src/test/resources/browser-debug-tool/websocket.js rename to jetty-websocket/websocket-jetty-server/src/test/resources/browser-debug-tool/websocket.js diff --git a/jetty-websocket/websocket-jetty-tests/fuzzingclient.json b/jetty-websocket/websocket-jetty-tests/fuzzingclient.json new file mode 100644 index 00000000000..fbe1ce7e85e --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/fuzzingclient.json @@ -0,0 +1,18 @@ +{ + "options": { + "failByDrop": false + }, + "outdir": "./target/reports/servers", + "servers": [ + { + "agent": "Jetty-10.0.0-SNAPSHOT", + "url": "ws://127.0.0.1:9001", + "options": { + "version": 18 + } + } + ], + "cases": ["*"], + "exclude-cases": [], + "exclude-agent-cases": {} +} diff --git a/jetty-websocket/websocket-jetty-tests/fuzzingserver.json b/jetty-websocket/websocket-jetty-tests/fuzzingserver.json new file mode 100644 index 00000000000..ade31281937 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/fuzzingserver.json @@ -0,0 +1,10 @@ +{ + "options": { + "failByDrop": false + }, + "url": "ws://127.0.0.1:9001", + "outdir": "./target/reports/clients", + "cases": ["*"], + "exclude-cases": [], + "exclude-agent-cases": {} +} diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/websocket-jetty-tests/pom.xml similarity index 51% rename from jetty-websocket/jetty-websocket-tests/pom.xml rename to jetty-websocket/websocket-jetty-tests/pom.xml index bfd1689a5d7..b59c57ef428 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/websocket-jetty-tests/pom.xml @@ -7,42 +7,95 @@ 4.0.0 - jetty-websocket-tests + websocket-jetty-tests Jetty :: Websocket :: org.eclipse.jetty.websocket :: Tests - ${project.groupId}.jetty.websocket.tests + ${project.groupId}.tests - org.eclipse.jetty.websocket - jetty-websocket-api - ${project.version} + org.slf4j + slf4j-api + test org.eclipse.jetty.websocket - jetty-websocket-client + websocket-jetty-api ${project.version} + test org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-client ${project.version} + test + + + org.eclipse.jetty.websocket + websocket-jetty-server + ${project.version} + test org.eclipse.jetty.tests jetty-http-tools ${project.version} + test - org.eclipse.jetty.toolchain - jetty-test-helper - compile + org.eclipse.jetty.http2 + http2-server + ${project.version} + test + + + org.eclipse.jetty + jetty-alpn-server + ${project.version} + test + + + org.eclipse.jetty + jetty-alpn-java-server + ${project.version} + test + + + org.eclipse.jetty.http2 + http2-http-client-transport + ${project.version} + test + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + + org.apache.maven.plugins + maven-deploy-plugin + + + true + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + true + + + + org.apache.felix diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/AnnoMaxMessageEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/AnnoMaxMessageEndpoint.java new file mode 100644 index 00000000000..3238cce22b0 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/AnnoMaxMessageEndpoint.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +@SuppressWarnings("unused") +@WebSocket(maxTextMessageSize = 100 * 1024) +public class AnnoMaxMessageEndpoint +{ + @OnWebSocketMessage + public void onMessage(Session session, String msg) throws IOException + { + session.getRemote().sendString(msg); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/CloseTrackingEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/CloseTrackingEndpoint.java similarity index 75% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/CloseTrackingEndpoint.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/CloseTrackingEndpoint.java index ac308f95b5d..1a7a2f306e6 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/CloseTrackingEndpoint.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/CloseTrackingEndpoint.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; +import java.nio.ByteBuffer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -25,14 +26,14 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.hamcrest.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; @@ -41,7 +42,7 @@ import static org.hamcrest.Matchers.nullValue; public class CloseTrackingEndpoint extends WebSocketAdapter { - private static final Logger LOG = Log.getLogger(CloseTrackingEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(CloseTrackingEndpoint.class); public int closeCode = -1; public String closeReason = null; @@ -51,6 +52,7 @@ public class CloseTrackingEndpoint extends WebSocketAdapter public CountDownLatch errorLatch = new CountDownLatch(1); public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue binaryMessageQueue = new LinkedBlockingQueue<>(); public AtomicReference error = new AtomicReference<>(); public void assertReceivedCloseEvent(int clientTimeoutMs, Matcher statusCodeMatcher) @@ -114,6 +116,13 @@ public class CloseTrackingEndpoint extends WebSocketAdapter messageQueue.offer(message); } + @Override + public void onWebSocketBinary(byte[] payload, int offset, int len) + { + LOG.debug("onWebSocketBinary({},offset,len)", payload, offset, len); + binaryMessageQueue.offer(ByteBuffer.wrap(payload, offset, len)); + } + public EndPoint getEndPoint() { Session session = getSession(); diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java similarity index 82% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java index bbec94336c6..d0cb78f7884 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; @@ -64,7 +64,8 @@ public class ConcurrentConnectTest ServletContextHandler context = new ServletContextHandler(); context.setContextPath("/"); - JettyWebSocketServlet servlet = new JettyWebSocketServlet() { + JettyWebSocketServlet servlet = new JettyWebSocketServlet() + { @Override protected void configure(JettyWebSocketServletFactory factory) { @@ -134,11 +135,6 @@ public class ConcurrentConnectTest } closeListener.closeLatch.await(5, TimeUnit.SECONDS); - for (EventSocket l : listeners) - { - assertTrue(((WebSocketSession)l.session).isStopped()); - } - assertTrue(client.getOpenSessions().isEmpty()); assertTrue(client.getContainedBeans(WebSocketSession.class).isEmpty()); } diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConnectMessageEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConnectMessageEndpoint.java new file mode 100644 index 00000000000..92c306cc07d --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConnectMessageEndpoint.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +@SuppressWarnings("unused") +@WebSocket +public class ConnectMessageEndpoint +{ + @OnWebSocketConnect + public void onConnect(Session session) throws IOException + { + session.getRemote().sendString("Greeting from onConnect"); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoCreator.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoCreator.java new file mode 100644 index 00000000000..fff616ad83d --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoCreator.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; +import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; +import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; + +public class EchoCreator implements JettyWebSocketCreator +{ + @Override + public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) + { + if (req.hasSubProtocol("echo")) + { + resp.setAcceptedSubProtocol("echo"); + } + + return new EchoSocket(); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoSocket.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoSocket.java new file mode 100644 index 00000000000..0b9e643c072 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EchoSocket.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.eclipse.jetty.websocket.api.WriteCallback; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +@SuppressWarnings("unused") +@WebSocket +public class EchoSocket extends EventSocket +{ + @Override + public void onMessage(String message) throws IOException + { + super.onMessage(message); + session.getRemote().sendString(message); + } + + @Override + public void onMessage(byte[] buf, int offset, int len) + { + super.onMessage(buf, offset, len); + session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len), WriteCallback.NOOP); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ErrorCloseTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ErrorCloseTest.java new file mode 100644 index 00000000000..0e077b8d7ff --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ErrorCloseTest.java @@ -0,0 +1,277 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; +import java.net.URI; +import java.time.Duration; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.servlet.DispatcherType; + +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketSessionListener; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.WebSocketSession; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ErrorCloseTest +{ + private Server server = new Server(); + private WebSocketClient client = new WebSocketClient(); + private ThrowingSocket serverSocket = new ThrowingSocket(); + private CountDownLatch serverCloseListener = new CountDownLatch(1); + private ServerConnector connector; + private URI serverUri; + + @BeforeEach + public void start() throws Exception + { + connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + contextHandler.addFilter(WebSocketUpgradeFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); + JettyWebSocketServletContainerInitializer.configure(contextHandler, (context, container) -> + { + container.addMapping("/", (req, resp) -> serverSocket); + container.addSessionListener(new WebSocketSessionListener() + { + @Override + public void onWebSocketSessionClosed(Session session) + { + serverCloseListener.countDown(); + } + }); + }); + server.setHandler(contextHandler); + + server.start(); + client.start(); + serverUri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + @WebSocket + public static class ThrowingSocket extends EventSocket + { + public List methodsToThrow = new ArrayList<>(); + + @Override + public void onOpen(Session session) + { + super.onOpen(session); + if (methodsToThrow.contains("onOpen")) + throw new RuntimeException("throwing from onOpen"); + } + + @Override + public void onMessage(String message) throws IOException + { + super.onMessage(message); + if (methodsToThrow.contains("onMessage")) + throw new RuntimeException("throwing from onMessage"); + } + + @Override + public void onClose(int statusCode, String reason) + { + super.onClose(statusCode, reason); + if (methodsToThrow.contains("onClose")) + throw new RuntimeException("throwing from onClose"); + } + + @Override + public void onError(Throwable cause) + { + super.onError(cause); + if (methodsToThrow.contains("onError")) + throw new RuntimeException("throwing from onError"); + } + } + + @Test + public void testOnOpenThrows() throws Exception + { + serverSocket.methodsToThrow.add("onOpen"); + EventSocket clientSocket = new EventSocket(); + + try (StacklessLogging stacklessLogging = new StacklessLogging(WebSocketCoreSession.class)) + { + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverSocket.error.getMessage(), containsString("throwing from onOpen")); + } + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } + + @Test + public void testOnMessageThrows() throws Exception + { + serverSocket.methodsToThrow.add("onMessage"); + EventSocket clientSocket = new EventSocket(); + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + clientSocket.session.getRemote().sendString("trigger onMessage error"); + + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverSocket.error.getMessage(), is("throwing from onMessage")); + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } + + @ParameterizedTest + @ValueSource(strings = {"onError", "onClose"}) + public void testWebSocketThrowsAfterOnOpenError(String methodToThrow) throws Exception + { + serverSocket.methodsToThrow.add("onOpen"); + serverSocket.methodsToThrow.add(methodToThrow); + EventSocket clientSocket = new EventSocket(); + + try (StacklessLogging ignored = new StacklessLogging(WebSocketSession.class)) + { + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + } + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } + + @ParameterizedTest + @ValueSource(strings = {"onError", "onClose"}) + public void testWebSocketThrowsAfterOnMessageError(String methodToThrow) throws Exception + { + serverSocket.methodsToThrow.add("onMessage"); + serverSocket.methodsToThrow.add(methodToThrow); + EventSocket clientSocket = new EventSocket(); + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + + try (StacklessLogging ignored = new StacklessLogging(WebSocketSession.class)) + { + clientSocket.session.getRemote().sendString("trigger onMessage error"); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + } + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } + + @ParameterizedTest + @ValueSource(strings = {"onError", "onClose"}) + public void testWebSocketThrowsOnTimeout(String methodToThrow) throws Exception + { + serverSocket.methodsToThrow.add(methodToThrow); + EventSocket clientSocket = new EventSocket(); + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + + // Set a short idleTimeout on the server. + assertTrue(serverSocket.openLatch.await(5, TimeUnit.SECONDS)); + serverSocket.session.setIdleTimeout(Duration.ofSeconds(1)); + + // Wait for server to timeout. + try (StacklessLogging ignored = new StacklessLogging(WebSocketSession.class)) + { + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + } + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } + + @ParameterizedTest + @ValueSource(strings = {"onError", "onClose"}) + public void testWebSocketThrowsOnRemoteDisconnect(String methodToThrow) throws Exception + { + serverSocket.methodsToThrow.add(methodToThrow); + EventSocket clientSocket = new EventSocket(); + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + + try (StacklessLogging ignored = new StacklessLogging(WebSocketSession.class)) + { + clientSocket.session.disconnect(); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + } + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } + + @ParameterizedTest + @ValueSource(strings = {"onError", "onClose"}) + public void testWebSocketThrowsOnLocalDisconnect(String methodToThrow) throws Exception + { + serverSocket.methodsToThrow.add(methodToThrow); + EventSocket clientSocket = new EventSocket(); + client.connect(clientSocket, serverUri).get(5, TimeUnit.SECONDS); + + try (StacklessLogging ignored = new StacklessLogging(WebSocketSession.class)) + { + serverSocket.session.disconnect(); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + } + + // Check we have stopped the WebSocketSession properly. + assertFalse(serverSocket.session.isOpen()); + serverCloseListener.await(5, TimeUnit.SECONDS); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java similarity index 60% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java index ae660da1c09..69d3fcb9e71 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; @@ -24,8 +24,6 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import org.eclipse.jetty.util.BlockingArrayQueue; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; @@ -33,11 +31,13 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @WebSocket public class EventSocket { - private static final Logger LOG = Log.getLogger(EventSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(EventSocket.class); public Session session; private String behavior; @@ -57,29 +57,33 @@ public class EventSocket { this.session = session; behavior = session.getPolicy().getBehavior().name(); - LOG.info("{} onOpen(): {}", toString(), session); + if (LOG.isDebugEnabled()) + LOG.debug("{} onOpen(): {}", toString(), session); openLatch.countDown(); } @OnWebSocketMessage public void onMessage(String message) throws IOException { - LOG.info("{} onMessage(): {}", toString(), message); + if (LOG.isDebugEnabled()) + LOG.debug("{} onMessage(): {}", toString(), message); messageQueue.offer(message); } @OnWebSocketMessage - public void onMessage(byte buf[], int offset, int len) + public void onMessage(byte[] buf, int offset, int len) { ByteBuffer message = ByteBuffer.wrap(buf, offset, len); - LOG.info("{} onMessage(): {}", toString(), message); + if (LOG.isDebugEnabled()) + LOG.debug("{} onMessage(): {}", toString(), message); binaryMessageQueue.offer(message); } @OnWebSocketClose public void onClose(int statusCode, String reason) { - LOG.info("{} onClose(): {}:{}", toString(), statusCode, reason); + if (LOG.isDebugEnabled()) + LOG.debug("{} onClose(): {}:{}", toString(), statusCode, reason); this.statusCode = statusCode; this.reason = reason; closeLatch.countDown(); @@ -88,7 +92,8 @@ public class EventSocket @OnWebSocketError public void onError(Throwable cause) { - LOG.info("{} onError(): {}", toString(), cause); + if (LOG.isDebugEnabled()) + LOG.debug("{} onError(): {}", toString(), cause); error = cause; errorLatch.countDown(); } diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/GetAuthHeaderEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/GetAuthHeaderEndpoint.java new file mode 100644 index 00000000000..b08a943fc6a --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/GetAuthHeaderEndpoint.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +@SuppressWarnings("unused") +@WebSocket +public class GetAuthHeaderEndpoint +{ + @OnWebSocketConnect + public void onConnect(Session session) throws IOException + { + String authHeaderName = "Authorization"; + String authHeaderValue = session.getUpgradeRequest().getHeader(authHeaderName); + session.getRemote().sendString("Header[" + authHeaderName + "]=" + authHeaderValue); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyOnCloseTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyOnCloseTest.java new file mode 100644 index 00000000000..77b15837219 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyOnCloseTest.java @@ -0,0 +1,195 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.net.URI; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JettyOnCloseTest +{ + private Server server; + private ServerConnector connector; + private WebSocketClient client; + private OnCloseEndpoint serverEndpoint = new OnCloseEndpoint(); + + @WebSocket + public static class OnCloseEndpoint extends EventSocket + { + private Consumer onClose; + + public void setOnClose(Consumer onClose) + { + this.onClose = onClose; + } + + @Override + public void onClose(int statusCode, String reason) + { + onClose.accept(session); + super.onClose(statusCode, reason); + } + } + + @WebSocket + public static class BlockingClientEndpoint extends EventSocket + { + private CountDownLatch blockInClose = new CountDownLatch(1); + + public void unBlockClose() + { + blockInClose.countDown(); + } + + @Override + public void onClose(int statusCode, String reason) + { + try + { + blockInClose.await(); + super.onClose(statusCode, reason); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + } + + @BeforeEach + public void start() throws Exception + { + server = new Server(); + connector = new ServerConnector(server); + connector.setPort(0); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + server.setHandler(contextHandler); + + JettyWebSocketServletContainerInitializer.configure(contextHandler, ((servletContext, container) -> + container.addMapping("/", (req, resp) -> serverEndpoint))); + + client = new WebSocketClient(); + server.start(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + @Test + public void changeStatusCodeInOnClose() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connect(clientEndpoint, uri).get(5, TimeUnit.SECONDS); + + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> session.close(StatusCode.SERVICE_RESTART, "custom close reason")); + + clientEndpoint.session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.SERVICE_RESTART)); + assertThat(clientEndpoint.reason, is("custom close reason")); + } + + @Test + public void secondCloseFromOnCloseFails() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connect(clientEndpoint, uri).get(5, TimeUnit.SECONDS); + + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose(Session::close); + + serverEndpoint.session.close(StatusCode.NORMAL, "first close"); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.NORMAL)); + assertThat(clientEndpoint.reason, is("first close")); + } + + @Test + public void abnormalStatusDoesNotChange() throws Exception + { + BlockingClientEndpoint clientEndpoint = new BlockingClientEndpoint(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connect(clientEndpoint, uri).get(5, TimeUnit.SECONDS); + + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> + { + session.close(StatusCode.SERVER_ERROR, "abnormal close 2"); + clientEndpoint.unBlockClose(); + }); + + serverEndpoint.session.close(StatusCode.PROTOCOL, "abnormal close 1"); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.PROTOCOL)); + assertThat(clientEndpoint.reason, is("abnormal close 1")); + } + + @Test + public void onErrorOccurringAfterOnClose() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + client.connect(clientEndpoint, uri).get(5, TimeUnit.SECONDS); + + assertTrue(serverEndpoint.openLatch.await(5, TimeUnit.SECONDS)); + serverEndpoint.setOnClose((session) -> + { + throw new RuntimeException("trigger onError from onClose"); + }); + + clientEndpoint.session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.statusCode, is(StatusCode.SERVER_ERROR)); + assertThat(clientEndpoint.reason, containsString("trigger onError from onClose")); + + assertTrue(serverEndpoint.errorLatch.await(5, TimeUnit.SECONDS)); + assertThat(serverEndpoint.error, instanceOf(RuntimeException.class)); + assertThat(serverEndpoint.error.getMessage(), containsString("trigger onError from onClose")); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketExtensionConfigTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketExtensionConfigTest.java similarity index 86% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketExtensionConfigTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketExtensionConfigTest.java index d981760f999..620a59ee419 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketExtensionConfigTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketExtensionConfigTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java similarity index 74% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java index d9ff41e5db3..2543e78f4c4 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketFilterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketNegotiationTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketNegotiationTest.java similarity index 82% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketNegotiationTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketNegotiationTest.java index f1eef9e655c..2c7efe059b0 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketNegotiationTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketNegotiationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; @@ -23,11 +23,11 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketServletTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketServletTest.java similarity index 77% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketServletTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketServletTest.java index 676ce97494d..2bf60c8dd27 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketServletTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/JettyWebSocketServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ParamsEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ParamsEndpoint.java similarity index 55% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ParamsEndpoint.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ParamsEndpoint.java index bd4470465f1..1782d9094fd 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ParamsEndpoint.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/ParamsEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/SimpleStatusServlet.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/SimpleStatusServlet.java new file mode 100644 index 00000000000..310f57f8ca2 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/SimpleStatusServlet.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class SimpleStatusServlet extends HttpServlet +{ + private final int statusCode; + + public SimpleStatusServlet(int statusCode) + { + this.statusCode = statusCode; + } + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + resp.setStatus(this.statusCode); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java similarity index 87% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java index 0c1302b0bab..90556e1823e 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; @@ -36,12 +36,12 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; public class SuspendResumeTest @@ -169,7 +169,6 @@ public class SuspendResumeTest assertNull(serverSocket.error); } - @Disabled @Test public void testSuspendAfterClose() throws Exception { @@ -192,8 +191,7 @@ public class SuspendResumeTest assertNull(clientSocket.error); assertNull(serverSocket.error); - // suspend the client so that no read events occur - SuspendToken suspendToken = clientSocket.session.suspend(); - suspendToken.resume(); + // suspend after closed throws ISE + assertThrows(IllegalStateException.class, () -> clientSocket.session.suspend()); } } diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java new file mode 100644 index 00000000000..1cd8a05caa4 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java @@ -0,0 +1,362 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.ConnectException; +import java.net.URI; +import java.nio.channels.ClosedChannelException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; +import org.eclipse.jetty.client.http.HttpClientConnectionFactory; +import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Cipher; +import org.eclipse.jetty.http2.client.HTTP2Client; +import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2; +import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory; +import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; +import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; +import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.SecureRequestCustomizer; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.UpgradeException; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.servlet.internal.UpgradeHttpServletRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsStringIgnoringCase; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class WebSocketOverHTTP2Test +{ + private Server server; + private ServerConnector connector; + private ServerConnector tlsConnector; + private WebSocketClient wsClient; + + private void startServer() throws Exception + { + startServer(new TestJettyWebSocketServlet()); + } + + private void startServer(TestJettyWebSocketServlet servlet) throws Exception + { + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + HttpConfiguration httpConfig = new HttpConfiguration(); + HttpConnectionFactory h1c = new HttpConnectionFactory(httpConfig); + HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfig); + connector = new ServerConnector(server, 1, 1, h1c, h2c); + server.addConnector(connector); + + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); + + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory h1s = new HttpConnectionFactory(httpsConfig); + HTTP2ServerConnectionFactory h2s = new HTTP2ServerConnectionFactory(httpsConfig); + ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); + alpn.setDefaultProtocol(h1s.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol()); + tlsConnector = new ServerConnector(server, 1, 1, ssl, alpn, h1s, h2s); + server.addConnector(tlsConnector); + + ServletContextHandler context = new ServletContextHandler(server, "/"); + context.addServlet(new ServletHolder(servlet), "/ws/*"); + JettyWebSocketServletContainerInitializer.configure(context, null); + + server.start(); + } + + private void startClient(Function protocolFn) throws Exception + { + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSslContextFactory(new SslContextFactory.Client(true)); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, protocolFn.apply(clientConnector))); + wsClient = new WebSocketClient(httpClient); + wsClient.start(); + } + + @AfterEach + public void stopServer() throws Exception + { + if (server != null) + server.stop(); + if (wsClient != null) + wsClient.stop(); + } + + @Test + public void testWebSocketOverDynamicHTTP1() throws Exception + { + testWebSocketOverDynamicTransport(clientConnector -> HttpClientConnectionFactory.HTTP11); + } + + @Test + public void testWebSocketOverDynamicHTTP2() throws Exception + { + testWebSocketOverDynamicTransport(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2C(new HTTP2Client(clientConnector))); + } + + private void testWebSocketOverDynamicTransport(Function protocolFn) throws Exception + { + startServer(); + startClient(protocolFn); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo"); + Session session = wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS); + + String text = "websocket"; + session.getRemote().sendString(text); + + String message = wsEndPoint.messageQueue.poll(5, TimeUnit.SECONDS); + assertNotNull(message); + assertEquals(text, message); + + session.close(StatusCode.NORMAL, null); + assertTrue(wsEndPoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertEquals(StatusCode.NORMAL, wsEndPoint.statusCode); + assertNull(wsEndPoint.error); + } + + @Test + public void testConnectProtocolDisabled() throws Exception + { + startServer(); + AbstractHTTP2ServerConnectionFactory h2c = connector.getBean(AbstractHTTP2ServerConnectionFactory.class); + h2c.setConnectProtocolEnabled(false); + + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2C(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause.getMessage(), containsStringIgnoringCase(ErrorCode.PROTOCOL_ERROR.name())); + } + + @Test + public void testSlowWebSocketUpgradeWithHTTP2DataFramesQueued() throws Exception + { + startServer(new TestJettyWebSocketServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + try + { + super.service(request, response); + // Flush the response to the client then wait before exiting + // this method so that the client can send HTTP/2 DATA frames + // that will be processed by the server while this method sleeps. + response.flushBuffer(); + Thread.sleep(1000); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + }); + + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + // Connect and send immediately a message, so the message + // arrives to the server while the server is still upgrading. + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("wss://localhost:" + tlsConnector.getLocalPort() + "/ws/echo"); + Session session = wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS); + String text = "websocket"; + session.getRemote().sendString(text); + + String message = wsEndPoint.messageQueue.poll(5, TimeUnit.SECONDS); + assertNotNull(message); + assertEquals(text, message); + + session.close(StatusCode.NORMAL, null); + assertTrue(wsEndPoint.closeLatch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testWebSocketConnectPortDoesNotExist() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + (connector.getLocalPort() + 1) + "/ws/echo"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(ConnectException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Connection refused")); + } + + @Test + public void testWebSocketNotFound() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/nothing"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(UpgradeException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 501")); + } + + @Test + public void testNotNegotiated() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/null"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(UpgradeException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 503")); + } + + @Test + public void testThrowFromCreator() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + CountDownLatch latch = new CountDownLatch(1); + connector.addBean(new HttpChannel.Listener() + { + @Override + public void onComplete(Request request) + { + latch.countDown(); + } + }); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/throw"); + + ExecutionException failure; + try (StacklessLogging ignored = new StacklessLogging(HttpChannel.class)) + { + failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + } + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(UpgradeException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 500")); + + // Wait for the request to complete on server before stopping. + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testServerConnectionClose() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/connectionClose"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(ClosedChannelException.class)); + } + + private static class TestJettyWebSocketServlet extends JettyWebSocketServlet + { + @Override + protected void configure(JettyWebSocketServletFactory factory) + { + factory.addMapping("/ws/echo", (request, response) -> new EchoSocket()); + factory.addMapping("/ws/null", (request, response) -> null); + factory.addMapping("/ws/throw", (request, response) -> + { + throw new RuntimeException("throwing from creator"); + }); + factory.addMapping("/ws/connectionClose", (request, response) -> + { + UpgradeHttpServletRequest servletRequest = (UpgradeHttpServletRequest)request.getHttpServletRequest(); + Request baseRequest = servletRequest.getBaseRequest(); + baseRequest.getHttpChannel().getEndPoint().close(); + return new EchoSocket(); + }); + } + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketServletExamplesTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketServletExamplesTest.java similarity index 88% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketServletExamplesTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketServletExamplesTest.java index 09af9fe3eaf..4f309ab5cf0 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketServletExamplesTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketServletExamplesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java similarity index 81% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java index 2baa46a4f2f..b13097aaea9 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; @@ -24,10 +24,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.ConnectionStatistics; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.server.HttpConnection; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -112,12 +110,10 @@ public class WebSocketStatsTest long getFrameByteSize(Frame frame) { - ByteBufferPool bufferPool = new MappedByteBufferPool(); - Generator generator = new Generator(bufferPool); - ByteBuffer buffer = bufferPool.acquire(frame.getPayloadLength() + 10, true); - int pos = BufferUtil.flipToFill(buffer); - generator.generateWholeFrame(frame, buffer); - return buffer.position() - pos; + Generator generator = new Generator(); + ByteBuffer headerBuffer = BufferUtil.allocate(Generator.MAX_HEADER_LENGTH); + generator.generateHeader(frame, headerBuffer); + return headerBuffer.remaining() + frame.getPayloadLength(); } @Test diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WriteAfterStopTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStopTest.java similarity index 59% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WriteAfterStopTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStopTest.java index 434e12c90b1..43ffc5e687f 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WriteAfterStopTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStopTest.java @@ -1,23 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests; +import java.io.IOException; import java.net.URI; import java.nio.channels.ClosedChannelException; import java.util.concurrent.TimeUnit; @@ -26,13 +27,10 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.WebSocketClient; -import org.eclipse.jetty.websocket.common.WebSocketSession; -import org.eclipse.jetty.websocket.core.internal.compress.CompressExtension; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; @@ -41,13 +39,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -public class WriteAfterStopTest +public class WebSocketStopTest { - public class UpgradeServlet extends JettyWebSocketServlet { @Override @@ -87,7 +86,28 @@ public class WriteAfterStopTest } @Test - public void test() throws Exception + public void stopWithOpenSessions() throws Exception + { + final URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + + // Connect to two sessions to the server. + EventSocket clientSocket1 = new EventSocket(); + EventSocket clientSocket2 = new EventSocket(); + assertNotNull(client.connect(clientSocket1, uri).get(5, TimeUnit.SECONDS)); + assertNotNull(client.connect(clientSocket2, uri).get(5, TimeUnit.SECONDS)); + assertTrue(clientSocket1.openLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket2.openLatch.await(5, TimeUnit.SECONDS)); + + // WS client is stopped and closes sessions with SHUTDOWN code. + client.stop(); + assertTrue(clientSocket1.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket2.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientSocket1.statusCode, is(StatusCode.SHUTDOWN)); + assertThat(clientSocket2.statusCode, is(StatusCode.SHUTDOWN)); + } + + @Test + public void testWriteAfterStop() throws Exception { URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); EventSocket clientSocket = new EventSocket(); @@ -108,7 +128,8 @@ public class WriteAfterStopTest assertThat(clientSocket.statusCode, is(StatusCode.NORMAL)); assertThat(serverSocket.statusCode, is(StatusCode.NORMAL)); - ((WebSocketSession)session).stop(); - assertThrows(IllegalStateException.class, () -> session.getRemote().sendString("hello world")); + IOException error = assertThrows(IOException.class, + () -> session.getRemote().sendString("this should fail before ExtensionStack")); + assertThat(error.getCause(), instanceOf(ClosedChannelException.class)); } -} \ No newline at end of file +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnClient.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnClient.java new file mode 100644 index 00000000000..662bbaa7bf5 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnClient.java @@ -0,0 +1,227 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.autobahn; + +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.util.Jetty; +import org.eclipse.jetty.util.UrlEncoded; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.tests.EchoSocket; +import org.eclipse.jetty.websocket.tests.EventSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * WebSocket Client for use with autobahn websocket testsuite (wstest). + *

        + * Installing Autobahn: + *

        + *
        + *    # For Debian / Ubuntu
        + *    $ sudo apt-get install python python-dev python-twisted
        + *    $ sudo apt-get install python-pip
        + *    $ sudo pip install autobahntestsuite
        + *
        + *    # For Fedora / Redhat
        + *    $ sudo yum install python python-dev python-pip twisted
        + *    $ sudo yum install libffi-devel
        + *    $ sudo pip install autobahntestsuite
        + * 
        + *

        + * Upgrading an existing installation of autobahntestsuite + *

        + *
        + *     $ sudo pip install -U autobahntestsuite
        + * 
        + *

        + * Running Autobahn Fuzzing Server (which you run this client implementation against): + *

        + *
        + *     # Change to websocket-jetty-tests directory first.
        + *     $ cd jetty-websocket/websocket-jetty-tests/
        + *     $ wstest --mode=fuzzingserver --spec=fuzzingserver.json
        + *
        + *     # Report output is configured (in the fuzzingserver.json) at location:
        + *     $ ls target/reports/clients/
        + * 
        + */ +public class JettyAutobahnClient +{ + public static void main(String[] args) + { + String hostname = "localhost"; + int port = 9001; + + if (args.length > 0) + hostname = args[0]; + if (args.length > 1) + port = Integer.parseInt(args[1]); + + // Optional case numbers + // NOTE: these are url query parameter case numbers (whole integers, eg "6"), not the case ids (eg "7.3.1") + int[] caseNumbers = null; + if (args.length > 2) + { + int offset = 2; + caseNumbers = new int[args.length - offset]; + for (int i = offset; i < args.length; i++) + { + caseNumbers[i - offset] = Integer.parseInt(args[i]); + } + } + + JettyAutobahnClient client = null; + try + { + String userAgent = "JettyWebsocketClient/" + Jetty.VERSION; + client = new JettyAutobahnClient(hostname, port, userAgent); + + LOG.info("Running test suite..."); + LOG.info("Using Fuzzing Server: {}:{}", hostname, port); + LOG.info("User Agent: {}", userAgent); + + if (caseNumbers == null) + { + int caseCount = client.getCaseCount(); + LOG.info("Will run all {} cases ...", caseCount); + for (int caseNum = 1; caseNum <= caseCount; caseNum++) + { + LOG.info("Running case {} (of {}) ...", caseNum, caseCount); + client.runCaseByNumber(caseNum); + } + } + else + { + LOG.info("Will run %d cases ...", caseNumbers.length); + for (int caseNum : caseNumbers) + { + client.runCaseByNumber(caseNum); + } + } + LOG.info("All test cases executed."); + client.updateReports(); + } + catch (Throwable t) + { + LOG.warn("Test Failed", t); + } + finally + { + if (client != null) + client.shutdown(); + } + } + + private static final Logger LOG = LoggerFactory.getLogger(JettyAutobahnClient.class); + private URI baseWebsocketUri; + private WebSocketClient client; + private String userAgent; + + public JettyAutobahnClient(String hostname, int port, String userAgent) throws Exception + { + this.userAgent = userAgent; + this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port); + this.client = new WebSocketClient(); + this.client.start(); + } + + public int getCaseCount() throws IOException, InterruptedException + { + URI wsUri = baseWebsocketUri.resolve("/getCaseCount"); + EventSocket onCaseCount = new EventSocket(); + CompletableFuture response = client.connect(onCaseCount, wsUri); + + if (waitForUpgrade(wsUri, response)) + { + String msg = onCaseCount.messageQueue.poll(10, TimeUnit.SECONDS); + onCaseCount.session.close(StatusCode.SHUTDOWN, null); + assertTrue(onCaseCount.closeLatch.await(2, TimeUnit.SECONDS)); + assertNotNull(msg); + return Integer.decode(msg); + } + throw new IllegalStateException("Unable to get Case Count"); + } + + public void runCaseByNumber(int caseNumber) throws IOException, InterruptedException + { + URI wsUri = baseWebsocketUri.resolve("/runCase?case=" + caseNumber + "&agent=" + UrlEncoded.encodeString(userAgent)); + LOG.info("test uri: {}", wsUri); + + EchoSocket echoHandler = new JettyAutobahnSocket(); + Future response = client.connect(echoHandler, wsUri); + if (waitForUpgrade(wsUri, response)) + { + // Wait up to 5 min as some of the tests can take a while + if (!echoHandler.closeLatch.await(5, TimeUnit.MINUTES)) + { + LOG.warn("could not close {}, aborting session", echoHandler); + echoHandler.session.disconnect(); + } + } + } + + public void shutdown() + { + try + { + client.stop(); + } + catch (Exception e) + { + LOG.warn("Unable to stop WebSocketClient", e); + } + } + + public void updateReports() throws IOException, InterruptedException, ExecutionException, TimeoutException + { + URI wsUri = baseWebsocketUri.resolve("/updateReports?agent=" + UrlEncoded.encodeString(userAgent)); + EventSocket onUpdateReports = new EventSocket(); + Future response = client.connect(onUpdateReports, wsUri); + response.get(5, TimeUnit.SECONDS); + assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS)); + LOG.info("Reports updated."); + LOG.info("Test suite finished!"); + } + + private boolean waitForUpgrade(URI wsUri, Future response) + { + try + { + response.get(10, TimeUnit.SECONDS); + return true; + } + catch (Throwable t) + { + LOG.warn("Unable to connect to: " + wsUri, t); + return false; + } + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnServer.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnServer.java new file mode 100644 index 00000000000..ecee7666180 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnServer.java @@ -0,0 +1,82 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.autobahn; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; + +/** + * WebSocket Server for use with autobahn websocket testsuite (wstest). + *

        + * Installing Autobahn: + *

        + *
        + *    # For Debian / Ubuntu
        + *    $ sudo apt-get install python python-dev python-twisted
        + *    $ sudo apt-get install python-pip
        + *    $ sudo pip install autobahntestsuite
        + *
        + *    # For Fedora / Redhat
        + *    $ sudo yum install python python-dev python-pip twisted
        + *    $ sudo yum install libffi-devel
        + *    $ sudo pip install autobahntestsuite
        + * 
        + *

        + * Upgrading an existing installation of autobahntestsuite + *

        + *
        + *     $ sudo pip install -U autobahntestsuite
        + * 
        + *

        + * Running Autobahn Fuzzing Client (against this server implementation): + *

        + *
        + *     # Change to websocket-jetty-tests directory first.
        + *     $ cd jetty-websocket/websocket-jetty-tests/
        + *     $ wstest --mode=fuzzingclient --spec=fuzzingclient.json
        + *
        + *     # Report output is configured (in the fuzzingclient.json) at location:
        + *     $ ls target/reports/servers/
        + * 
        + */ +public class JettyAutobahnServer +{ + public static void main(String[] args) throws Exception + { + int port = 9001; // same port as found in fuzzing-client.json + if (args != null && args.length > 0) + port = Integer.parseInt(args[0]); + + Server server = new Server(port); + ServerConnector connector = new ServerConnector(server); + connector.setIdleTimeout(10000); + server.addConnector(connector); + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + server.setHandler(context); + + JettyWebSocketServletContainerInitializer.configure(context, (servletContext, container) -> + container.addMapping("/", (req, resp) -> new JettyAutobahnSocket())); + + server.start(); + server.join(); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnSocket.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnSocket.java new file mode 100644 index 00000000000..bc2dc3869f0 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/autobahn/JettyAutobahnSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.autobahn; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.core.WebSocketConstants; +import org.eclipse.jetty.websocket.tests.EchoSocket; + +@WebSocket +public class JettyAutobahnSocket extends EchoSocket +{ + @Override + public void onOpen(Session session) + { + super.onOpen(session); + session.setMaxTextMessageSize(Long.MAX_VALUE); + session.setMaxBinaryMessageSize(Long.MAX_VALUE); + session.setMaxFrameSize(WebSocketConstants.DEFAULT_MAX_FRAME_SIZE * 2); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/BadNetworkTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/BadNetworkTest.java similarity index 84% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/BadNetworkTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/BadNetworkTest.java index 11f7cb431b3..4efcc4ab8ca 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/BadNetworkTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/BadNetworkTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; @@ -30,8 +30,6 @@ import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketListener; @@ -44,6 +42,8 @@ import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -150,7 +150,7 @@ public class BadNetworkTest public static class ServerEndpoint implements WebSocketListener { - private static final Logger LOG = Log.getLogger(ClientCloseTest.ServerEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(ClientCloseTest.ServerEndpoint.class); private Session session; @Override @@ -175,7 +175,7 @@ public class BadNetworkTest } catch (IOException e) { - LOG.warn(e); + LOG.warn("Failed to send string", e); } } @@ -195,7 +195,7 @@ public class BadNetworkTest { if (LOG.isDebugEnabled()) { - LOG.debug(cause); + LOG.debug("ServerEndpoint error", cause); } } } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java similarity index 78% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java index 1340b64030a..5d3534fc585 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; @@ -36,8 +36,6 @@ import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.BlockingArrayQueue; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Frame; import org.eclipse.jetty.websocket.api.MessageTooLargeException; import org.eclipse.jetty.websocket.api.Session; @@ -53,10 +51,11 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint; -import org.eclipse.jetty.websocket.tests.util.FutureWriteCallback; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.nio.charset.StandardCharsets.UTF_8; import static java.time.Duration.ofSeconds; @@ -66,6 +65,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -84,11 +84,7 @@ public class ClientCloseTest { // Send message from client to server final String echoMsg = "echo-test"; - FutureWriteCallback testFut = new FutureWriteCallback(); - clientSocket.getRemote().sendString(echoMsg, testFut); - - // Wait for send future - testFut.get(5, SECONDS); + clientSocket.getRemote().sendString(echoMsg); // Verify received message String recvMsg = clientSocket.messageQueue.poll(5, SECONDS); @@ -176,27 +172,24 @@ public class ClientCloseTest CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint(); Future clientConnectFuture = client.connect(clientSocket, wsUri); - try (Session session = confirmConnection(clientSocket, clientConnectFuture)) - { - // client confirms connection via echo + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture); - // client sends close frame (code 1000, normal) - final String origCloseReason = "send-more-frames"; - clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); + // client sends close frame (code 1000, normal) + final String origCloseReason = "send-more-frames"; + clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); - // Verify received messages - String recvMsg = clientSocket.messageQueue.poll(5, SECONDS); - assertThat("Received message 1", recvMsg, is("Hello")); - recvMsg = clientSocket.messageQueue.poll(5, SECONDS); - assertThat("Received message 2", recvMsg, is("World")); + // Verify received messages + String recvMsg = clientSocket.messageQueue.poll(5, SECONDS); + assertThat("Received message 1", recvMsg, is("Hello")); + recvMsg = clientSocket.messageQueue.poll(5, SECONDS); + assertThat("Received message 2", recvMsg, is("World")); - // Verify that there are no errors - assertThat("Error events", clientSocket.error.get(), nullValue()); - - // client close event on ws-endpoint - clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.NORMAL), containsString("")); - } + // Verify that there are no errors + assertThat("Error events", clientSocket.error.get(), nullValue()); + // client close event on ws-endpoint + clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.NORMAL), containsString("")); clientSessionTracker.assertClosedProperly(client); } @@ -215,18 +208,15 @@ public class ClientCloseTest CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint(); Future clientConnectFuture = client.connect(clientSocket, wsUri); - try (Session session = confirmConnection(clientSocket, clientConnectFuture)) - { - // client confirms connection via echo + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture); - session.getRemote().sendString("too-large-message"); + clientSocket.getSession().getRemote().sendString("too-large-message"); + clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.MESSAGE_TOO_LARGE), containsString("Text message too large")); - clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.MESSAGE_TOO_LARGE), containsString("exceeds maximum size")); - - // client should have noticed the error - assertThat("OnError Latch", clientSocket.errorLatch.await(2, SECONDS), is(true)); - assertThat("OnError", clientSocket.error.get(), instanceOf(MessageTooLargeException.class)); - } + // client should have noticed the error + assertThat("OnError Latch", clientSocket.errorLatch.await(2, SECONDS), is(true)); + assertThat("OnError", clientSocket.error.get(), instanceOf(MessageTooLargeException.class)); // client triggers close event on client ws-endpoint clientSessionTracker.assertClosedProperly(client); @@ -278,27 +268,47 @@ public class ClientCloseTest CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint(); Future clientConnectFuture = client.connect(clientSocket, wsUri); - try (Session ignored = confirmConnection(clientSocket, clientConnectFuture)) - { - // client confirms connection via echo + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture); - // client sends close frame - final String origCloseReason = "sleep|2500"; - clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); + // client sends close frame + final String origCloseReason = "sleep|2500"; + clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); - // client close should occur - clientSocket.assertReceivedCloseEvent(clientTimeout * 2, - is(StatusCode.SHUTDOWN), - containsString("Timeout")); - - // client idle timeout triggers close event on client ws-endpoint - assertThat("OnError Latch", clientSocket.errorLatch.await(2, SECONDS), is(true)); - assertThat("OnError", clientSocket.error.get(), instanceOf(WebSocketTimeoutException.class)); - } + // client close should occur + clientSocket.assertReceivedCloseEvent(clientTimeout * 2, + is(StatusCode.SHUTDOWN), + containsString("Timeout")); + // client idle timeout triggers close event on client ws-endpoint + assertThat("OnError Latch", clientSocket.errorLatch.await(2, SECONDS), is(true)); + assertThat("OnError", clientSocket.error.get(), instanceOf(WebSocketTimeoutException.class)); clientSessionTracker.assertClosedProperly(client); } + @Test + public void testDoubleClose() throws Exception + { + ClientOpenSessionTracker clientSessionTracker = new ClientOpenSessionTracker(1); + clientSessionTracker.addTo(client); + + // Client connects + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/ws")); + CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint(); + Future clientConnectFuture = client.connect(clientSocket, wsUri); + + // Client confirms connection via echo. + confirmConnection(clientSocket, clientConnectFuture); + + // Close twice, first close should succeed and second close is a NOOP + clientSocket.getSession().close(StatusCode.NORMAL, "close1"); + clientSocket.getSession().close(StatusCode.NO_CODE, "close2"); + + // Second close is ignored, we are notified of the first close. + clientSocket.assertReceivedCloseEvent(5000, is(StatusCode.NORMAL), containsString("close1")); + assertNull(clientSocket.error.get()); + } + @Test public void testStopLifecycle() throws Exception { @@ -415,7 +425,7 @@ public class ClientCloseTest public static class ServerEndpoint implements WebSocketFrameListener, WebSocketListener { - private static final Logger LOG = Log.getLogger(ServerEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(ServerEndpoint.class); private Session session; CountDownLatch block = new CountDownLatch(1); @@ -451,7 +461,7 @@ public class ClientCloseTest } catch (Throwable t) { - LOG.debug(t); + LOG.debug("send text failure", t); throw new RuntimeException(t); } } @@ -504,7 +514,7 @@ public class ClientCloseTest } catch (Throwable ignore) { - LOG.ignore(ignore); + LOG.trace("IGNORED", ignore); } } else if (reason.startsWith("sleep|")) @@ -518,10 +528,10 @@ public class ClientCloseTest } catch (InterruptedException ignore) { - LOG.ignore(ignore); + LOG.trace("IGNORED", ignore); } } } } } -} \ No newline at end of file +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java similarity index 90% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java index 33b8f4c5121..96d1e240536 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConfigTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConnectTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConnectTest.java similarity index 78% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConnectTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConnectTest.java index 444eb448569..bb6189b06d7 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConnectTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientConnectTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; @@ -26,6 +26,9 @@ import java.net.SocketTimeoutException; import java.net.URI; import java.time.Duration; import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -70,6 +73,7 @@ public class ClientConnectTest { private Server server; private WebSocketClient client; + private CountDownLatch serverLatch = new CountDownLatch(1); @SuppressWarnings("unchecked") private E assertExpectedError(ExecutionException e, CloseTrackingEndpoint wsocket, Matcher errorMatcher) @@ -97,7 +101,7 @@ public class ClientConnectTest { client = new WebSocketClient(); client.setConnectTimeout(TimeUnit.SECONDS.toMillis(3)); - client.setIdleTimeout(Duration.ofSeconds(10)); + client.setIdleTimeout(Duration.ofSeconds(3)); client.start(); } @@ -124,6 +128,19 @@ public class ClientConnectTest return new EchoSocket(); }); container.addMapping("/get-auth-header", (req, resp) -> new GetAuthHeaderEndpoint()); + + container.addMapping("/noResponse", (req, resp) -> + { + try + { + serverLatch.await(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + return null; + }); }); context.addFilter(WebSocketUpgradeFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); @@ -167,6 +184,27 @@ public class ClientConnectTest } } + @Test + public void testUpgradeRequestPercentEncodedQuery() throws Exception + { + CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); + client.setIdleTimeout(Duration.ofSeconds(10)); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/echo?name=%25foo")); + ClientUpgradeRequest request = new ClientUpgradeRequest(); + request.setSubProtocols("echo"); + Future future = client.connect(cliSock, wsUri); + + try (Session sess = future.get(30, TimeUnit.SECONDS)) + { + assertThat("Connect.UpgradeRequest", sess.getUpgradeRequest(), notNullValue()); + Map> paramMap = sess.getUpgradeRequest().getParameterMap(); + List values = paramMap.get("name"); + assertThat("Params[name]", values.get(0), is("%foo")); + assertThat("Connect.UpgradeResponse", sess.getUpgradeResponse(), notNullValue()); + } + } + @Test public void testUpgradeWithAuthorizationHeader() throws Exception { @@ -211,7 +249,7 @@ public class ClientConnectTest } @Test - public void testBadHandshake_GetOK() throws Exception + public void testBadHandshakeGetOK() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -229,7 +267,7 @@ public class ClientConnectTest } @Test - public void testBadHandshake_GetOK_WithSecWebSocketAccept() throws Exception + public void testBadHandshakeGetOKWithSecWebSocketAccept() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -247,7 +285,7 @@ public class ClientConnectTest } @Test - public void testBadHandshake_SwitchingProtocols_InvalidConnectionHeader() throws Exception + public void testBadHandshakeSwitchingProtocolsInvalidConnectionHeader() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -265,7 +303,7 @@ public class ClientConnectTest } @Test - public void testBadHandshake_SwitchingProtocols_NoConnectionHeader() throws Exception + public void testBadHandshakeSwitchingProtocolsNoConnectionHeader() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -365,37 +403,34 @@ public class ClientConnectTest } @Test - public void testConnectionTimeout_Concurrent() throws Exception + public void testConnectionTimeoutConcurrent() throws Exception { + client.setConnectTimeout(1000); + client.setIdleTimeout(Duration.ofSeconds(1)); CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); - try (ServerSocket serverSocket = new ServerSocket()) - { - InetAddress addr = InetAddress.getByName("localhost"); - InetSocketAddress endpoint = new InetSocketAddress(addr, 0); - serverSocket.bind(endpoint, 1); - int port = serverSocket.getLocalPort(); - URI wsUri = URI.create(String.format("ws://%s:%d/", addr.getHostAddress(), port)); - Future future = client.connect(cliSock, wsUri); + // Connect to endpoint which waits and does not send back a response. + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/noResponse")); + Future future = client.connect(cliSock, wsUri); - // Accept the connection, but do nothing on it (no response, no upgrade, etc) - serverSocket.accept(); + // The attempt to get upgrade response future should throw error + Exception e = assertThrows(Exception.class, + () -> future.get(5, TimeUnit.SECONDS)); - // The attempt to get upgrade response future should throw error - Exception e = assertThrows(Exception.class, - () -> future.get(5, TimeUnit.SECONDS)); + // Allow server to exit now we have failed. + serverLatch.countDown(); - if (e instanceof ExecutionException) - { - assertExpectedError((ExecutionException)e, cliSock, anyOf( - instanceOf(ConnectException.class), - instanceOf(UpgradeException.class) - )); - } - else - { - assertThat("Should have been a TimeoutException", e, instanceOf(TimeoutException.class)); - } - } + // Unwrap the exception to test if it was what we expected. + assertThat(e, instanceOf(ExecutionException.class)); + + Throwable jettyUpgradeException = e.getCause(); + assertThat(jettyUpgradeException, instanceOf(UpgradeException.class)); + + Throwable coreUpgradeException = jettyUpgradeException.getCause(); + assertThat(coreUpgradeException, instanceOf(org.eclipse.jetty.websocket.core.exception.UpgradeException.class)); + + Throwable timeoutException = coreUpgradeException.getCause(); + assertThat(timeoutException, instanceOf(TimeoutException.class)); + assertThat(timeoutException.getMessage(), containsString("Idle timeout")); } } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientOpenSessionTracker.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientOpenSessionTracker.java similarity index 68% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientOpenSessionTracker.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientOpenSessionTracker.java index 6e5962d3a7f..778fba0e7b4 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientOpenSessionTracker.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientOpenSessionTracker.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientSessionsTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientSessionsTest.java similarity index 86% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientSessionsTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientSessionsTest.java index bfc627bb98f..d612814d06d 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientSessionsTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientSessionsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; @@ -95,7 +95,7 @@ public class ClientSessionsTest } @Test - public void testBasicEcho_FromClient() throws Exception + public void testBasicEchoFromClient() throws Exception { WebSocketClient client = new WebSocketClient(); diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientWriteThread.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientWriteThread.java similarity index 67% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientWriteThread.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientWriteThread.java index 73ef4d92371..1f15c7ebfeb 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientWriteThread.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientWriteThread.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; @@ -21,16 +21,16 @@ package org.eclipse.jetty.websocket.tests.client; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.tests.util.FutureWriteCallback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ClientWriteThread extends Thread { - private static final Logger LOG = Log.getLogger(ClientWriteThread.class); + private static final Logger LOG = LoggerFactory.getLogger(ClientWriteThread.class); private final Session session; private int slowness = -1; private int messageCount = 100; @@ -63,7 +63,7 @@ public class ClientWriteThread extends Thread try { - LOG.debug("Writing {} messages to connection {}", messageCount); + LOG.debug("Writing {} messages to {}", messageCount, session); LOG.debug("Artificial Slowness {} ms", slowness); FutureWriteCallback lastMessage = null; RemoteEndpoint remote = session.getRemote(); @@ -87,7 +87,7 @@ public class ClientWriteThread extends Thread } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to write messages", e); } } @@ -105,4 +105,4 @@ public class ClientWriteThread extends Thread { this.slowness = slowness; } -} \ No newline at end of file +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/InvalidUpgradeServlet.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/InvalidUpgradeServlet.java similarity index 74% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/InvalidUpgradeServlet.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/InvalidUpgradeServlet.java index 1b4fc2d642b..9493af892fd 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/InvalidUpgradeServlet.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/InvalidUpgradeServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/SlowClientTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/SlowClientTest.java similarity index 83% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/SlowClientTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/SlowClientTest.java index 8848364f852..978d1fda795 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/SlowClientTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/SlowClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/WebSocketClientTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/WebSocketClientTest.java similarity index 72% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/WebSocketClientTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/WebSocketClientTest.java index 290e2de0ec3..6b10557e870 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/WebSocketClientTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/WebSocketClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.client; @@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.tests.client; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; +import java.nio.ByteBuffer; import java.time.Duration; import java.util.Arrays; import java.util.Collection; @@ -34,6 +35,7 @@ import javax.servlet.DispatcherType; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; @@ -122,7 +124,7 @@ public class WebSocketClientTest } @Test - public void testAddExtension_NotInstalled() throws Exception + public void testAddExtensionNotInstalled() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -141,7 +143,7 @@ public class WebSocketClientTest } @Test - public void testBasicEcho_FromClient() throws Exception + public void testBasicEchoFromClient() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -172,7 +174,87 @@ public class WebSocketClientTest } @Test - public void testBasicEcho_UsingCallback() throws Exception + public void testBasicEchoPartialUsageFromClient() throws Exception + { + CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); + + client.setIdleTimeout(Duration.ofSeconds(10)); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/echo")); + ClientUpgradeRequest request = new ClientUpgradeRequest(); + request.setSubProtocols("echo"); + Future future = client.connect(cliSock, wsUri, request); + + try (Session sess = future.get(30, TimeUnit.SECONDS)) + { + assertThat("Session", sess, notNullValue()); + assertThat("Session.open", sess.isOpen(), is(true)); + assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); + assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); + + Collection sessions = client.getOpenSessions(); + assertThat("client.sessions.size", sessions.size(), is(1)); + + RemoteEndpoint remote = cliSock.getSession().getRemote(); + remote.sendPartialString("Hello", false); + remote.sendPartialString(" ", false); + remote.sendPartialString("World", true); + + // wait for response from server + String received = cliSock.messageQueue.poll(5, TimeUnit.SECONDS); + assertThat("Message", received, containsString("Hello World")); + } + } + + @Test + public void testBasicEchoPartialTextWithPartialBinaryFromClient() throws Exception + { + CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); + + client.setIdleTimeout(Duration.ofSeconds(10)); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/echo")); + ClientUpgradeRequest request = new ClientUpgradeRequest(); + request.setSubProtocols("echo"); + Future future = client.connect(cliSock, wsUri, request); + + try (Session sess = future.get(30, TimeUnit.SECONDS)) + { + assertThat("Session", sess, notNullValue()); + assertThat("Session.open", sess.isOpen(), is(true)); + assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); + assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); + + Collection sessions = client.getOpenSessions(); + assertThat("client.sessions.size", sessions.size(), is(1)); + + RemoteEndpoint remote = cliSock.getSession().getRemote(); + remote.sendPartialString("Hello", false); + remote.sendPartialString(" ", false); + remote.sendPartialString("World", true); + + String[] parts = { + "The difference between the right word ", + "and the almost right word is the difference ", + "between lightning and a lightning bug." + }; + + remote.sendPartialBytes(BufferUtil.toBuffer(parts[0]), false); + remote.sendPartialBytes(BufferUtil.toBuffer(parts[1]), false); + remote.sendPartialBytes(BufferUtil.toBuffer(parts[2]), true); + + // wait for response from server + String received = cliSock.messageQueue.poll(5, TimeUnit.SECONDS); + assertThat("Message", received, containsString("Hello World")); + + ByteBuffer bufReceived = cliSock.binaryMessageQueue.poll(5, TimeUnit.SECONDS); + received = BufferUtil.toUTF8String(bufReceived.slice()); + assertThat("Message", received, containsString(parts[0] + parts[1] + parts[2])); + } + } + + @Test + public void testBasicEchoUsingCallback() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); @@ -205,7 +287,7 @@ public class WebSocketClientTest } @Test - public void testBasicEcho_FromServer() throws Exception + public void testBasicEchoFromServer() throws Exception { CloseTrackingEndpoint cliSock = new CloseTrackingEndpoint(); diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java similarity index 61% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java index 6e87475cddb..ebdbe1624b5 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoCreator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.examples; diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java new file mode 100644 index 00000000000..aa4ebe7d510 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAdvancedEchoServlet.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.examples; + +import java.time.Duration; +import javax.servlet.annotation.WebServlet; + +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; + +@SuppressWarnings("serial") +@WebServlet(name = "MyAdvanced Echo WebSocket Servlet", urlPatterns = {"/advecho"}) +public class MyAdvancedEchoServlet extends JettyWebSocketServlet +{ + @Override + public void configure(JettyWebSocketServletFactory factory) + { + // set a 10 second timeout + factory.setIdleTimeout(Duration.ofSeconds(10)); + + // set a custom WebSocket creator + factory.setCreator(new MyAdvancedEchoCreator()); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedCreator.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedCreator.java similarity index 60% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedCreator.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedCreator.java index c5f15c69a60..5679b859b4d 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedCreator.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedCreator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.examples; diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedServlet.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedServlet.java new file mode 100644 index 00000000000..58de095bad4 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyAuthedServlet.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.examples; + +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; + +@SuppressWarnings("serial") +public class MyAuthedServlet extends JettyWebSocketServlet +{ + @Override + public void configure(JettyWebSocketServletFactory factory) + { + factory.setCreator(new MyAuthedCreator()); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyBinaryEchoSocket.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyBinaryEchoSocket.java new file mode 100644 index 00000000000..67df89368d1 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyBinaryEchoSocket.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.examples; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +/** + * Echo BINARY messages + */ +@WebSocket +public class MyBinaryEchoSocket +{ + @OnWebSocketMessage + public void onWebSocketText(Session session, byte[] buf, int offset, int len) + { + // Echo message back, asynchronously + session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len), null); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java new file mode 100644 index 00000000000..1c29c913f15 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoServlet.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.examples; + +import java.time.Duration; +import javax.servlet.annotation.WebServlet; + +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; + +@SuppressWarnings("serial") +@WebServlet(name = "MyEcho WebSocket Servlet", urlPatterns = {"/echo"}) +public class MyEchoServlet extends JettyWebSocketServlet +{ + @Override + public void configure(JettyWebSocketServletFactory factory) + { + // set a 10 second timeout + factory.setIdleTimeout(Duration.ofSeconds(10)); + + // register MyEchoSocket as the WebSocket to create on Upgrade + factory.register(MyEchoSocket.class); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoSocket.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoSocket.java new file mode 100644 index 00000000000..180a7e53d10 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/examples/MyEchoSocket.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.examples; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +/** + * Example WebSocket, simple echo + */ +@WebSocket +public class MyEchoSocket +{ + @OnWebSocketMessage + public void onWebSocketText(Session session, String message) + { + // Echo message back, asynchronously + session.getRemote().sendString(message, null); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/extensions/ExtensionConfigTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/extensions/ExtensionConfigTest.java similarity index 81% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/extensions/ExtensionConfigTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/extensions/ExtensionConfigTest.java index df84a613b97..1ef482ada5d 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/extensions/ExtensionConfigTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/extensions/ExtensionConfigTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.extensions; @@ -107,7 +107,7 @@ public class ExtensionConfigTest } @Test - public void testParseSimple_BasicParameters() + public void testParseSimpleBasicParameters() { ExtensionConfig cfg = ExtensionConfig.parse("bar; baz=2"); Map expectedParams = new HashMap<>(); @@ -116,7 +116,7 @@ public class ExtensionConfigTest } @Test - public void testParseSimple_NoParameters() + public void testParseSimpleNoParameters() { ExtensionConfig cfg = ExtensionConfig.parse("foo"); Map expectedParams = new HashMap<>(); diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/AbstractCloseEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/AbstractCloseEndpoint.java similarity index 56% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/AbstractCloseEndpoint.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/AbstractCloseEndpoint.java index 27e9a7ceef8..4f3ffc2f469 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/AbstractCloseEndpoint.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/AbstractCloseEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; @@ -22,10 +22,11 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.hamcrest.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -33,7 +34,8 @@ import static org.hamcrest.Matchers.nullValue; public abstract class AbstractCloseEndpoint extends WebSocketAdapter { - public final Logger LOG; + public final Logger log; + public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); public String closeReason = null; public int closeStatusCode = -1; @@ -41,13 +43,21 @@ public abstract class AbstractCloseEndpoint extends WebSocketAdapter public AbstractCloseEndpoint() { - this.LOG = Log.getLogger(this.getClass().getName()); + this.log = LoggerFactory.getLogger(this.getClass().getName()); + } + + @Override + public void onWebSocketConnect(Session sess) + { + super.onWebSocketConnect(sess); + log.debug("onWebSocketConnect({})", sess); + openLatch.countDown(); } @Override public void onWebSocketClose(int statusCode, String reason) { - LOG.debug("onWebSocketClose({}, {})", statusCode, reason); + log.debug("onWebSocketClose({}, {})", statusCode, reason); this.closeStatusCode = statusCode; this.closeReason = reason; closeLatch.countDown(); @@ -56,7 +66,7 @@ public abstract class AbstractCloseEndpoint extends WebSocketAdapter @Override public void onWebSocketError(Throwable cause) { - LOG.debug("onWebSocketError({})", cause.getClass().getSimpleName()); + log.debug("onWebSocketError({})", cause.getClass().getSimpleName()); errors.offer(cause); } diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/CloseInOnCloseEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/CloseInOnCloseEndpoint.java new file mode 100644 index 00000000000..37de5a3928c --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/CloseInOnCloseEndpoint.java @@ -0,0 +1,31 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.server; + +import org.eclipse.jetty.websocket.api.StatusCode; + +public class CloseInOnCloseEndpoint extends AbstractCloseEndpoint +{ + @Override + public void onWebSocketClose(int statusCode, String reason) + { + getSession().close(StatusCode.SERVER_ERROR, "this should be a noop"); + super.onWebSocketClose(statusCode, reason); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/CloseInOnCloseEndpointNewThread.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/CloseInOnCloseEndpointNewThread.java new file mode 100644 index 00000000000..8286ad10dfa --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/CloseInOnCloseEndpointNewThread.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.server; + +import java.util.concurrent.CountDownLatch; + +import org.eclipse.jetty.websocket.api.StatusCode; + +public class CloseInOnCloseEndpointNewThread extends AbstractCloseEndpoint +{ + @Override + public void onWebSocketClose(int statusCode, String reason) + { + try + { + CountDownLatch complete = new CountDownLatch(1); + new Thread(() -> + { + getSession().close(StatusCode.SERVER_ERROR, "this should be a noop"); + complete.countDown(); + }).start(); + complete.await(); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + + super.onWebSocketClose(statusCode, reason); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ContainerEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ContainerEndpoint.java similarity index 59% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ContainerEndpoint.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ContainerEndpoint.java index 3905b8947fc..e188a109879 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ContainerEndpoint.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ContainerEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; @@ -22,8 +22,8 @@ import java.util.Collection; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.api.WriteCallback; -import org.eclipse.jetty.websocket.common.WebSocketContainer; /** * On Message, return container information @@ -42,7 +42,7 @@ public class ContainerEndpoint extends AbstractCloseEndpoint @Override public void onWebSocketText(String message) { - LOG.debug("onWebSocketText({})", message); + log.debug("onWebSocketText({})", message); if (message.equalsIgnoreCase("openSessions")) { Collection sessions = container.getOpenSessions(); @@ -62,7 +62,7 @@ public class ContainerEndpoint extends AbstractCloseEndpoint @Override public void onWebSocketConnect(Session sess) { - LOG.debug("onWebSocketConnect({})", sess); + log.debug("onWebSocketConnect({})", sess); this.session = sess; } } diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastCloseEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastCloseEndpoint.java new file mode 100644 index 00000000000..a425c54b54e --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastCloseEndpoint.java @@ -0,0 +1,35 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.server; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; + +/** + * On Connect, close socket + */ +public class FastCloseEndpoint extends AbstractCloseEndpoint +{ + @Override + public void onWebSocketConnect(Session sess) + { + log.debug("onWebSocketConnect({})", sess); + sess.close(StatusCode.NORMAL, "FastCloseServer"); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastFailEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastFailEndpoint.java new file mode 100644 index 00000000000..1f7950b29e6 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FastFailEndpoint.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.server; + +import org.eclipse.jetty.websocket.api.Session; + +/** + * On Connect, throw unhandled exception + */ +public class FastFailEndpoint extends AbstractCloseEndpoint +{ + @Override + public void onWebSocketConnect(Session sess) + { + log.debug("onWebSocketConnect({})", sess); + // Test failure due to unhandled exception + // this should trigger a fast-fail closure during open/connect + throw new RuntimeException("Intentional FastFail"); + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FrameAnnotationTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FrameAnnotationTest.java new file mode 100644 index 00000000000..c79c67582f5 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FrameAnnotationTest.java @@ -0,0 +1,210 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.server; + +import java.net.URI; +import java.time.Duration; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; + +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.Frame; +import org.eclipse.jetty.websocket.api.RemoteEndpoint; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.util.WSURI; +import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.WebSocketSession; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; +import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; +import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class FrameAnnotationTest +{ + private Server server; + private FrameCreator frameCreator; + private WebSocketClient client; + + @BeforeEach + public void startServer() throws Exception + { + server = new Server(); + + ServerConnector connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + + ServletHolder closeEndpoint = new ServletHolder(new JettyWebSocketServlet() + { + @Override + protected void configure(JettyWebSocketServletFactory factory) + { + factory.setIdleTimeout(Duration.ofSeconds(2)); + frameCreator = new FrameCreator(); + factory.setCreator(frameCreator); + } + }); + context.addServlet(closeEndpoint, "/ws"); + JettyWebSocketServletContainerInitializer.configure(context, null); + + HandlerList handlers = new HandlerList(); + handlers.addHandler(context); + handlers.addHandler(new DefaultHandler()); + + server.setHandler(handlers); + + server.start(); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + @BeforeEach + public void startClient() throws Exception + { + client = new WebSocketClient(); + client.start(); + } + + @AfterEach + public void stopClient() throws Exception + { + client.stop(); + } + + private void close(Session session) + { + if (session != null) + { + session.close(); + } + } + + @Test + public void testPartialText() throws Exception + { + ClientUpgradeRequest request = new ClientUpgradeRequest(); + CloseTrackingEndpoint clientEndpoint = new CloseTrackingEndpoint(); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/ws")); + Future futSession = client.connect(clientEndpoint, wsUri, request); + + Session session = null; + try (StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) + { + session = futSession.get(5, SECONDS); + + RemoteEndpoint clientRemote = session.getRemote(); + clientRemote.sendPartialString("hello", false); + clientRemote.sendPartialString(" ", false); + clientRemote.sendPartialString("world", true); + + FrameEndpoint serverEndpoint = frameCreator.frameEndpoint; + + String event = serverEndpoint.frameEvents.poll(5, SECONDS); + assertThat("Event", event, is("FRAME[TEXT,fin=false,payload=hello,len=5]")); + event = serverEndpoint.frameEvents.poll(5, SECONDS); + assertThat("Event", event, is("FRAME[CONTINUATION,fin=false,payload= ,len=1]")); + event = serverEndpoint.frameEvents.poll(5, SECONDS); + assertThat("Event", event, is("FRAME[CONTINUATION,fin=true,payload=world,len=5]")); + } + finally + { + close(session); + } + } + + public static class FrameCreator implements JettyWebSocketCreator + { + public FrameEndpoint frameEndpoint; + + @Override + public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) + { + frameEndpoint = new FrameEndpoint(); + return frameEndpoint; + } + } + + @WebSocket + public static class FrameEndpoint + { + public Session session; + public CountDownLatch closeLatch = new CountDownLatch(1); + public LinkedBlockingQueue frameEvents = new LinkedBlockingQueue<>(); + + @OnWebSocketClose + public void onWebSocketClose(int statusCode, String reason) + { + closeLatch.countDown(); + } + + @OnWebSocketConnect + public void onWebSocketConnect(Session session) + { + this.session = session; + } + + @OnWebSocketError + public void onWebSocketError(Throwable cause) + { + cause.printStackTrace(System.err); + } + + @OnWebSocketFrame + public void onWebSocketFrame(Frame frame) + { + frameEvents.offer(String.format("FRAME[%s,fin=%b,payload=%s,len=%d]", + OpCode.name(frame.getOpCode()), + frame.isFin(), + BufferUtil.toUTF8String(frame.getPayload()), + frame.getPayloadLength())); + } + } +} diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FrameListenerTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FrameListenerTest.java new file mode 100644 index 00000000000..dc2107f2727 --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/FrameListenerTest.java @@ -0,0 +1,188 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.server; + +import java.net.URI; +import java.time.Duration; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; + +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.Frame; +import org.eclipse.jetty.websocket.api.RemoteEndpoint; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketFrameListener; +import org.eclipse.jetty.websocket.api.util.WSURI; +import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.WebSocketSession; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class FrameListenerTest +{ + private Server server; + private FrameEndpoint serverEndpoint; + private WebSocketClient client; + + @BeforeEach + public void startServer() throws Exception + { + server = new Server(); + + ServerConnector connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + + ServletHolder closeEndpoint = new ServletHolder(new JettyWebSocketServlet() + { + @Override + public void configure(JettyWebSocketServletFactory factory) + { + factory.setIdleTimeout(Duration.ofSeconds(2)); + serverEndpoint = new FrameEndpoint(); + factory.setCreator((req, resp) -> serverEndpoint); + } + }); + context.addServlet(closeEndpoint, "/ws"); + JettyWebSocketServletContainerInitializer.configure(context, null); + + HandlerList handlers = new HandlerList(); + handlers.addHandler(context); + handlers.addHandler(new DefaultHandler()); + + server.setHandler(handlers); + + server.start(); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + @BeforeEach + public void startClient() throws Exception + { + client = new WebSocketClient(); + client.start(); + } + + @AfterEach + public void stopClient() throws Exception + { + client.stop(); + } + + private void close(Session session) + { + if (session != null) + { + session.close(); + } + } + + @Test + public void testPartialText() throws Exception + { + ClientUpgradeRequest request = new ClientUpgradeRequest(); + CloseTrackingEndpoint clientEndpoint = new CloseTrackingEndpoint(); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/ws")); + Future futSession = client.connect(clientEndpoint, wsUri, request); + + Session session = null; + try (StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) + { + session = futSession.get(5, SECONDS); + + RemoteEndpoint clientRemote = session.getRemote(); + clientRemote.sendPartialString("hello", false); + clientRemote.sendPartialString(" ", false); + clientRemote.sendPartialString("world", true); + + String event = serverEndpoint.frameEvents.poll(5, SECONDS); + assertThat("Event", event, is("FRAME[TEXT,fin=false,payload=hello,len=5]")); + event = serverEndpoint.frameEvents.poll(5, SECONDS); + assertThat("Event", event, is("FRAME[CONTINUATION,fin=false,payload= ,len=1]")); + event = serverEndpoint.frameEvents.poll(5, SECONDS); + assertThat("Event", event, is("FRAME[CONTINUATION,fin=true,payload=world,len=5]")); + } + finally + { + close(session); + } + } + + public static class FrameEndpoint implements WebSocketFrameListener + { + public Session session; + public CountDownLatch closeLatch = new CountDownLatch(1); + public LinkedBlockingQueue frameEvents = new LinkedBlockingQueue<>(); + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + closeLatch.countDown(); + } + + @Override + public void onWebSocketConnect(Session session) + { + this.session = session; + } + + @Override + public void onWebSocketError(Throwable cause) + { + cause.printStackTrace(System.err); + } + + @Override + public void onWebSocketFrame(Frame frame) + { + frameEvents.offer(String.format("FRAME[%s,fin=%b,payload=%s,len=%d]", + OpCode.name(frame.getOpCode()), + frame.isFin(), + BufferUtil.toUTF8String(frame.getPayload()), + frame.getPayloadLength())); + } + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/PartialListenerTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/PartialListenerTest.java similarity index 91% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/PartialListenerTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/PartialListenerTest.java index 08edf8d620f..1c2804d59f4 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/PartialListenerTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/PartialListenerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; @@ -25,6 +25,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.DefaultHandler; @@ -32,7 +33,6 @@ import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketPartialListener; @@ -40,7 +40,6 @@ import org.eclipse.jetty.websocket.api.util.WSURI; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.common.WebSocketSession; -import org.eclipse.jetty.websocket.common.util.TextUtil; import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; @@ -48,6 +47,7 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint; +import org.eclipse.jetty.websocket.util.TextUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -194,7 +194,7 @@ public class PartialListenerTest * Test to ensure that the internal state tracking the partial messages is reset after each complete message. */ @Test - public void testPartial_TextBinaryText() throws Exception + public void testPartialTextBinaryText() throws Exception { ClientUpgradeRequest request = new ClientUpgradeRequest(); CloseTrackingEndpoint clientEndpoint = new CloseTrackingEndpoint(); diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseCreator.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseCreator.java similarity index 64% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseCreator.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseCreator.java index 387e08ee235..e7521981ba9 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseCreator.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseCreator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; @@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.tests.server; import java.util.concurrent.LinkedBlockingQueue; import javax.servlet.ServletContext; -import org.eclipse.jetty.websocket.common.WebSocketContainer; +import org.eclipse.jetty.websocket.api.WebSocketContainer; import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; import org.eclipse.jetty.websocket.server.JettyWebSocketCreator; @@ -63,6 +63,16 @@ public class ServerCloseCreator implements JettyWebSocketCreator closeSocket = new ContainerEndpoint(container); resp.setAcceptedSubProtocol("container"); } + else if (req.hasSubProtocol("closeInOnClose")) + { + closeSocket = new CloseInOnCloseEndpoint(); + resp.setAcceptedSubProtocol("closeInOnClose"); + } + else if (req.hasSubProtocol("closeInOnCloseNewThread")) + { + closeSocket = new CloseInOnCloseEndpointNewThread(); + resp.setAcceptedSubProtocol("closeInOnCloseNewThread"); + } if (closeSocket != null) { diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseTest.java similarity index 74% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseTest.java index 43f8fc09342..3277da8b00c 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerCloseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; @@ -23,13 +23,13 @@ import java.nio.channels.ClosedChannelException; import java.time.Duration; import java.util.concurrent.Future; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.util.WSURI; @@ -51,6 +51,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Tests various close scenarios @@ -275,4 +276,52 @@ public class ServerCloseTest close(session); } } + + @Test + public void testSecondCloseFromOnClosed() throws Exception + { + // Testing WebSocketSession.close() in onClosed() does not cause deadlock. + ClientUpgradeRequest request = new ClientUpgradeRequest(); + request.setSubProtocols("closeInOnClose"); + CloseTrackingEndpoint clientEndpoint = new CloseTrackingEndpoint(); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/ws")); + client.connect(clientEndpoint, wsUri, request).get(5, SECONDS); + + // Hard close from the server. Server onClosed() will try to close again which should be a NOOP. + AbstractCloseEndpoint serverEndpoint = serverEndpointCreator.pollLastCreated(); + assertTrue(serverEndpoint.openLatch.await(5, SECONDS)); + serverEndpoint.getSession().close(StatusCode.SHUTDOWN, "SHUTDOWN hard close"); + + // Verify that client got close + clientEndpoint.assertReceivedCloseEvent(5000, is(StatusCode.SHUTDOWN), containsString("SHUTDOWN hard close")); + + // Verify that server socket got close event + assertTrue(serverEndpoint.closeLatch.await(5, SECONDS)); + assertThat(serverEndpoint.closeStatusCode, is(StatusCode.SHUTDOWN)); + } + + @Test + public void testSecondCloseFromOnClosedInNewThread() throws Exception + { + // Testing WebSocketSession.close() in onClosed() does not cause deadlock. + ClientUpgradeRequest request = new ClientUpgradeRequest(); + request.setSubProtocols("closeInOnCloseNewThread"); + CloseTrackingEndpoint clientEndpoint = new CloseTrackingEndpoint(); + + URI wsUri = WSURI.toWebsocket(server.getURI().resolve("/ws")); + client.connect(clientEndpoint, wsUri, request).get(5, SECONDS); + + // Hard close from the server. Server onClosed() will try to close again which should be a NOOP. + AbstractCloseEndpoint serverEndpoint = serverEndpointCreator.pollLastCreated(); + assertTrue(serverEndpoint.openLatch.await(5, SECONDS)); + serverEndpoint.getSession().close(StatusCode.SHUTDOWN, "SHUTDOWN hard close"); + + // Verify that client got close + clientEndpoint.assertReceivedCloseEvent(5000, is(StatusCode.SHUTDOWN), containsString("SHUTDOWN hard close")); + + // Verify that server socket got close event + assertTrue(serverEndpoint.closeLatch.await(5, SECONDS)); + assertThat(serverEndpoint.closeStatusCode, is(StatusCode.SHUTDOWN)); + } } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java similarity index 93% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java index 6d55258c0d5..510774ed602 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/ServerConfigTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerEndpoint.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerEndpoint.java similarity index 60% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerEndpoint.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerEndpoint.java index ebdce28cfc4..37d676bb02c 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerEndpoint.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerEndpoint.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; @@ -23,16 +23,16 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @WebSocket public class SlowServerEndpoint { - private static final Logger LOG = Log.getLogger(SlowServerEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(SlowServerEndpoint.class); @OnWebSocketMessage public void onMessage(Session session, String msg) @@ -55,7 +55,7 @@ public class SlowServerEndpoint } catch (Throwable cause) { - LOG.warn(cause); + LOG.warn("failed to send text", cause); } } }); @@ -69,7 +69,7 @@ public class SlowServerEndpoint } catch (IOException ignore) { - LOG.ignore(ignore); + LOG.trace("IGNORED", ignore); } } } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerTest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerTest.java similarity index 83% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerTest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerTest.java index ba63acdda4c..f48f3846bc7 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerTest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/SlowServerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.server; diff --git a/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/FutureWriteCallback.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/FutureWriteCallback.java new file mode 100644 index 00000000000..204c6a1bcab --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/FutureWriteCallback.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.tests.util; + +import java.util.concurrent.Future; + +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.websocket.api.WriteCallback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Allows events to a {@link WriteCallback} to drive a {@link Future} for the user. + */ +public class FutureWriteCallback extends FutureCallback implements WriteCallback +{ + private static final Logger LOG = LoggerFactory.getLogger(FutureWriteCallback.class); + + @Override + public void writeFailed(Throwable cause) + { + if (LOG.isDebugEnabled()) + LOG.debug(".writeFailed", cause); + failed(cause); + } + + @Override + public void writeSuccess() + { + if (LOG.isDebugEnabled()) + LOG.debug(".writeSuccess"); + succeeded(); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/WSURITest.java b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/WSURITest.java similarity index 74% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/WSURITest.java rename to jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/WSURITest.java index 6c0e2c6148d..9913deee34d 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/WSURITest.java +++ b/jetty-websocket/websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/util/WSURITest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.tests.util; diff --git a/jetty-websocket/websocket-jetty-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-jetty-tests/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..f53242c83bf --- /dev/null +++ b/jetty-websocket/websocket-jetty-tests/src/test/resources/jetty-logging.properties @@ -0,0 +1,11 @@ +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG +# org.eclipse.jetty.websocket.LEVEL=DEBUG +# org.eclipse.jetty.websocket.test.LEVEL=DEBUG +# org.eclipse.jetty.websocket.tests.EventSocket.LEVEL=DEBUG +# org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG +# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG +# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG +# org.eclipse.jetty.client.LEVEL=DEBUG +# org.eclipse.jetty.io.LEVEL=DEBUG +# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO diff --git a/jetty-websocket/websocket-jetty-tests/src/test/resources/keystore.p12 b/jetty-websocket/websocket-jetty-tests/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..b51c835024b Binary files /dev/null and b/jetty-websocket/websocket-jetty-tests/src/test/resources/keystore.p12 differ diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index f803f732e80..beeeab4b0fc 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -25,6 +25,15 @@ jetty-servlet ${project.version}
        + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper @@ -32,7 +41,7 @@ org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api ${project.version} test @@ -65,7 +74,7 @@ - org.eclipse.jetty.websocket:jetty-websocket-api + org.eclipse.jetty.websocket:websocket-jetty-api javax.websocket diff --git a/jetty-websocket/websocket-servlet/src/main/java/module-info.java b/jetty-websocket/websocket-servlet/src/main/java/module-info.java index cfa6b652061..93715204b9d 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/module-info.java +++ b/jetty-websocket/websocket-servlet/src/main/java/module-info.java @@ -1,30 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // module org.eclipse.jetty.websocket.servlet { exports org.eclipse.jetty.websocket.servlet; - requires jetty.servlet.api; - requires org.eclipse.jetty.http; - requires org.eclipse.jetty.io; - requires org.eclipse.jetty.server; - requires org.eclipse.jetty.servlet; - requires org.eclipse.jetty.util; - requires org.eclipse.jetty.websocket.core; + requires transitive org.eclipse.jetty.servlet; + requires transitive org.eclipse.jetty.websocket.core; + requires org.slf4j; } diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/FrameHandlerFactory.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/FrameHandlerFactory.java index b893e2024b2..a895d9db690 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/FrameHandlerFactory.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/FrameHandlerFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeRequest.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeRequest.java index ca9733ac683..ef81155a00b 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeRequest.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeResponse.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeResponse.java index 15ac69ba78e..04b5d490558 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeResponse.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/ServletUpgradeResponse.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; @@ -176,7 +176,7 @@ public class ServletUpgradeResponse if (matches < 1) throw new IllegalArgumentException("Extension not a requested extension"); - matches = negotiation.getNegotiatedExtensions().stream().filter(e -> e.getName().equals(config.getName())).count(); + matches = configs.stream().filter(e -> e.getName().equals(config.getName())).count(); if (matches > 1) throw new IllegalArgumentException("Multiple extensions of the same name"); } diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketCreator.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketCreator.java index 3094ed6287e..b4db96bd148 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketCreator.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketCreator.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketMapping.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketMapping.java index f89476b6ab2..30bf8098e2b 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketMapping.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketMapping.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; import java.io.IOException; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -33,30 +34,32 @@ import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.Configuration; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.exception.WebSocketException; import org.eclipse.jetty.websocket.core.server.Handshaker; import org.eclipse.jetty.websocket.core.server.Negotiation; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; /** * Mapping of pathSpec to a tupple of {@link WebSocketCreator}, {@link FrameHandlerFactory} and - * {@link org.eclipse.jetty.websocket.core.FrameHandler.Customizer}. + * {@link Configuration.Customizer}. *

        - * When the {@link #upgrade(HttpServletRequest, HttpServletResponse, FrameHandler.Customizer)} + * When the {@link #upgrade(HttpServletRequest, HttpServletResponse, Configuration.Customizer)} * method is called, a match for the pathSpec is looked for. If one is found then the * creator is used to create a POJO for the WebSocket endpoint, the factory is used to * wrap that POJO with a {@link FrameHandler} and the customizer is used to configure the resulting - * {@link FrameHandler.CoreSession}.

        + * {@link CoreSession}.

        */ public class WebSocketMapping implements Dumpable, LifeCycle.Listener { - private static final Logger LOG = Log.getLogger(WebSocketMapping.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketMapping.class); public static WebSocketMapping getMapping(ServletContext servletContext, String mappingKey) { @@ -186,7 +189,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener * @param factory the factory to use to create a FrameHandler for the websocket * @param customizer the customizer to use to customize the WebSocket session. */ - public void addMapping(PathSpec pathSpec, WebSocketCreator creator, FrameHandlerFactory factory, FrameHandler.Customizer customizer) throws WebSocketException + public void addMapping(PathSpec pathSpec, WebSocketCreator creator, FrameHandlerFactory factory, Configuration.Customizer customizer) throws WebSocketException { mappings.put(pathSpec, new Negotiator(creator, factory, customizer)); } @@ -213,7 +216,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener return mapping.getResource(); } - public boolean upgrade(HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException + public boolean upgrade(HttpServletRequest request, HttpServletResponse response, Configuration.Customizer defaultCustomizer) throws IOException { // Since this may be a filter, we need to be smart about determining the target path. // We should rely on the Container for stripping path parameters and its ilk before @@ -244,7 +247,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener private final WebSocketCreator creator; private final FrameHandlerFactory factory; - public Negotiator(WebSocketCreator creator, FrameHandlerFactory factory, FrameHandler.Customizer customizer) + public Negotiator(WebSocketCreator creator, FrameHandlerFactory factory, Configuration.Customizer customizer) { super(components, customizer); this.creator = creator; @@ -263,39 +266,26 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener if (servletContext == null) throw new IllegalStateException("null servletContext from request"); - ClassLoader loader = servletContext.getClassLoader(); - ClassLoader old = Thread.currentThread().getContextClassLoader(); + ServletUpgradeRequest upgradeRequest = new ServletUpgradeRequest(negotiation); + ServletUpgradeResponse upgradeResponse = new ServletUpgradeResponse(negotiation); - try + AtomicReference result = new AtomicReference<>(); + ((ContextHandler.Context)servletContext).getContextHandler().handle(() -> + result.set(creator.createWebSocket(upgradeRequest, upgradeResponse))); + Object websocketPojo = result.get(); + + // Handling for response forbidden (and similar paths) + if (upgradeResponse.isCommitted()) + return null; + + if (websocketPojo == null) { - Thread.currentThread().setContextClassLoader(loader); - - ServletUpgradeRequest upgradeRequest = new ServletUpgradeRequest(negotiation); - ServletUpgradeResponse upgradeResponse = new ServletUpgradeResponse(negotiation); - - Object websocketPojo = creator.createWebSocket(upgradeRequest, upgradeResponse); - - // Handling for response forbidden (and similar paths) - if (upgradeResponse.isCommitted()) - return null; - - if (websocketPojo == null) - { - // no creation, sorry - upgradeResponse.sendError(SC_SERVICE_UNAVAILABLE, "WebSocket Endpoint Creation Refused"); - return null; - } - - FrameHandler frameHandler = factory.newFrameHandler(websocketPojo, upgradeRequest, upgradeResponse); - if (frameHandler != null) - return frameHandler; - + // no creation, sorry + upgradeResponse.sendError(SC_SERVICE_UNAVAILABLE, "WebSocket Endpoint Creation Refused"); return null; } - finally - { - Thread.currentThread().setContextClassLoader(old); - } + + return factory.newFrameHandler(websocketPojo, upgradeRequest, upgradeResponse); } @Override diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java index c818781d191..6a3e00a84bf 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; @@ -29,11 +29,11 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Abstract Servlet used to bridge the Servlet API to the WebSocket API. @@ -88,7 +88,7 @@ import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; @SuppressWarnings("serial") public abstract class WebSocketServlet extends HttpServlet { - private static final Logger LOG = Log.getLogger(WebSocketServlet.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketServlet.class); private final CustomizedWebSocketServletFactory customizer = new CustomizedWebSocketServletFactory(); private WebSocketMapping mapping; @@ -181,7 +181,7 @@ public abstract class WebSocketServlet extends HttpServlet super.service(req, resp); } - private class CustomizedWebSocketServletFactory extends FrameHandler.ConfigurationCustomizer implements WebSocketServletFactory + private class CustomizedWebSocketServletFactory extends Configuration.ConfigurationCustomizer implements WebSocketServletFactory { @Override public WebSocketExtensionRegistry getExtensionRegistry() diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.java index d659b9a95a3..f62a25056e5 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServletFactory.java @@ -1,82 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; -import java.time.Duration; - import org.eclipse.jetty.http.pathmap.PathSpec; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry; -public interface WebSocketServletFactory extends FrameHandler.Configuration +public interface WebSocketServletFactory extends Configuration { - WebSocketExtensionRegistry getExtensionRegistry(); - @Override - Duration getIdleTimeout(); - - @Override - void setIdleTimeout(Duration duration); - - @Override - Duration getWriteTimeout(); - - @Override - void setWriteTimeout(Duration duration); - - @Override - int getInputBufferSize(); - - @Override - void setInputBufferSize(int bufferSize); - - @Override - long getMaxFrameSize(); - - @Override - void setMaxFrameSize(long maxFrameSize); - - @Override - long getMaxBinaryMessageSize(); - - @Override - void setMaxBinaryMessageSize(long bufferSize); - - @Override - long getMaxTextMessageSize(); - - @Override - void setMaxTextMessageSize(long bufferSize); - - @Override - int getOutputBufferSize(); - - @Override - void setOutputBufferSize(int bufferSize); - - @Override - boolean isAutoFragment(); - - @Override - void setAutoFragment(boolean autoFragment); - void addMapping(String pathSpec, WebSocketCreator creator); /** @@ -129,11 +78,11 @@ public interface WebSocketServletFactory extends FrameHandler.Configuration * Recognized Path Spec syntaxes: *

        *
        - *
        /path/to or / or *.ext or servlet|{spec}
        + *
        {@code /path/to} or {@code /} or {@code *.ext} or {@code servlet|{spec}}
        *
        Servlet Syntax
        - *
        ^{spec} or regex|{spec}
        + *
        {@code ^{spec}} or {@code regex|{spec}}
        *
        Regex Syntax
        - *
        uri-template|{spec}
        + *
        {@code uri-template|{spec}}
        *
        URI Template (see JSR356 and RFC6570 level 1)
        *
        * diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketUpgradeFilter.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketUpgradeFilter.java index af5c385e75f..6829d6219a9 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketUpgradeFilter.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketUpgradeFilter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet; @@ -38,10 +38,10 @@ import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.Configuration; import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Inline Servlet Filter to capture WebSocket upgrade requests. @@ -73,7 +73,7 @@ import org.eclipse.jetty.websocket.core.WebSocketComponents; @ManagedObject("WebSocket Upgrade Filter") public class WebSocketUpgradeFilter implements Filter, Dumpable { - private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketUpgradeFilter.class); private static FilterHolder getFilter(ServletContext servletContext) { @@ -125,7 +125,7 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable public static final String MAPPING_ATTRIBUTE_INIT_PARAM = "org.eclipse.jetty.websocket.servlet.WebSocketMapping.key"; - private final FrameHandler.ConfigurationCustomizer defaultCustomizer = new FrameHandler.ConfigurationCustomizer(); + private final Configuration.ConfigurationCustomizer defaultCustomizer = new Configuration.ConfigurationCustomizer(); private WebSocketMapping mapping; @Override diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java index 85fa5b968e6..f2f56dd0be5 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.websocket.servlet.internal; @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; @@ -55,6 +56,7 @@ public class UpgradeHttpServletRequest implements HttpServletRequest { private static final String UNSUPPORTED_WITH_WEBSOCKET_UPGRADE = "Feature unsupported with a Upgraded to WebSocket HttpServletRequest"; + private final Request baseRequest; private final ServletContext context; private final DispatcherType dispatcher; private final String method; @@ -110,8 +112,9 @@ public class UpgradeHttpServletRequest implements HttpServletRequest remoteUser = httpRequest.getRemoteUser(); principal = httpRequest.getUserPrincipal(); - authentication = Request.getBaseRequest(httpRequest).getAuthentication(); - scope = Request.getBaseRequest(httpRequest).getUserIdentityScope(); + baseRequest = Objects.requireNonNull(Request.getBaseRequest(httpRequest)); + authentication = baseRequest.getAuthentication(); + scope = baseRequest.getUserIdentityScope(); Enumeration headerNames = httpRequest.getHeaderNames(); while (headerNames.hasMoreElements()) @@ -278,6 +281,11 @@ public class UpgradeHttpServletRequest implements HttpServletRequest return session; } + public Request getBaseRequest() + { + return baseRequest; + } + @Override public String getRequestedSessionId() { diff --git a/jetty-websocket/websocket-util/pom.xml b/jetty-websocket/websocket-util/pom.xml new file mode 100644 index 00000000000..9412101ce9f --- /dev/null +++ b/jetty-websocket/websocket-util/pom.xml @@ -0,0 +1,69 @@ + + + + org.eclipse.jetty.websocket + websocket-parent + 10.0.0-SNAPSHOT + + + 4.0.0 + websocket-util + Jetty :: Websocket :: org.eclipse.jetty.websocket :: Util + + + ${project.groupId}.util + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + ban-java-servlet-api + + enforce + + + + + + javax.servlet + servletapi + org.eclipse.jetty.orbit:javax.servlet + org.mortbay.jetty:servlet-api + jetty:servlet-api + jetty-servlet-api + + + + + + + + + + + + + org.eclipse.jetty.websocket + websocket-core + ${project.version} + + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + diff --git a/jetty-websocket/websocket-util/src/main/java/module-info.java b/jetty-websocket/websocket-util/src/main/java/module-info.java new file mode 100644 index 00000000000..183e1fd2715 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/module-info.java @@ -0,0 +1,26 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +module org.eclipse.jetty.websocket.util +{ + exports org.eclipse.jetty.websocket.util; + exports org.eclipse.jetty.websocket.util.messages; + + requires org.slf4j; + requires transitive org.eclipse.jetty.websocket.core; +} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/DuplicateAnnotationException.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/DuplicateAnnotationException.java similarity index 53% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/DuplicateAnnotationException.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/DuplicateAnnotationException.java index db7818caead..df3a7b49fa8 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/DuplicateAnnotationException.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/DuplicateAnnotationException.java @@ -1,28 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.common.util; +package org.eclipse.jetty.websocket.util; import java.lang.annotation.Annotation; import java.lang.reflect.Method; -import org.eclipse.jetty.websocket.api.InvalidWebSocketException; - @SuppressWarnings("serial") public class DuplicateAnnotationException extends InvalidWebSocketException { diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/InvalidSignatureException.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvalidSignatureException.java similarity index 61% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/InvalidSignatureException.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvalidSignatureException.java index 7e6f6ea96db..388b0faae47 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/InvalidSignatureException.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvalidSignatureException.java @@ -1,29 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.common.util; +package org.eclipse.jetty.websocket.util; import java.lang.annotation.Annotation; import java.lang.invoke.MethodType; import java.lang.reflect.Method; -import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException; - @SuppressWarnings("serial") public class InvalidSignatureException extends InvalidWebSocketException { diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvalidWebSocketException.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvalidWebSocketException.java new file mode 100644 index 00000000000..8b8329f4e38 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvalidWebSocketException.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util; + +import org.eclipse.jetty.websocket.core.exception.WebSocketException; + +/** + * Indicating that the provided Class is not a valid WebSocket per the chosen API. + */ +@SuppressWarnings("serial") +public class InvalidWebSocketException extends WebSocketException +{ + public InvalidWebSocketException(String message) + { + super(message); + } + + public InvalidWebSocketException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtils.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvokerUtils.java similarity index 85% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtils.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvokerUtils.java index fa160723fdd..c09827cc608 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/util/InvokerUtils.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/InvokerUtils.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.common.util; +package org.eclipse.jetty.websocket.util; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -165,14 +165,15 @@ public class InvokerUtils * the actual method being called. *

        * + * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} instance to use. * @param targetClass the target class for invocations of the resulting MethodHandle (also known as parameter 0) * @param method the method to invoke * @param callingArgs the calling arguments. This is the array of arguments that will always be passed into the returned MethodHandle. * They will be present in the {@link MethodHandle#type()} in the order specified in this array. */ - public static MethodHandle mutatedInvoker(Class targetClass, Method method, Arg... callingArgs) + public static MethodHandle mutatedInvoker(MethodHandles.Lookup lookup, Class targetClass, Method method, Arg... callingArgs) { - return mutatedInvoker(targetClass, method, PARAM_IDENTITY, null, callingArgs); + return mutatedInvoker(lookup, targetClass, true, method, PARAM_IDENTITY, null, callingArgs); } /** @@ -193,6 +194,7 @@ public class InvokerUtils *
      11. The next parameters are all of the provided {@code callingArg} types
      12. * * + * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} instance to use. * @param targetClass the target class for invocations of the resulting MethodHandle (also known as parameter 0) * @param method the method to invoke * @param paramIdentifier the mechanism to identify parameters in method @@ -204,13 +206,13 @@ public class InvokerUtils * @return the MethodHandle for this set of CallingArgs * @throws RuntimeException when unable to fit Calling Args to Parameter Types */ - public static MethodHandle mutatedInvoker(Class targetClass, Method method, ParamIdentifier paramIdentifier, String[] namedVariables, Arg... callingArgs) + public static MethodHandle mutatedInvoker(MethodHandles.Lookup lookup, Class targetClass, Method method, ParamIdentifier paramIdentifier, String[] namedVariables, Arg... callingArgs) { - return mutatedInvoker(targetClass, true, method, paramIdentifier, namedVariables, callingArgs); + return mutatedInvoker(lookup, targetClass, true, method, paramIdentifier, namedVariables, callingArgs); } - @SuppressWarnings("Duplicates") - private static MethodHandle mutatedInvoker(Class targetClass, boolean throwOnFailure, Method method, ParamIdentifier paramIdentifier, + private static MethodHandle mutatedInvoker(MethodHandles.Lookup lookup, Class targetClass, boolean throwOnFailure, + Method method, ParamIdentifier paramIdentifier, String[] namedVariables, Arg... rawCallingArgs) { Class[] parameterTypes = method.getParameterTypes(); @@ -239,17 +241,15 @@ public class InvokerUtils // ParamIdentifier is used to find named parameters (like javax.websocket's @PathParam declaration) boolean hasNamedParamArgs = false; Arg[] parameterArgs = new Arg[parameterTypes.length + 1]; + parameterArgs[0] = new Arg(targetClass); // first type is always the calling object instance type + for (int i = 0; i < parameterTypes.length; i++) { - parameterArgs[0] = new Arg(targetClass); // first type is always the calling object instance type - for (int i = 0; i < parameterTypes.length; i++) + Arg arg = paramIdentifier.getParamArg(method, parameterTypes[i], i); + if (arg.name != null) { - Arg arg = paramIdentifier.getParamArg(method, parameterTypes[i], i); - if (arg.name != null) - { - hasNamedParamArgs = true; - } - parameterArgs[i + 1] = arg; + hasNamedParamArgs = true; } + parameterArgs[i + 1] = arg; } // Parameter to Calling Argument mapping. @@ -289,10 +289,6 @@ public class InvokerUtils cTypes.add(arg.getType()); } } - MethodType callingType = MethodType.methodType(method.getReturnType(), cTypes); - - // Create low level MethodHandle - MethodHandles.Lookup lookup = MethodHandles.lookup(); try { @@ -301,6 +297,7 @@ public class InvokerUtils // the calling 'refc' type of where the method is declared, not the targetClass. // That behavior of #unreflect() results in a MethodType referring to the // base/abstract/interface where the method is declared, and not the targetClass + MethodType callingType = MethodType.methodType(method.getReturnType(), cTypes); MethodType rawType = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); MethodHandle methodHandle = lookup.findVirtual(targetClass, method.getName(), rawType); @@ -444,6 +441,7 @@ public class InvokerUtils *
      13. {@link MethodHandle#invoke(Object...)} - to call the specific method
      14. * * + * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} instance to use. * @param targetClass the target class for invocations of the resulting MethodHandle (also known as parameter 0) * @param method the method to invoke * @param paramIdentifier the mechanism to identify parameters in method @@ -454,10 +452,15 @@ public class InvokerUtils * They will be present in the {@link MethodHandle#type()} in the order specified in this array. * @return the MethodHandle for this set of CallingArgs, or null if not possible to create MethodHandle with CallingArgs to provided method */ - public static MethodHandle optionalMutatedInvoker(Class targetClass, Method method, ParamIdentifier paramIdentifier, String[] namedVariables, - Arg... callingArgs) + public static MethodHandle optionalMutatedInvoker(MethodHandles.Lookup lookup, Class targetClass, Method method, ParamIdentifier paramIdentifier, + String[] namedVariables, Arg... callingArgs) { - return mutatedInvoker(targetClass, false, method, paramIdentifier, namedVariables, callingArgs); + return mutatedInvoker(lookup, targetClass, false, method, paramIdentifier, namedVariables, callingArgs); + } + + public static MethodHandle optionalMutatedInvoker(MethodHandles.Lookup lookup, Class targetClass, Method method, Arg... callingArgs) + { + return mutatedInvoker(lookup, targetClass, false, method, PARAM_IDENTITY, null, callingArgs); } private static void appendTypeList(StringBuilder str, Arg[] args) diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/ReflectUtils.java similarity index 95% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/ReflectUtils.java index 68ff1cc216b..c038b45ead2 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/ReflectUtils.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.common.util; +package org.eclipse.jetty.websocket.util; import java.lang.annotation.Annotation; import java.lang.invoke.MethodType; @@ -30,8 +30,6 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import org.eclipse.jetty.websocket.api.InvalidWebSocketException; - public class ReflectUtils { diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/TextUtil.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/TextUtil.java similarity index 73% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/TextUtil.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/TextUtil.java index f8a358c98f7..21a2a138d1a 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/TextUtil.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/TextUtil.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.common.util; +package org.eclipse.jetty.websocket.util; /** * Collection of utility methods for Text content diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/AbstractMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/AbstractMessageSink.java new file mode 100644 index 00000000000..14d1cc85713 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/AbstractMessageSink.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; +import java.util.Objects; + +import org.eclipse.jetty.websocket.core.CoreSession; + +public abstract class AbstractMessageSink implements MessageSink +{ + protected final CoreSession session; + protected final MethodHandle methodHandle; + + public AbstractMessageSink(CoreSession session, MethodHandle methodHandle) + { + this.session = Objects.requireNonNull(session, "CoreSession"); + this.methodHandle = Objects.requireNonNull(methodHandle, "MethodHandle"); + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ByteArrayMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ByteArrayMessageSink.java new file mode 100644 index 00000000000..1921e36b704 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ByteArrayMessageSink.java @@ -0,0 +1,114 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; + +public class ByteArrayMessageSink extends AbstractMessageSink +{ + private static final byte[] EMPTY_BUFFER = new byte[0]; + private static final int BUFFER_SIZE = 65535; + private ByteArrayOutputStream out; + private int size; + + public ByteArrayMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + + // byte[] buf + MethodType onMessageType = MethodType.methodType(Void.TYPE, byte[].class, int.class, int.class); + if (methodHandle.type().changeReturnType(void.class) != onMessageType.changeReturnType(void.class)) + { + throw InvalidSignatureException.build(onMessageType, methodHandle.type()); + } + } + + @Override + public void accept(Frame frame, Callback callback) + { + try + { + size += frame.getPayloadLength(); + long maxBinaryMessageSize = session.getMaxBinaryMessageSize(); + if (maxBinaryMessageSize > 0 && size > maxBinaryMessageSize) + { + throw new MessageTooLargeException(String.format("Binary message too large: (actual) %,d > (configured max binary message size) %,d", + size, maxBinaryMessageSize)); + } + + // If we are fin and no OutputStream has been created we don't need to aggregate. + if (frame.isFin() && (out == null)) + { + if (frame.hasPayload()) + { + byte[] buf = BufferUtil.toArray(frame.getPayload()); + methodHandle.invoke(buf, 0, buf.length); + } + else + methodHandle.invoke(EMPTY_BUFFER, 0, 0); + + callback.succeeded(); + return; + } + + aggregatePayload(frame); + if (frame.isFin()) + { + byte[] buf = out.toByteArray(); + methodHandle.invoke(buf, 0, buf.length); + } + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + finally + { + if (frame.isFin()) + { + // reset + out = null; + size = 0; + } + } + } + + private void aggregatePayload(Frame frame) throws IOException + { + if (frame.hasPayload()) + { + ByteBuffer payload = frame.getPayload(); + if (out == null) + out = new ByteArrayOutputStream(BUFFER_SIZE); + BufferUtil.writeTo(payload, out); + } + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ByteBufferMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ByteBufferMessageSink.java new file mode 100644 index 00000000000..0c255e4e267 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ByteBufferMessageSink.java @@ -0,0 +1,113 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.nio.ByteBuffer; +import java.util.Objects; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; + +public class ByteBufferMessageSink extends AbstractMessageSink +{ + private static final int BUFFER_SIZE = 65535; + private ByteArrayOutputStream out; + private int size; + + public ByteBufferMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + + // Validate onMessageMethod + Objects.requireNonNull(methodHandle, "MethodHandle"); + MethodType onMessageType = MethodType.methodType(Void.TYPE, ByteBuffer.class); + if (methodHandle.type() != onMessageType) + { + throw InvalidSignatureException.build(onMessageType, methodHandle.type()); + } + } + + @Override + public void accept(Frame frame, Callback callback) + { + try + { + size += frame.getPayloadLength(); + long maxBinaryMessageSize = session.getMaxBinaryMessageSize(); + if (maxBinaryMessageSize > 0 && size > maxBinaryMessageSize) + { + throw new MessageTooLargeException(String.format("Binary message too large: (actual) %,d > (configured max binary message size) %,d", + size, maxBinaryMessageSize)); + } + + // If we are fin and no OutputStream has been created we don't need to aggregate. + if (frame.isFin() && (out == null)) + { + if (frame.hasPayload()) + methodHandle.invoke(frame.getPayload()); + else + methodHandle.invoke(BufferUtil.EMPTY_BUFFER); + + callback.succeeded(); + return; + } + + aggregatePayload(frame); + if (frame.isFin()) + methodHandle.invoke(ByteBuffer.wrap(out.toByteArray())); + + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + finally + { + if (frame.isFin()) + { + // reset + out = null; + size = 0; + } + } + } + + private void aggregatePayload(Frame frame) throws IOException + { + if (frame.hasPayload()) + { + ByteBuffer payload = frame.getPayload(); + + if (out == null) + out = new ByteArrayOutputStream(BUFFER_SIZE); + + BufferUtil.writeTo(payload, out); + payload.position(payload.limit()); // consume buffer + } + } +} diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/DispatchedMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/DispatchedMessageSink.java similarity index 59% rename from jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/DispatchedMessageSink.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/DispatchedMessageSink.java index 5c65e53dc3d..805dd70790f 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/DispatchedMessageSink.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/DispatchedMessageSink.java @@ -1,31 +1,30 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.common.message; +package org.eclipse.jetty.websocket.util.messages; +import java.io.Closeable; import java.lang.invoke.MethodHandle; -import java.util.Objects; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.websocket.common.AbstractMessageSink; -import org.eclipse.jetty.websocket.common.MessageSink; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; /** @@ -96,19 +95,15 @@ import org.eclipse.jetty.websocket.core.Frame; * EOF stream.read EOF * RESUME(NEXT MSG) * - * - * @param the type of object to give to user function - * @param the type of object that user function will return */ -public abstract class DispatchedMessageSink extends AbstractMessageSink +public abstract class DispatchedMessageSink extends AbstractMessageSink { private CompletableFuture dispatchComplete; private MessageSink typeSink; - public DispatchedMessageSink(Executor executor, MethodHandle methodHandle) + public DispatchedMessageSink(CoreSession session, MethodHandle methodHandle) { - super(executor, methodHandle); - Objects.requireNonNull(this.executor, "Executor"); + super(session, methodHandle); } public abstract MessageSink newSink(Frame frame); @@ -118,57 +113,45 @@ public abstract class DispatchedMessageSink extends AbstractMessageSink if (typeSink == null) { typeSink = newSink(frame); - // Dispatch to end user function (will likely start with blocking for data/accept) dispatchComplete = new CompletableFuture<>(); - executor.execute(() -> + + // Dispatch to end user function (will likely start with blocking for data/accept). + // If the MessageSink can be closed do this after invoking and before completing the CompletableFuture. + new Thread(() -> { - final T dispatchedType = (T)typeSink; try { - methodHandle.invoke(dispatchedType); + methodHandle.invoke(typeSink); + if (typeSink instanceof Closeable) + IO.close((Closeable)typeSink); + dispatchComplete.complete(null); } catch (Throwable throwable) { + if (typeSink instanceof Closeable) + IO.close((Closeable)typeSink); + dispatchComplete.completeExceptionally(throwable); } - }); + }).start(); } - final Callback frameCallback; - + Callback frameCallback = callback; if (frame.isFin()) { - CompletableFuture finComplete = new CompletableFuture<>(); - frameCallback = new Callback() + // This is the final frame we should wait for the frame callback and the dispatched thread. + Callback.Completable completableCallback = new Callback.Completable(); + frameCallback = completableCallback; + CompletableFuture.allOf(dispatchComplete, completableCallback).whenComplete((aVoid, throwable) -> { - @Override - public void failed(Throwable cause) - { - finComplete.completeExceptionally(cause); - } - - @Override - public void succeeded() - { - finComplete.complete(null); - } - }; - CompletableFuture.allOf(dispatchComplete, finComplete).whenComplete( - (aVoid, throwable) -> - { - typeSink = null; - dispatchComplete = null; - if (throwable != null) - callback.failed(throwable); - else - callback.succeeded(); - }); - } - else - { - // Non-fin-frame - frameCallback = callback; + typeSink = null; + dispatchComplete = null; + if (throwable != null) + callback.failed(throwable); + else + callback.succeeded(); + }); } typeSink.accept(frame, frameCallback); diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/InputStreamMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/InputStreamMessageSink.java new file mode 100644 index 00000000000..161b367dd2e --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/InputStreamMessageSink.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; + +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; + +public class InputStreamMessageSink extends DispatchedMessageSink +{ + public InputStreamMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + } + + @Override + public MessageSink newSink(Frame frame) + { + return new MessageInputStream(); + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageInputStream.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageInputStream.java new file mode 100644 index 00000000000..54ed65b55bd --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageInputStream.java @@ -0,0 +1,238 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.Frame; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Support class for reading a WebSocket BINARY message via a InputStream. + *

        + * An InputStream that can access a queue of ByteBuffer payloads, along with expected InputStream blocking behavior. + *

        + */ +public class MessageInputStream extends InputStream implements MessageSink +{ + private static final Logger LOG = LoggerFactory.getLogger(MessageInputStream.class); + private static final Entry EOF = new Entry(BufferUtil.EMPTY_BUFFER, Callback.NOOP); + private static final Entry CLOSED = new Entry(BufferUtil.EMPTY_BUFFER, Callback.NOOP); + private final BlockingArrayQueue buffers = new BlockingArrayQueue<>(); + private boolean closed = false; + private Entry currentEntry; + private long timeoutMs = -1; + + @Override + public void accept(Frame frame, Callback callback) + { + if (LOG.isDebugEnabled()) + LOG.debug("accepting {}", frame); + + boolean succeed = false; + synchronized (this) + { + // If closed or we have no payload, request the next frame. + if (closed || (!frame.hasPayload() && !frame.isFin())) + { + succeed = true; + } + else + { + if (frame.hasPayload()) + buffers.add(new Entry(frame.getPayload(), callback)); + else + succeed = true; + + if (frame.isFin()) + buffers.add(EOF); + } + } + + if (succeed) + callback.succeeded(); + } + + @Override + public int read() throws IOException + { + byte[] buf = new byte[1]; + while (true) + { + int len = read(buf, 0, 1); + if (len < 0) // EOF + return -1; + if (len > 0) // did read something + return buf[0]; + // reading nothing (len == 0) tries again + } + } + + @Override + public int read(final byte[] b, final int off, final int len) throws IOException + { + return read(ByteBuffer.wrap(b, off, len).flip()); + } + + public int read(ByteBuffer buffer) throws IOException + { + Entry currentEntry = getCurrentEntry(); + if (LOG.isDebugEnabled()) + LOG.debug("currentEntry = {}", currentEntry); + + if (currentEntry == CLOSED) + throw new IOException("Closed"); + + if (currentEntry == EOF) + { + if (LOG.isDebugEnabled()) + LOG.debug("Read EOF"); + return -1; + } + + // We have content. + int fillLen = BufferUtil.append(buffer, currentEntry.buffer); + if (!currentEntry.buffer.hasRemaining()) + succeedCurrentEntry(); + + // Return number of bytes actually copied into buffer. + if (LOG.isDebugEnabled()) + LOG.debug("filled {} bytes from {}", fillLen, currentEntry); + return fillLen; + } + + @Override + public void close() throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("close()"); + + ArrayList entries = new ArrayList<>(); + synchronized (this) + { + if (closed) + return; + closed = true; + + if (currentEntry != null) + { + entries.add(currentEntry); + currentEntry = null; + } + + // Clear queue and fail all entries. + entries.addAll(buffers); + buffers.clear(); + buffers.offer(CLOSED); + } + + // Succeed all entries as we don't need them anymore (failing would close the connection). + for (Entry e : entries) + { + e.callback.succeeded(); + } + + super.close(); + } + + public void setTimeout(long timeoutMs) + { + this.timeoutMs = timeoutMs; + } + + private void succeedCurrentEntry() + { + Entry current; + synchronized (this) + { + current = currentEntry; + currentEntry = null; + } + if (current != null) + current.callback.succeeded(); + } + + private Entry getCurrentEntry() throws IOException + { + synchronized (this) + { + if (currentEntry != null) + return currentEntry; + } + + try + { + if (LOG.isDebugEnabled()) + LOG.debug("Waiting {} ms to read", timeoutMs); + + Entry result; + if (timeoutMs < 0) + { + // Wait forever until a buffer is available. + result = buffers.take(); + } + else + { + // Wait at most for the given timeout. + result = buffers.poll(timeoutMs, TimeUnit.MILLISECONDS); + if (result == null) + throw new IOException(String.format("Read timeout: %,dms expired", timeoutMs)); + } + + synchronized (this) + { + currentEntry = result; + return currentEntry; + } + } + catch (InterruptedException e) + { + close(); + throw new InterruptedIOException(); + } + } + + private static class Entry + { + public ByteBuffer buffer; + public Callback callback; + + public Entry(ByteBuffer buffer, Callback callback) + { + this.buffer = Objects.requireNonNull(buffer); + this.callback = callback; + } + + @Override + public String toString() + { + return String.format("Entry[%s,%s]", BufferUtil.toDetailString(buffer), callback.getClass().getSimpleName()); + } + } +} diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageOutputStream.java similarity index 54% rename from jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java rename to jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageOutputStream.java index 08399e92420..389fd20eaf5 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageOutputStream.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.common.messages; +package org.eclipse.jetty.websocket.util.messages; import java.io.IOException; import java.io.OutputStream; @@ -25,38 +25,41 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Support for writing a single WebSocket BINARY message via a {@link OutputStream} */ public class MessageOutputStream extends OutputStream { - private static final Logger LOG = Log.getLogger(MessageOutputStream.class); + private static final Logger LOG = LoggerFactory.getLogger(MessageOutputStream.class); - private final FrameHandler.CoreSession coreSession; + private final CoreSession coreSession; private final ByteBufferPool bufferPool; - private final SharedBlockingCallback blocker; + private final int bufferSize; private long frameCount; private long bytesSent; - private Frame frame; private ByteBuffer buffer; private Callback callback; private boolean closed; + private byte messageOpCode = OpCode.BINARY; - public MessageOutputStream(FrameHandler.CoreSession coreSession, int bufferSize, ByteBufferPool bufferPool) + public MessageOutputStream(CoreSession coreSession, ByteBufferPool bufferPool) { this.coreSession = coreSession; this.bufferPool = bufferPool; - this.blocker = new SharedBlockingCallback(); + this.bufferSize = coreSession.getOutputBufferSize(); this.buffer = bufferPool.acquire(bufferSize, true); - BufferUtil.flipToFill(buffer); - this.frame = new Frame(OpCode.BINARY); + } + + void setMessageType(byte opcode) + { + this.messageOpCode = opcode; } @Override @@ -64,7 +67,7 @@ public class MessageOutputStream extends OutputStream { try { - send(bytes, off, len); + send(ByteBuffer.wrap(bytes, off, len)); } catch (Throwable x) { @@ -79,7 +82,21 @@ public class MessageOutputStream extends OutputStream { try { - send(new byte[]{(byte)b}, 0, 1); + send(ByteBuffer.wrap(new byte[]{(byte)b})); + } + catch (Throwable x) + { + // Notify without holding locks. + notifyFailure(x); + throw x; + } + } + + public void write(ByteBuffer buffer) throws IOException + { + try + { + send(buffer); } catch (Throwable x) { @@ -112,54 +129,49 @@ public class MessageOutputStream extends OutputStream throw new IOException("Stream is closed"); closed = fin; - - BufferUtil.flipToFlush(buffer, 0); + Frame frame = new Frame(frameCount == 0 ? messageOpCode : OpCode.CONTINUATION); frame.setPayload(buffer); frame.setFin(fin); - try (SharedBlockingCallback.Blocker b = blocker.acquire()) - { - coreSession.sendFrame(frame, b, false); - b.block(); - } + int initialBufferSize = buffer.remaining(); + FutureCallback b = new FutureCallback(); + coreSession.sendFrame(frame, b, false); + b.block(); - ++frameCount; // Any flush after the first will be a CONTINUATION frame. - frame = new Frame(OpCode.CONTINUATION); + bytesSent += initialBufferSize; + ++frameCount; - // Buffer has been sent, buffer should have been consumed - assert buffer.remaining() == 0; - - BufferUtil.clearToFill(buffer); + // Buffer has been sent, but buffer should not have been consumed. + try + { + assert buffer.remaining() == initialBufferSize; + BufferUtil.clear(buffer); + } + catch (Throwable t) + { + t.printStackTrace(); + } } } - private void send(byte[] bytes, final int offset, final int length) throws IOException + private void send(ByteBuffer data) throws IOException { synchronized (this) { if (closed) throw new IOException("Stream is closed"); - int remaining = length; - int off = offset; - while (remaining > 0) + while (data.hasRemaining()) { - // There may be no space available, we want - // to handle correctly when space == 0. - int space = buffer.remaining(); - int size = Math.min(space, remaining); - buffer.put(bytes, off, size); - off += size; - remaining -= size; - if (remaining > 0) - { - // If we could not write everything, it means - // that the buffer was full, so flush it. + int bufferRemainingSpace = bufferSize - buffer.remaining(); + int copied = Math.min(bufferRemainingSpace, data.remaining()); + BufferUtil.append(buffer, data.array(), data.arrayOffset() + data.position(), copied); + data.position(data.position() + copied); + + if (data.hasRemaining()) flush(false); - } } - bytesSent += length; } } diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageReader.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageReader.java new file mode 100644 index 00000000000..e20e7da922e --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageReader.java @@ -0,0 +1,100 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.io.IOException; +import java.io.Reader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.WebSocketConstants; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Support class for reading a (single) WebSocket TEXT message via a Reader. + *

        + * In compliance to the WebSocket spec, this reader always uses the {@link StandardCharsets#UTF_8}. + */ +public class MessageReader extends Reader implements MessageSink +{ + private static final int BUFFER_SIZE = WebSocketConstants.DEFAULT_INPUT_BUFFER_SIZE; + + private final ByteBuffer buffer; + private final MessageInputStream stream; + private final CharsetDecoder utf8Decoder = UTF_8.newDecoder() + .onUnmappableCharacter(CodingErrorAction.REPORT) + .onMalformedInput(CodingErrorAction.REPORT); + + public MessageReader() + { + this(BUFFER_SIZE); + } + + public MessageReader(int bufferSize) + { + this.stream = new MessageInputStream(); + this.buffer = BufferUtil.allocate(bufferSize); + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException + { + CharBuffer charBuffer = CharBuffer.wrap(cbuf, off, len); + boolean endOfInput = false; + while (true) + { + int read = stream.read(buffer); + if (read == 0) + break; + if (read < 0) + { + endOfInput = true; + break; + } + } + + CoderResult result = utf8Decoder.decode(buffer, charBuffer, endOfInput); + if (result.isError()) + result.throwException(); + + if (endOfInput && (charBuffer.position() == 0)) + return -1; + return charBuffer.position(); + } + + @Override + public void close() throws IOException + { + stream.close(); + } + + @Override + public void accept(Frame frame, Callback callback) + { + stream.accept(frame, callback); + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageSink.java new file mode 100644 index 00000000000..d1b5842d2c5 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageSink.java @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.Frame; + +/** + * Sink consumer for messages (used for multiple frames with continuations, + * and also to allow for streaming APIs) + */ +public interface MessageSink +{ + /** + * Consume the frame payload to the message. + * + * @param frame the frame, its payload (and fin state) to append + * @param callback the callback for how the frame was consumed + */ + void accept(Frame frame, Callback callback); +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageWriter.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageWriter.java new file mode 100644 index 00000000000..4dbde70a72d --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/MessageWriter.java @@ -0,0 +1,75 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.io.IOException; +import java.io.Writer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.OpCode; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Support for writing a single WebSocket TEXT message via a {@link Writer} + *

        + * Note: Per WebSocket spec, all WebSocket TEXT messages must be encoded in UTF-8 + */ +public class MessageWriter extends Writer +{ + private final MessageOutputStream outputStream; + private final CharsetEncoder utf8Encoder = UTF_8.newEncoder() + .onUnmappableCharacter(CodingErrorAction.REPORT) + .onMalformedInput(CodingErrorAction.REPORT); + + public MessageWriter(CoreSession coreSession, ByteBufferPool bufferPool) + { + this.outputStream = new MessageOutputStream(coreSession, bufferPool); + this.outputStream.setMessageType(OpCode.TEXT); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException + { + CharBuffer charBuffer = CharBuffer.wrap(cbuf, off, len); + outputStream.write(utf8Encoder.encode(charBuffer)); + } + + @Override + public void flush() throws IOException + { + outputStream.flush(); + } + + @Override + public void close() throws IOException + { + outputStream.close(); + } + + public void setCallback(Callback callback) + { + outputStream.setCallback(callback); + } +} \ No newline at end of file diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialByteArrayMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialByteArrayMessageSink.java new file mode 100644 index 00000000000..a42c3577837 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialByteArrayMessageSink.java @@ -0,0 +1,64 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.util.InvalidSignatureException; + +public class PartialByteArrayMessageSink extends AbstractMessageSink +{ + private static byte[] EMPTY_BUFFER = new byte[0]; + + public PartialByteArrayMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + + // byte[] buf, int offset, int length + MethodType onMessageType = MethodType.methodType(Void.TYPE, byte[].class, int.class, int.class, boolean.class); + if (methodHandle.type() != onMessageType) + { + throw InvalidSignatureException.build(onMessageType, methodHandle.type()); + } + } + + @Override + public void accept(Frame frame, Callback callback) + { + try + { + if (frame.hasPayload() || frame.isFin()) + { + byte[] buffer = frame.hasPayload() ? BufferUtil.toArray(frame.getPayload()) : EMPTY_BUFFER; + methodHandle.invoke(buffer, 0, buffer.length, frame.isFin()); + } + + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialByteBufferMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialByteBufferMessageSink.java new file mode 100644 index 00000000000..ce00ee7acef --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialByteBufferMessageSink.java @@ -0,0 +1,57 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; + +public class PartialByteBufferMessageSink extends AbstractMessageSink +{ + public PartialByteBufferMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + + /* TODO: Review + MethodType onMessageType = MethodType.methodType(Void.TYPE, ByteBuffer.class, boolean.class); + if (methodHandle.type() != onMessageType) + { + throw InvalidSignatureException.build(onMessageType, methodHandle.type()); + } + */ + } + + @Override + public void accept(Frame frame, Callback callback) + { + try + { + if (frame.hasPayload() || frame.isFin()) + methodHandle.invoke(frame.getPayload(), frame.isFin()); + + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialStringMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialStringMessageSink.java new file mode 100644 index 00000000000..457bb1461ea --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/PartialStringMessageSink.java @@ -0,0 +1,65 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; +import java.util.Objects; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Utf8StringBuilder; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; + +public class PartialStringMessageSink extends AbstractMessageSink +{ + private Utf8StringBuilder out; + + public PartialStringMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + Objects.requireNonNull(methodHandle, "MethodHandle"); + } + + @Override + public void accept(Frame frame, Callback callback) + { + try + { + if (out == null) + out = new Utf8StringBuilder(session.getInputBufferSize()); + + out.append(frame.getPayload()); + if (frame.isFin()) + { + methodHandle.invoke(out.toString(), true); + out = null; + } + else + { + methodHandle.invoke(out.takePartialString(), false); + } + + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ReaderMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ReaderMessageSink.java new file mode 100644 index 00000000000..df70a7cc7b8 --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/ReaderMessageSink.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; + +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; + +public class ReaderMessageSink extends DispatchedMessageSink +{ + public ReaderMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + } + + @Override + public MessageReader newSink(Frame frame) + { + return new MessageReader(session.getInputBufferSize()); + } +} diff --git a/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/StringMessageSink.java b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/StringMessageSink.java new file mode 100644 index 00000000000..78fef1afb1b --- /dev/null +++ b/jetty-websocket/websocket-util/src/main/java/org/eclipse/jetty/websocket/util/messages/StringMessageSink.java @@ -0,0 +1,76 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util.messages; + +import java.lang.invoke.MethodHandle; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Utf8StringBuilder; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; + +public class StringMessageSink extends AbstractMessageSink +{ + private Utf8StringBuilder out; + private int size; + + public StringMessageSink(CoreSession session, MethodHandle methodHandle) + { + super(session, methodHandle); + this.size = 0; + } + + @Override + public void accept(Frame frame, Callback callback) + { + try + { + size += frame.getPayloadLength(); + long maxTextMessageSize = session.getMaxTextMessageSize(); + if (maxTextMessageSize > 0 && size > maxTextMessageSize) + { + throw new MessageTooLargeException(String.format("Text message too large: (actual) %,d > (configured max text message size) %,d", + size, maxTextMessageSize)); + } + + if (out == null) + out = new Utf8StringBuilder(session.getInputBufferSize()); + + out.append(frame.getPayload()); + if (frame.isFin()) + methodHandle.invoke(out.toString()); + + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + finally + { + if (frame.isFin()) + { + // reset + size = 0; + out = null; + } + } + } +} diff --git a/jetty-websocket/websocket-util/src/test/java/org/eclipse/jetty/websocket/util/MessageReaderTest.java b/jetty-websocket/websocket-util/src/test/java/org/eclipse/jetty/websocket/util/MessageReaderTest.java new file mode 100644 index 00000000000..eb676efec42 --- /dev/null +++ b/jetty-websocket/websocket-util/src/test/java/org/eclipse/jetty/websocket/util/MessageReaderTest.java @@ -0,0 +1,139 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.MalformedInputException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.util.messages.MessageReader; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class MessageReaderTest +{ + private final MessageReader reader = new MessageReader(); + private final CompletableFuture message = new CompletableFuture<>(); + private boolean first = true; + + @BeforeEach + public void before() + { + // Read the message in a different thread. + new Thread(() -> + { + try + { + message.complete(IO.toString(reader)); + } + catch (IOException e) + { + message.completeExceptionally(e); + } + }).start(); + } + + @Test + public void testSingleFrameMessage() throws Exception + { + giveString("hello world!", true); + + String s = message.get(5, TimeUnit.SECONDS); + assertThat(s, is("hello world!")); + } + + @Test + public void testFragmentedMessage() throws Exception + { + giveString("hello", false); + giveString(" ", false); + giveString("world", false); + giveString("!", true); + + String s = message.get(5, TimeUnit.SECONDS); + assertThat(s, is("hello world!")); + } + + @Test + public void testEmptySegments() throws Exception + { + giveString("", false); + giveString("hello ", false); + giveString("", false); + giveString("", false); + giveString("world!", false); + giveString("", false); + giveString("", true); + + String s = message.get(5, TimeUnit.SECONDS); + assertThat(s, is("hello world!")); + } + + @Test + public void testCloseStream() throws Exception + { + giveString("hello ", false); + reader.close(); + giveString("world!", true); + + ExecutionException error = assertThrows(ExecutionException.class, () -> message.get(5, TimeUnit.SECONDS)); + Throwable cause = error.getCause(); + assertThat(cause, instanceOf(IOException.class)); + assertThat(cause.getMessage(), is("Closed")); + } + + @Test + public void testInvalidUtf8() throws Exception + { + ByteBuffer invalidUtf8Payload = BufferUtil.toBuffer(new byte[]{0x7F, (byte)0xFF, (byte)0xFF}); + giveByteBuffer(invalidUtf8Payload, true); + + ExecutionException error = assertThrows(ExecutionException.class, () -> message.get(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(MalformedInputException.class)); + } + + private void giveString(String s, boolean last) throws IOException + { + giveByteBuffer(ByteBuffer.wrap(StringUtil.getUtf8Bytes(s)), last); + } + + private void giveByteBuffer(ByteBuffer buffer, boolean last) throws IOException + { + byte opCode = first ? OpCode.TEXT : OpCode.CONTINUATION; + Frame frame = new Frame(opCode, last, buffer); + FutureCallback callback = new FutureCallback(); + reader.accept(frame, callback); + callback.block(5, TimeUnit.SECONDS); + first = false; + } +} diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/MessageWriterTest.java b/jetty-websocket/websocket-util/src/test/java/org/eclipse/jetty/websocket/util/MessageWriterTest.java similarity index 53% rename from jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/MessageWriterTest.java rename to jetty-websocket/websocket-util/src/test/java/org/eclipse/jetty/websocket/util/MessageWriterTest.java index 24efba23ce2..a1c26f60f69 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/messages/MessageWriterTest.java +++ b/jetty-websocket/websocket-util/src/test/java/org/eclipse/jetty/websocket/util/MessageWriterTest.java @@ -1,46 +1,115 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.websocket.javax.common.messages; +package org.eclipse.jetty.websocket.util; import java.io.IOException; +import java.nio.charset.MalformedInputException; import java.util.Arrays; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Utf8StringBuilder; +import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.util.messages.MessageWriter; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; public class MessageWriterTest { + private final CoreSession coreSession = new CoreSession.Empty(); + private final ByteBufferPool bufferPool = new MappedByteBufferPool(); + @Test - public void testSingleByteArray_512b() throws IOException, InterruptedException + public void testMultipleWrites() throws Exception + { + WholeMessageCapture capture = new WholeMessageCapture(); + try (MessageWriter stream = new MessageWriter(capture, bufferPool)) + { + stream.write("Hello"); + stream.write(" "); + stream.write("World"); + } + + assertThat("Socket.messageQueue.size", capture.messages.size(), is(1)); + String msg = capture.messages.poll(); + assertThat("Message", msg, is("Hello World")); + } + + @Test + public void testSingleWrite() throws Exception + { + WholeMessageCapture capture = new WholeMessageCapture(); + try (MessageWriter stream = new MessageWriter(capture, bufferPool)) + { + stream.append("Hello World"); + } + + assertThat("Socket.messageQueue.size", capture.messages.size(), is(1)); + String msg = capture.messages.poll(); + assertThat("Message", msg, is("Hello World")); + } + + @Test + public void testWriteLargeRequiringMultipleBuffers() throws Exception + { + int outputBufferSize = 4096; + int size = (int)(outputBufferSize * 2.5); + char[] buf = new char[size]; + + Arrays.fill(buf, 'x'); + buf[size - 1] = 'o'; // mark last entry for debugging + + WholeMessageCapture capture = new WholeMessageCapture(); + try (MessageWriter stream = new MessageWriter(capture, bufferPool)) + { + stream.write(buf); + } + + assertThat("Socket.messageQueue.size", capture.messages.size(), is(1)); + String msg = capture.messages.poll(); + String expected = new String(buf); + assertThat("Message", msg, is(expected)); + } + + @Test + public void testInvalidUtf8() + { + final String invalidUtf8String = "\uD800"; + MessageWriter writer = new MessageWriter(coreSession, bufferPool); + assertThrows(MalformedInputException.class, () -> writer.write(invalidUtf8String.toCharArray())); + } + + @Test + public void testSingleByteArray512b() throws IOException, InterruptedException { FrameCapture capture = new FrameCapture(); - try (MessageWriter writer = new MessageWriter(capture, 1024)) + capture.setOutputBufferSize(1024); + try (MessageWriter writer = new MessageWriter(capture, bufferPool)) { char[] cbuf = new char[512]; Arrays.fill(cbuf, 'x'); @@ -54,10 +123,11 @@ public class MessageWriterTest } @Test - public void testSingleByteArray_2k() throws IOException, InterruptedException + public void testSingleByteArray2k() throws IOException, InterruptedException { FrameCapture capture = new FrameCapture(); - try (MessageWriter writer = new MessageWriter(capture, 1024)) + capture.setOutputBufferSize(1024); + try (MessageWriter writer = new MessageWriter(capture, bufferPool)) { char[] cbuf = new char[1024 * 2]; Arrays.fill(cbuf, 'x'); @@ -76,14 +146,15 @@ public class MessageWriterTest } @Test - public void testMultipleByteArrays_2k() throws IOException, InterruptedException + public void testMultipleByteArrays2k() throws IOException, InterruptedException { final int testSize = 1024 * 2; final int outputSize = 80; final int writerBufferSize = 100; FrameCapture capture = new FrameCapture(); - try (MessageWriter writer = new MessageWriter(capture, writerBufferSize)) + capture.setOutputBufferSize(writerBufferSize); + try (MessageWriter writer = new MessageWriter(capture, bufferPool)) { char[] cbuf = new char[testSize]; Arrays.fill(cbuf, 'x'); @@ -125,7 +196,8 @@ public class MessageWriterTest final int testSize = writerBufferSize + 16; WholeMessageCapture capture = new WholeMessageCapture(); - try (MessageWriter writer = new MessageWriter(capture, writerBufferSize)) + capture.setOutputBufferSize(writerBufferSize); + try (MessageWriter writer = new MessageWriter(capture, bufferPool)) { char[] cbuf = new char[testSize]; Arrays.fill(cbuf, 'x'); @@ -139,7 +211,7 @@ public class MessageWriterTest assertThat("Message[0].length", message.length(), is(testSize)); } - public static class FrameCapture extends FrameHandler.CoreSession.Empty + public static class FrameCapture extends CoreSession.Empty { public BlockingQueue frames = new LinkedBlockingQueue<>(); @@ -151,7 +223,7 @@ public class MessageWriterTest } } - public static class WholeMessageCapture extends FrameHandler.CoreSession.Empty + public static class WholeMessageCapture extends CoreSession.Empty { public BlockingQueue messages = new LinkedBlockingQueue<>(); @@ -163,7 +235,7 @@ public class MessageWriterTest if (frame.getOpCode() == OpCode.TEXT) activeMessage = new Utf8StringBuilder(); - activeMessage.append(frame.getPayload()); + activeMessage.append(frame.getPayload().slice()); if (frame.isFin()) { diff --git a/jetty-websocket/websocket-util/src/test/org/eclipse/jetty/websocket/util/PartialStringMessageSinkTest.java b/jetty-websocket/websocket-util/src/test/org/eclipse/jetty/websocket/util/PartialStringMessageSinkTest.java new file mode 100644 index 00000000000..1cb9e174fc8 --- /dev/null +++ b/jetty-websocket/websocket-util/src/test/org/eclipse/jetty/websocket/util/PartialStringMessageSinkTest.java @@ -0,0 +1,153 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.Utf8Appendable; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.util.messages.PartialStringMessageSink; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class PartialStringMessageSinkTest +{ + private CoreSession coreSession = new CoreSession.Empty(); + private OnMessageEndpoint endpoint = new OnMessageEndpoint(); + private PartialStringMessageSink messageSink; + + @BeforeEach + public void before() throws Exception + { + messageSink = new PartialStringMessageSink(coreSession, endpoint.getMethodHandle()); + } + + @Test + public void testValidUtf8() throws Exception + { + ByteBuffer utf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90, (byte)0x8D, (byte)0x88}); + + FutureCallback callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, utf8Payload).setFin(true), callback); + callback.block(5, TimeUnit.SECONDS); + + List message = Objects.requireNonNull(endpoint.messages.poll(5, TimeUnit.SECONDS)); + assertThat(message.size(), is(1)); + assertThat(message.get(0), is("\uD800\uDF48")); + } + + @Test + public void testUtf8Continuation() throws Exception + { + ByteBuffer firstUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90}); + ByteBuffer continuationUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0x8D, (byte)0x88}); + + FutureCallback callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, firstUtf8Payload).setFin(false), callback); + callback.block(5, TimeUnit.SECONDS); + + callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, continuationUtf8Payload).setFin(true), callback); + callback.block(5, TimeUnit.SECONDS); + + List message = Objects.requireNonNull(endpoint.messages.poll(5, TimeUnit.SECONDS)); + assertThat(message.size(), is(2)); + assertThat(message.get(0), is("")); + assertThat(message.get(1), is("\uD800\uDF48")); + } + + @Test + public void testInvalidSingleFrameUtf8() throws Exception + { + ByteBuffer invalidUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90, (byte)0x8D}); + + FutureCallback callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, invalidUtf8Payload).setFin(true), callback); + + // Callback should fail and we don't receive the message in the sink. + RuntimeException error = assertThrows(RuntimeException.class, () -> callback.block(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(Utf8Appendable.NotUtf8Exception.class)); + List message = Objects.requireNonNull(endpoint.messages.poll(5, TimeUnit.SECONDS)); + assertTrue(message.isEmpty()); + } + + @Test + public void testInvalidMultiFrameUtf8() throws Exception + { + ByteBuffer firstUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90}); + ByteBuffer continuationUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0x8D}); + + FutureCallback firstCallback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, firstUtf8Payload).setFin(false), firstCallback); + firstCallback.block(5, TimeUnit.SECONDS); + + FutureCallback continuationCallback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, continuationUtf8Payload).setFin(true), continuationCallback); + + // Callback should fail and we only received the first frame which had no full character. + RuntimeException error = assertThrows(RuntimeException.class, () -> continuationCallback.block(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(Utf8Appendable.NotUtf8Exception.class)); + List message = Objects.requireNonNull(endpoint.messages.poll(5, TimeUnit.SECONDS)); + assertThat(message.size(), is(1)); + assertThat(message.get(0), is("")); + } + + public static class OnMessageEndpoint + { + private BlockingArrayQueue> messages; + + public OnMessageEndpoint() + { + messages = new BlockingArrayQueue<>(); + messages.add(new ArrayList<>()); + } + + public void onMessage(String message, boolean last) + { + messages.get(messages.size() - 1).add(message); + if (last) + messages.add(new ArrayList<>()); + } + + public MethodHandle getMethodHandle() throws Exception + { + return MethodHandles.lookup() + .findVirtual(this.getClass(), "onMessage", MethodType.methodType(void.class, String.class, boolean.class)) + .bindTo(this); + } + } +} diff --git a/jetty-websocket/websocket-util/src/test/org/eclipse/jetty/websocket/util/StringMessageSinkTest.java b/jetty-websocket/websocket-util/src/test/org/eclipse/jetty/websocket/util/StringMessageSinkTest.java new file mode 100644 index 00000000000..f876c52a942 --- /dev/null +++ b/jetty-websocket/websocket-util/src/test/org/eclipse/jetty/websocket/util/StringMessageSinkTest.java @@ -0,0 +1,147 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.websocket.util; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.Utf8Appendable; +import org.eclipse.jetty.websocket.core.CoreSession; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException; +import org.eclipse.jetty.websocket.util.messages.StringMessageSink; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class StringMessageSinkTest +{ + private CoreSession coreSession = new CoreSession.Empty(); + private OnMessageEndpoint endpoint = new OnMessageEndpoint(); + + @Test + public void testMaxMessageSize() throws Exception + { + StringMessageSink messageSink = new StringMessageSink(coreSession, endpoint.getMethodHandle()); + ByteBuffer utf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90, (byte)0x8D, (byte)0x88}); + + FutureCallback callback = new FutureCallback(); + coreSession.setMaxTextMessageSize(3); + messageSink.accept(new Frame(OpCode.TEXT, utf8Payload).setFin(true), callback); + + // Callback should fail and we don't receive the message in the sink. + RuntimeException error = assertThrows(RuntimeException.class, () -> callback.block(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(MessageTooLargeException.class)); + assertNull(endpoint.messages.poll()); + } + + @Test + public void testValidUtf8() throws Exception + { + StringMessageSink messageSink = new StringMessageSink(coreSession, endpoint.getMethodHandle()); + ByteBuffer utf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90, (byte)0x8D, (byte)0x88}); + + FutureCallback callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, utf8Payload).setFin(true), callback); + callback.block(5, TimeUnit.SECONDS); + + assertThat(endpoint.messages.poll(5, TimeUnit.SECONDS), is("\uD800\uDF48")); + } + + @Test + public void testUtf8Continuation() throws Exception + { + StringMessageSink messageSink = new StringMessageSink(coreSession, endpoint.getMethodHandle()); + ByteBuffer firstUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90}); + ByteBuffer continuationUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0x8D, (byte)0x88}); + + FutureCallback callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, firstUtf8Payload).setFin(false), callback); + callback.block(5, TimeUnit.SECONDS); + + callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, continuationUtf8Payload).setFin(true), callback); + callback.block(5, TimeUnit.SECONDS); + + assertThat(endpoint.messages.poll(5, TimeUnit.SECONDS), is("\uD800\uDF48")); + } + + @Test + public void testInvalidSingleFrameUtf8() throws Exception + { + StringMessageSink messageSink = new StringMessageSink(coreSession, endpoint.getMethodHandle()); + ByteBuffer invalidUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90, (byte)0x8D}); + + FutureCallback callback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, invalidUtf8Payload).setFin(true), callback); + + // Callback should fail and we don't receive the message in the sink. + RuntimeException error = assertThrows(RuntimeException.class, () -> callback.block(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(Utf8Appendable.NotUtf8Exception.class)); + assertNull(endpoint.messages.poll()); + } + + @Test + public void testInvalidMultiFrameUtf8() throws Exception + { + StringMessageSink messageSink = new StringMessageSink(coreSession, endpoint.getMethodHandle()); + ByteBuffer firstUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0xF0, (byte)0x90}); + ByteBuffer continuationUtf8Payload = BufferUtil.toBuffer(new byte[]{(byte)0x8D}); + + FutureCallback firstCallback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, firstUtf8Payload).setFin(false), firstCallback); + firstCallback.block(5, TimeUnit.SECONDS); + + FutureCallback continuationCallback = new FutureCallback(); + messageSink.accept(new Frame(OpCode.TEXT, continuationUtf8Payload).setFin(true), continuationCallback); + + // Callback should fail and we don't receive the message in the sink. + RuntimeException error = assertThrows(RuntimeException.class, () -> continuationCallback.block(5, TimeUnit.SECONDS)); + assertThat(error.getCause(), instanceOf(Utf8Appendable.NotUtf8Exception.class)); + assertNull(endpoint.messages.poll()); + } + + public static class OnMessageEndpoint + { + private BlockingArrayQueue messages = new BlockingArrayQueue<>(); + + public void onMessage(String message) + { + messages.add(message); + } + + public MethodHandle getMethodHandle() throws Exception + { + return MethodHandles.lookup() + .findVirtual(this.getClass(), "onMessage", MethodType.methodType(void.class, String.class)) + .bindTo(this); + } + } +} diff --git a/jetty-websocket/websocket-util/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-util/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..376b9b6babb --- /dev/null +++ b/jetty-websocket/websocket-util/src/test/resources/jetty-logging.properties @@ -0,0 +1 @@ +# Jetty Logging using jetty-slf4j-impl diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index be891ef3f1b..038206e3ecb 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -40,6 +40,15 @@ jetty-util ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-xml/src/main/java/module-info.java b/jetty-xml/src/main/java/module-info.java index 946d8dfab96..6c26b215b96 100644 --- a/jetty-xml/src/main/java/module-info.java +++ b/jetty-xml/src/main/java/module-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import org.eclipse.jetty.xml.ConfigurationProcessorFactory; @@ -22,8 +22,9 @@ module org.eclipse.jetty.xml { exports org.eclipse.jetty.xml; - requires java.xml; - requires org.eclipse.jetty.util; + requires transitive java.xml; + requires transitive org.eclipse.jetty.util; + requires org.slf4j; uses ConfigurationProcessorFactory; } diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessor.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessor.java index 1262e44df63..bcdf656ceee 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessor.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessor.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java index 7f05892c7d5..e25e5147b81 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java index 56c990f2592..630b4f92bf1 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index dd4000c758f..c3cca7ec114 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; @@ -23,10 +23,12 @@ import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; @@ -36,11 +38,12 @@ import java.nio.file.Paths; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -49,8 +52,9 @@ import java.util.Properties; import java.util.Queue; import java.util.ServiceLoader; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; -import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.MultiException; @@ -58,9 +62,9 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; /** @@ -80,22 +84,67 @@ import org.xml.sax.SAXException; */ public class XmlConfiguration { - private static final Logger LOG = Log.getLogger(XmlConfiguration.class); - private static final Class[] __primitives = + private static final Logger LOG = LoggerFactory.getLogger(XmlConfiguration.class); + private static final Class[] PRIMITIVES = + { + Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE + }; + private static final Class[] BOXED_PRIMITIVES = + { + Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, + Void.class + }; + private static final Class[] SUPPORTED_COLLECTIONS = + { + ArrayList.class, HashSet.class, Queue.class, List.class, Set.class, Collection.class + }; + private static final List PROCESSOR_FACTORIES = TypeUtil.serviceProviderStream(ServiceLoader.load(ConfigurationProcessorFactory.class)) + .flatMap(p -> Stream.of(p.get())) + .collect(Collectors.toList()); + private static final XmlParser PARSER = initParser(); + public static final Comparator EXECUTABLE_COMPARATOR = (e1, e2) -> { - Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE + // Favour methods with less parameters + int count = e1.getParameterCount(); + int compare = Integer.compare(count, e2.getParameterCount()); + if (compare == 0 && count > 0) + { + Parameter[] p1 = e1.getParameters(); + Parameter[] p2 = e2.getParameters(); + + // Favour methods without varargs + compare = Boolean.compare(p1[count - 1].isVarArgs(), p2[count - 1].isVarArgs()); + if (compare == 0) + { + // Rank by differences in the parameters + for (int i = 0; i < count; i++) + { + Class t1 = p1[i].getType(); + Class t2 = p2[i].getType(); + if (t1 != t2) + { + // Favour derived type over base type + compare = Boolean.compare(t1.isAssignableFrom(t2), t2.isAssignableFrom(t1)); + if (compare == 0) + { + // favour primitive type over reference + compare = Boolean.compare(!t1.isPrimitive(), !t2.isPrimitive()); + if (compare == 0) + // Use name to avoid non determinant sorting + compare = t1.getName().compareTo(t2.getName()); + } + + // break on the first different parameter (should always be true) + if (compare != 0) + break; + } + } + } + compare = Math.min(1, Math.max(compare, -1)); + } + + return compare; }; - private static final Class[] __boxedPrimitives = - { - Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, - Void.class - }; - private static final Class[] __supportedCollections = - { - ArrayList.class, HashSet.class, Queue.class, List.class, Set.class, Collection.class - }; - private static final Iterable __factoryLoader = ServiceLoader.load(ConfigurationProcessorFactory.class); - private static final XmlParser __parser = initParser(); private static XmlParser initParser() { @@ -174,7 +223,7 @@ public class XmlConfiguration } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to get webapp file reference", e); } } @@ -200,14 +249,14 @@ public class XmlConfiguration */ public XmlConfiguration(Resource resource) throws SAXException, IOException { - synchronized (__parser) + synchronized (PARSER) { _location = resource; try (InputStream inputStream = resource.getInputStream()) { - setConfig(__parser.parse(inputStream)); + setConfig(PARSER.parse(inputStream)); } - _dtd = __parser.getDTD(); + _dtd = PARSER.getDTD(); } } @@ -227,9 +276,9 @@ public class XmlConfiguration { _processor = new JettyXmlConfiguration(); } - else if (__factoryLoader != null) + else if (PROCESSOR_FACTORIES != null) { - for (ConfigurationProcessorFactory factory : __factoryLoader) + for (ConfigurationProcessorFactory factory : PROCESSOR_FACTORIES) { _processor = factory.getConfigurationProcessor(_dtd, config.getTag()); if (_processor != null) @@ -300,6 +349,8 @@ public class XmlConfiguration */ public Object configure() throws Exception { + if (LOG.isDebugEnabled()) + LOG.debug("Configure {}", _location); return _processor.configure(); } @@ -340,64 +391,60 @@ public class XmlConfiguration String id = _root.getAttribute("id"); if (id != null) _configuration.getIdMap().put(id, obj); - configure(obj, _root, 0); + + AttrOrElementNode aoeNode = new AttrOrElementNode(obj, _root, "Id", "Class", "Arg"); + // The Object already existed, if it has nodes, warn about them not being used. + aoeNode.getNodes("Arg") + .forEach((node) -> LOG.warn("Ignored arg {} in {}", node, this._configuration._location)); + configure(obj, _root, aoeNode.getNext()); return obj; } @Override public Object configure() throws Exception { - Class oClass = nodeClass(_root); - - String id = _root.getAttribute("id"); + AttrOrElementNode aoeNode = new AttrOrElementNode(_root, "Id", "Class", "Arg"); + String id = aoeNode.getString("Id"); + String clazz = aoeNode.getString("Class"); Object obj = id == null ? null : _configuration.getIdMap().get(id); + Class oClass = clazz != null ? Loader.loadClass(clazz) : obj == null ? null : obj.getClass(); + + if (LOG.isDebugEnabled()) + LOG.debug("Configure {} {}", oClass, obj); - int index = 0; if (obj == null && oClass != null) { - index = _root.size(); - Map namedArgMap = new HashMap<>(); - - List arguments = new LinkedList<>(); - for (int i = 0; i < _root.size(); i++) - { - Object o = _root.get(i); - if (o instanceof String) - continue; - - XmlParser.Node node = (XmlParser.Node)o; - if (node.getTag().equals("Arg")) - { - String namedAttribute = node.getAttribute("name"); - Object value = value(null, (XmlParser.Node)o); - if (namedAttribute != null) - namedArgMap.put(namedAttribute, value); - arguments.add(value); - } - else - { - index = i; - break; - } - } - try { - obj = construct(oClass, arguments.toArray(), namedArgMap); + obj = construct(oClass, new Args(null, oClass, aoeNode.getNodes("Arg"))); + if (id != null) + _configuration.getIdMap().put(id, obj); } catch (NoSuchMethodException x) { - throw new IllegalStateException(String.format("No constructor %s(%s,%s) in %s", oClass, arguments, namedArgMap, _configuration)); + throw new IllegalStateException(String.format("No matching constructor %s in %s", oClass, _configuration)); } } - if (id != null) - _configuration.getIdMap().put(id, obj); + else + { + // The Object already existed, if it has nodes, warn about them not being used. + aoeNode.getNodes("Arg") + .forEach((node) -> LOG.warn("Ignored arg {} in {}", node, this._configuration._location)); + } _configuration.initializeDefaults(obj); - configure(obj, _root, index); + configure(obj, _root, aoeNode.getNext()); return obj; } + private static Class nodeClass(XmlParser.Node node) throws ClassNotFoundException + { + String className = node.getAttribute("class"); + if (className == null) + return null; + return Loader.loadClass(className); + } + /** * Recursive configuration routine. * This method applies the nested Set, Put, Call, etc. elements to the given object. @@ -409,21 +456,6 @@ public class XmlConfiguration */ public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception { - // Object already constructed so skip any arguments - for (; i < cfg.size(); i++) - { - Object o = cfg.get(i); - if (o instanceof String) - continue; - XmlParser.Node node = (XmlParser.Node)o; - if ("Arg".equals(node.getTag())) - { - LOG.warn("Ignored arg: " + node); - continue; - } - break; - } - // Process real arguments for (; i < cfg.size(); i++) { @@ -437,6 +469,10 @@ public class XmlConfiguration String tag = node.getTag(); switch (tag) { + case "Arg": + case "Class": + case "Id": + throw new IllegalStateException("Element '" + tag + "' not skipped"); case "Set": set(obj, node); break; @@ -482,14 +518,6 @@ public class XmlConfiguration } } - private static Class nodeClass(XmlParser.Node node) throws ClassNotFoundException - { - String className = node.getAttribute("class"); - if (className == null) - return null; - return Loader.loadClass(className); - } - /** *

        Call a setter method.

        *

        This method makes a best effort to find a matching set method. @@ -554,7 +582,7 @@ public class XmlConfiguration } catch (IllegalArgumentException | IllegalAccessException | NoSuchMethodException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); me.add(e); } @@ -569,7 +597,7 @@ public class XmlConfiguration } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); me.add(e); } @@ -606,7 +634,7 @@ public class XmlConfiguration } catch (NoSuchFieldException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); me.add(e); } @@ -630,13 +658,13 @@ public class XmlConfiguration } catch (IllegalArgumentException | IllegalAccessException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); me.add(e); } try { - for (Class c : __supportedCollections) + for (Class c : SUPPORTED_COLLECTIONS) { if (paramTypes[0].isAssignableFrom(c)) { @@ -648,7 +676,7 @@ public class XmlConfiguration } catch (IllegalAccessException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); me.add(e); } } @@ -662,11 +690,11 @@ public class XmlConfiguration Class sClass = set.getParameterTypes()[0]; if (sClass.isPrimitive()) { - for (int t = 0; t < __primitives.length; t++) + for (int t = 0; t < PRIMITIVES.length; t++) { - if (sClass.equals(__primitives[t])) + if (sClass.equals(PRIMITIVES[t])) { - sClass = __boxedPrimitives[t]; + sClass = BOXED_PRIMITIVES[t]; break; } } @@ -680,7 +708,7 @@ public class XmlConfiguration } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); me.add(e); } } @@ -862,7 +890,6 @@ public class XmlConfiguration String id = aoeNode.getString("Id"); String name = aoeNode.getString("Name"); String clazz = aoeNode.getString("Class"); - List args = aoeNode.getList("Arg"); Class oClass; if (clazz != null) @@ -883,7 +910,7 @@ public class XmlConfiguration try { - Object nobj = call(oClass, name, obj, args.toArray(new Object[0])); + Object nobj = call(oClass, name, obj, new Args(obj, oClass, aoeNode.getNodes("Arg"))); if (id != null) _configuration.getIdMap().put(id, nobj); configure(nobj, node, aoeNode.getNext()); @@ -895,7 +922,7 @@ public class XmlConfiguration } } - private Object call(Class oClass, String methodName, Object obj, Object[] arg) throws InvocationTargetException, NoSuchMethodException + private Object call(Class oClass, String methodName, Object obj, Args args) throws InvocationTargetException, NoSuchMethodException { Objects.requireNonNull(oClass, "Class cannot be null"); Objects.requireNonNull(methodName, "Method name cannot be null"); @@ -903,11 +930,15 @@ public class XmlConfiguration throw new IllegalArgumentException("Method name cannot be blank"); // Lets just try all methods for now - for (Method method : oClass.getMethods()) + + Method[] methods = oClass.getMethods(); + Arrays.sort(methods, EXECUTABLE_COMPARATOR); + for (Method method : methods) { if (!method.getName().equals(methodName)) continue; - if (method.getParameterCount() != arg.length) + Object[] arguments = args.applyTo(method); + if (arguments == null) continue; if (Modifier.isStatic(method.getModifiers()) != (obj == null)) continue; @@ -916,38 +947,11 @@ public class XmlConfiguration try { - return invokeMethod(method, obj, arg); + return invokeMethod(method, obj, arguments); } catch (IllegalAccessException | IllegalArgumentException e) { - LOG.ignore(e); - } - } - - // Lets look for a method with varargs arguments - Object[] argsWithVarargs = null; - for (Method method : oClass.getMethods()) - { - if (!method.getName().equals(methodName)) - continue; - if (method.getParameterCount() != arg.length + 1) - continue; - if (!method.getParameterTypes()[arg.length].isArray()) - continue; - if (Modifier.isStatic(method.getModifiers()) != (obj == null)) - continue; - if ((obj == null) && method.getDeclaringClass() != oClass) - continue; - - if (argsWithVarargs == null) - argsWithVarargs = ArrayUtil.addToArray(arg, new Object[0], Object.class); - try - { - return invokeMethod(method, obj, argsWithVarargs); - } - catch (IllegalAccessException | IllegalArgumentException e) - { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } @@ -963,36 +967,19 @@ public class XmlConfiguration */ private Object newObj(Object obj, XmlParser.Node node) throws Exception { - final AttrOrElementNode aoeNode = new AttrOrElementNode(obj, node, "Id", "Class", "Arg"); - final String id = aoeNode.getString("Id"); - final String clazz = aoeNode.getString("Class"); - final List argNodes = aoeNode.getNodes("Arg"); + AttrOrElementNode aoeNode = new AttrOrElementNode(obj, node, "Id", "Class", "Arg"); + String id = aoeNode.getString("Id"); + String clazz = aoeNode.getString("Class"); if (LOG.isDebugEnabled()) LOG.debug("XML new " + clazz); Class oClass = Loader.loadClass(clazz); - // Find the elements - Map namedArgMap = new HashMap<>(); - List arguments = new LinkedList<>(); - for (XmlParser.Node child : argNodes) - { - String namedAttribute = child.getAttribute("name"); - Object value = value(obj, child); - if (namedAttribute != null) - { - // named arguments - namedArgMap.put(namedAttribute, value); - } - // raw arguments - arguments.add(value); - } - Object nobj; try { - nobj = construct(oClass, arguments.toArray(), namedArgMap); + nobj = construct(oClass, new Args(obj, oClass, aoeNode.getNodes("Arg"))); } catch (NoSuchMethodException e) { @@ -1007,84 +994,24 @@ public class XmlConfiguration return nobj; } - private Object construct(Class klass, Object[] arguments, Map namedArgMap) throws InvocationTargetException, NoSuchMethodException + private Object construct(Class klass, Args args) throws InvocationTargetException, NoSuchMethodException { Objects.requireNonNull(klass, "Class cannot be null"); - Objects.requireNonNull(namedArgMap, "Named Argument Map cannot be null"); + Objects.requireNonNull(args, "Named list cannot be null"); - for (Constructor constructor : klass.getConstructors()) + Constructor[] constructors = klass.getConstructors(); + Arrays.sort(constructors, EXECUTABLE_COMPARATOR); + for (Constructor constructor : constructors) { - if (arguments == null) - { - // null arguments in .newInstance() is allowed - if (constructor.getParameterCount() != 0) - continue; - } - else if (constructor.getParameterCount() != arguments.length) - { - continue; - } - try { - if (arguments == null || arguments.length == 0) - { - if (LOG.isDebugEnabled()) - LOG.debug("Invoking constructor, no arguments"); - return invokeConstructor(constructor); - } - - if (namedArgMap.isEmpty()) - { - if (LOG.isDebugEnabled()) - LOG.debug("Invoking constructor, no XML parameter mapping"); + Object[] arguments = args.applyTo(constructor); + if (arguments != null) return invokeConstructor(constructor, arguments); - } - - Annotation[][] parameterAnnotations = constructor.getParameterAnnotations(); - if (parameterAnnotations == null || parameterAnnotations.length == 0) - { - if (LOG.isDebugEnabled()) - LOG.debug("Invoking constructor, no parameter annotations"); - return invokeConstructor(constructor, arguments); - } - - int count = 0; - Object[] swizzled = new Object[arguments.length]; - for (Annotation[] annotations : parameterAnnotations) - { - for (Annotation annotation : annotations) - { - if (annotation instanceof Name) - { - Name param = (Name)annotation; - if (namedArgMap.containsKey(param.value())) - { - if (LOG.isDebugEnabled()) - LOG.debug("Mapping named parameter {} in position {}", param.value(), count); - swizzled[count] = namedArgMap.get(param.value()); - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Mapping argument {} in position {}", arguments[count], count); - swizzled[count] = arguments[count]; - } - ++count; - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Skipping parameter annotated with {}", annotation); - } - } - } - - return invokeConstructor(constructor, swizzled); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } throw new NoSuchMethodException(""); @@ -1098,13 +1025,14 @@ public class XmlConfiguration */ private Object refObj(XmlParser.Node node) throws Exception { - String refid = node.getAttribute("refid"); + AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id"); + String refid = aoeNode.getString("Id"); if (refid == null) - refid = node.getAttribute("id"); + refid = node.getAttribute("refid"); Object obj = _configuration.getIdMap().get(refid); if (obj == null && node.size() > 0) throw new IllegalStateException("No object for refid=" + refid); - configure(obj, node, 0); + configure(obj, node, aoeNode.getNext()); return obj; } @@ -1227,11 +1155,11 @@ public class XmlConfiguration */ private Object propertyObj(XmlParser.Node node) throws Exception { - final AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default"); - final String id = aoeNode.getString("Id"); - final String name = aoeNode.getString("Name", true); - final List deprecated = aoeNode.getList("Deprecated"); - final String dftValue = aoeNode.getString("Default"); + AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default"); + String id = aoeNode.getString("Id"); + String name = aoeNode.getString("Name", true); + List deprecated = aoeNode.getList("Deprecated"); + String dftValue = aoeNode.getString("Default"); // Look for a value Map properties = _configuration.getProperties(); @@ -1278,11 +1206,11 @@ public class XmlConfiguration */ private Object systemPropertyObj(XmlParser.Node node) throws Exception { - final AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default"); - final String id = aoeNode.getString("Id"); - final String name = aoeNode.getString("Name", true); - final List deprecated = aoeNode.getList("Deprecated"); - final String dftValue = aoeNode.getString("Default"); + AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default"); + String id = aoeNode.getString("Id"); + String name = aoeNode.getString("Name", true); + List deprecated = aoeNode.getList("Deprecated"); + String dftValue = aoeNode.getString("Default"); // Look for a value String value = System.getProperty(name); @@ -1508,7 +1436,7 @@ public class XmlConfiguration } } - for (Class collectionClass : __supportedCollections) + for (Class collectionClass : SUPPORTED_COLLECTIONS) { if (isTypeMatchingClass(type, collectionClass)) return convertArrayToCollection(value, collectionClass); @@ -1684,40 +1612,158 @@ public class XmlConfiguration public List getNodes(String elementName) { - String attrName = StringUtil.asciiToLowerCase(elementName); - final List values = new ArrayList<>(); - - String attr = _node.getAttribute(attrName); - if (attr != null) - { - for (String a : StringUtil.csvSplit(null, attr, 0, attr.length())) - { - // create a fake node - XmlParser.Node n = new XmlParser.Node(null, elementName, null); - n.add(a); - values.add(n); - } - } - - for (int i = 0; i < _next; i++) - { - Object o = _node.get(i); - if (!(o instanceof XmlParser.Node)) - continue; - XmlParser.Node n = (XmlParser.Node)o; - - if (elementName.equals(n.getTag())) - { - if (attr != null) - throw new IllegalStateException("Cannot have attr '" + attrName + "' and element '" + elementName + "'"); - - values.add(n); - } - } - - return values; + return XmlConfiguration.getNodes(_node, elementName); } } + + private class Args + { + private final Class _class; + private final List _arguments; + private final List _names; + + private Args(Object obj, Class oClass, List args) throws Exception + { + _class = oClass; + _arguments = new ArrayList<>(); + _names = new ArrayList<>(); + for (XmlParser.Node child : args) + { + _arguments.add(value(obj, child)); + _names.add(child.getAttribute("name")); + } + } + + private Args(List arguments, List names) + { + _class = null; + _arguments = arguments; + _names = names; + } + + Object[] applyTo(Executable executable) + { + Object[] args = matchArgsToParameters(executable); + if (args == null && _class != null) + { + // Could this be an empty varargs match? + int count = executable.getParameterCount(); + if (count > 0 && executable.getParameters()[count - 1].isVarArgs()) + { + // There is not a no varArgs alternative so let's try a an empty varArgs match + args = asEmptyVarArgs(executable.getParameterTypes()[count - 1]).matchArgsToParameters(executable); + } + } + return args; + } + + Args asEmptyVarArgs(Class varArgType) + { + List arguments = new ArrayList<>(_arguments); + arguments.add(Array.newInstance(varArgType.getComponentType(), 0)); + List names = new ArrayList<>(_names); + names.add(null); + return new Args(arguments, names); + } + + Object[] matchArgsToParameters(Executable executable) + { + int count = executable.getParameterCount(); + + // No match of wrong number of parameters + if (count != _arguments.size()) + return null; + + // Handle no parameter case + if (count == 0) + return new Object[0]; + + // If no arg names are specified, keep the arg order + Object[] args; + if (_names.stream().noneMatch(Objects::nonNull)) + { + args = _arguments.toArray(new Object[0]); + } + else + { + // If we don't have any parameters with names, then no match + Annotation[][] parameterAnnotations = executable.getParameterAnnotations(); + if (parameterAnnotations == null || parameterAnnotations.length == 0) + return null; + + // Find the position of all named parameters from the executable + Map position = new HashMap<>(); + int p = 0; + for (Annotation[] paramAnnotation : parameterAnnotations) + { + Integer pos = p++; + Arrays.stream(paramAnnotation) + .filter(Name.class::isInstance) + .map(Name.class::cast) + .findFirst().ifPresent(n -> position.put(n.value(), pos)); + } + + List arguments = new ArrayList<>(_arguments); + List names = new ArrayList<>(_names); + // Map the actual arguments to the names + for (p = 0; p < count; p++) + { + String name = names.get(p); + if (name != null) + { + Integer pos = position.get(name); + if (pos == null) + return null; + if (pos != p) + { + // adjust position of parameter + arguments.add(pos, arguments.remove(p)); + names.add(pos, names.remove(p)); + p = Math.min(p, pos); + } + } + } + args = arguments.toArray(new Object[0]); + } + + return args; + } + } + } + + private static List getNodes(XmlParser.Node node, String elementName) + { + String attrName = StringUtil.asciiToLowerCase(elementName); + final List values = new ArrayList<>(); + + String attr = node.getAttribute(attrName); + if (attr != null) + { + for (String a : StringUtil.csvSplit(null, attr, 0, attr.length())) + { + // create a fake node + XmlParser.Node n = new XmlParser.Node(null, elementName, null); + n.add(a); + values.add(n); + } + } + + for (Object o : node) + { + if (!(o instanceof XmlParser.Node)) + continue; + XmlParser.Node n = (XmlParser.Node)o; + + if (elementName.equals(n.getTag())) + { + if (attr != null) + throw new IllegalStateException("Cannot have attr '" + attrName + "' and element '" + elementName + "'"); + + values.add(n); + } + } + + return values; } /** @@ -1747,6 +1793,8 @@ public class XmlConfiguration properties.putAll(System.getProperties()); // For all arguments, load properties + if (LOG.isDebugEnabled()) + LOG.debug("args={}", Arrays.asList(args)); for (String arg : args) { if (arg.indexOf('=') >= 0) @@ -1785,23 +1833,40 @@ public class XmlConfiguration } } + if (LOG.isDebugEnabled()) + LOG.debug("objects={}", objects); + // For all objects created by XmlConfigurations, start them if they are lifecycles. + List started = new ArrayList<>(objects.size()); for (Object obj : objects) { if (obj instanceof LifeCycle) { LifeCycle lc = (LifeCycle)obj; if (!lc.isRunning()) + { lc.start(); + if (lc.isStarted()) + started.add(lc); + else + { + // Failed to start a component, so stop all started components + Collections.reverse(started); + for (LifeCycle slc : started) + { + slc.stop(); + } + break; + } + } } } - return null; }); } catch (Error | Exception e) { - LOG.warn(e); + LOG.warn("Unable to execute XmlConfiguration", e); throw e; } } diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java index 3480ccf8339..58f8da3c488 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; @@ -34,9 +34,9 @@ import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; @@ -54,7 +54,7 @@ import org.xml.sax.helpers.DefaultHandler; */ public class XmlParser { - private static final Logger LOG = Log.getLogger(XmlParser.class); + private static final Logger LOG = LoggerFactory.getLogger(XmlParser.class); private Map _redirectMap = new HashMap(); private SAXParser _parser; @@ -70,7 +70,7 @@ public class XmlParser public XmlParser() { SAXParserFactory factory = SAXParserFactory.newInstance(); - boolean validatingDefault = factory.getClass().toString().startsWith("org.apache.xerces."); + boolean validatingDefault = factory.getClass().toString().contains("org.apache.xerces."); String validatingProp = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validatingDefault ? "true" : "false"); boolean validating = Boolean.valueOf(validatingProp).booleanValue(); setValidating(validating); @@ -99,7 +99,7 @@ public class XmlParser if (validating) LOG.warn("Schema validation may not be supported: ", e); else - LOG.ignore(e); + LOG.trace("IGNORED", e); } _parser.getXMLReader().setFeature("http://xml.org/sax/features/validation", validating); @@ -117,7 +117,7 @@ public class XmlParser } catch (Exception e) { - LOG.warn(Log.EXCEPTION, e); + LOG.warn("Unable to set validating on XML Parser", e); throw new Error(e.toString()); } } @@ -286,7 +286,7 @@ public class XmlParser } catch (IOException e) { - LOG.ignore(e); + LOG.trace("IGNORED", e); } } return null; @@ -425,7 +425,7 @@ public class XmlParser @Override public void warning(SAXParseException ex) { - LOG.debug(Log.EXCEPTION, ex); + LOG.debug("SAX Parse Issue", ex); LOG.warn("WARNING@" + getLocationString(ex) + " : " + ex.toString()); } @@ -435,16 +435,16 @@ public class XmlParser // Save error and continue to report other errors if (_error == null) _error = ex; - LOG.debug(Log.EXCEPTION, ex); - LOG.warn("ERROR@" + getLocationString(ex) + " : " + ex.toString()); + LOG.debug("SAX Parse Issue", ex); + LOG.error("ERROR@" + getLocationString(ex) + " : " + ex.toString()); } @Override public void fatalError(SAXParseException ex) throws SAXException { _error = ex; - LOG.debug(Log.EXCEPTION, ex); - LOG.warn("FATAL@" + getLocationString(ex) + " : " + ex.toString()); + LOG.debug("SAX Parse Issue", ex); + LOG.error("FATAL@" + getLocationString(ex) + " : " + ex.toString()); throw ex; } diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/package-info.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/package-info.java index 3858e599f33..39b9b15c8d0 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/package-info.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/package-info.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // /** diff --git a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_10_0.dtd b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_10_0.dtd index bd0aa99d06d..123da7df8ca 100644 --- a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_10_0.dtd +++ b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_10_0.dtd @@ -19,21 +19,18 @@ my be specified if a match is not achieved. - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - + + - + - + - + - + - + - + - - + + - + - + @@ -280,7 +276,7 @@ If it contains multiple value elements they are added as strings before being converted to any specified type. --> - + - + - + - + diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/AnnotatedTestConfiguration.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/AnnotatedTestConfiguration.java index 9d1ff60db16..1ca713a2519 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/AnnotatedTestConfiguration.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/AnnotatedTestConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; @@ -37,6 +37,18 @@ public class AnnotatedTestConfiguration { } + public AnnotatedTestConfiguration(Integer test) + { + // exists to make constructor matching harder + throw new UnsupportedOperationException("Should not be called"); + } + + public AnnotatedTestConfiguration(Integer one, Integer two, Integer three) + { + // exists to make constructor matching harder + throw new UnsupportedOperationException("Should not be called"); + } + public AnnotatedTestConfiguration(@Name("first") String first, @Name("second") String second, @Name("third") String third) { this.first = first; @@ -44,6 +56,53 @@ public class AnnotatedTestConfiguration this.third = third; } + public AnnotatedTestConfiguration(Long one, Long two, Long three) + { + // exists to make constructor matching harder + throw new UnsupportedOperationException("Should not be called"); + } + + public void setAll(Integer one, Integer two, Integer three) + { + // exists to make method matching harder + throw new UnsupportedOperationException("Should not be called"); + } + + public void setAll(@Name("first") String first, @Name("second") String second, @Name("third") String third) + { + this.first = first; + this.second = second; + this.third = third; + } + + public void setAll(long one, long two, long three) + { + // exists to make method matching harder + throw new UnsupportedOperationException("Should not be called"); + } + + public void setVarArgs(String first, String... theRest) + { + this.first = first; + this.second = theRest.length > 0 ? theRest[0] : null; + this.third = theRest.length > 1 ? theRest[1] : null; + } + + public void call(Integer value) + { + this.first = String.valueOf(value); + } + + public void call(String value) + { + this.second = value; + } + + public void call(E value) + { + this.third = String.valueOf(value); + } + public String getFirst() { return first; diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/ConstructorArgTestClass.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/ConstructorArgTestClass.java index 4109a4956f1..0be0575e659 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/ConstructorArgTestClass.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/ConstructorArgTestClass.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/DefaultTestConfiguration.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/DefaultTestConfiguration.java index 711dfbaf60c..b4e02b75057 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/DefaultTestConfiguration.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/DefaultTestConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java index 66cac9ef9ba..721ce04f3fb 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; @@ -34,7 +34,7 @@ public class TestConfiguration extends HashMap { public static int VALUE = 77; - public final Object ID = new Object(); + public final Object id = new Object(); public final String name; public TestConfiguration nested; @@ -54,6 +54,7 @@ public class TestConfiguration extends HashMap private Set set; private ConstructorArgTestClass constructorArgTestClass; public Map map; + public Double number; public TestConfiguration() { @@ -65,6 +66,16 @@ public class TestConfiguration extends HashMap name = n; } + public void setNumber(Object value) + { + testObject = value; + } + + public void setNumber(double value) + { + number = value; + } + public void setTest(Object value) { testObject = value; diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java index 9a5d6afeeec..6d66f0be86a 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java index 7edd331e023..8838a0797dd 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; @@ -23,32 +23,46 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import org.eclipse.jetty.logging.JettyLogger; +import org.eclipse.jetty.logging.StdErrAppender; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.log.StdErrLog; +import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; import org.xml.sax.SAXException; import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; @@ -56,6 +70,7 @@ import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -65,10 +80,6 @@ public class XmlConfigurationTest { public WorkDir workDir; - protected String[] _configure = new String[]{ - "org/eclipse/jetty/xml/configureWithAttr.xml", "org/eclipse/jetty/xml/configureWithElements.xml" - }; - private static final String STRING_ARRAY_XML = "String1String2"; private static final String INT_ARRAY_XML = "12"; @@ -81,175 +92,193 @@ public class XmlConfigurationTest configuration.configure(); } - @Test - public void testPassedObject() throws Exception + public static String[] xmlConfigs() { - for (String configure : _configure) - { - Map properties = new HashMap<>(); - properties.put("whatever", "xxx"); - TestConfiguration.VALUE = 77; - URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure); - XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(url)); - TestConfiguration tc = new TestConfiguration("tc"); - configuration.getProperties().putAll(properties); - configuration.configure(tc); - - assertEquals("SetValue", tc.testObject, "Set String"); - assertEquals(2, tc.testInt, "Set Type"); - - assertEquals(18080, tc.propValue); - - assertEquals("PutValue", tc.get("Test"), "Put"); - assertEquals("2", tc.get("TestDft"), "Put dft"); - assertEquals(2, tc.get("TestInt"), "Put type"); - - assertEquals("PutValue", tc.get("Trim"), "Trim"); - assertEquals(null, tc.get("Null"), "Null"); - assertEquals(null, tc.get("NullTrim"), "NullTrim"); - - assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim"); - assertEquals("-1String", tc.get("Objects"), "Objects"); - assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim"); - assertEquals("\n PutValue\n ", tc.get("String"), "String"); - assertEquals("", tc.get("NullString"), "NullString"); - assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace"); - assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString"); - assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString"); - assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString"); - - assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty"); - assertEquals(System.getenv("HOME"), tc.get("Env"), "Env"); - - assertEquals("xxx", tc.get("Property"), "Property"); - - assertEquals("Yes", tc.get("Called"), "Called"); - - assertTrue(TestConfiguration.called); - - assertEquals("Blah", tc.oa[0], "oa[0]"); - assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]"); - assertEquals(1.2345, tc.oa[2], "oa[2]"); - assertEquals(null, tc.oa[3], "oa[3]"); - - assertEquals(1, tc.ia[0], "ia[0]"); - assertEquals(2, tc.ia[1], "ia[1]"); - assertEquals(3, tc.ia[2], "ia[2]"); - assertEquals(0, tc.ia[3], "ia[3]"); - - TestConfiguration tc2 = tc.nested; - assertTrue(tc2 != null); - assertEquals(true, tc2.get("Arg"), "Called(bool)"); - - assertEquals(null, tc.get("Arg"), "nested config"); - assertEquals(true, tc2.get("Arg"), "nested config"); - - assertEquals("Call1", tc2.testObject, "nested config"); - assertEquals(4, tc2.testInt, "nested config"); - assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call"); - - assertEquals(tc.testField1, 77, "static to field"); - assertEquals(tc.testField2, 2, "field to field"); - assertEquals(TestConfiguration.VALUE, 42, "literal to static"); - - assertEquals(((Map)configuration.getIdMap().get("map")).get("key0"), "value0"); - assertEquals(((Map)configuration.getIdMap().get("map")).get("key1"), "value1"); - } + return new String[]{"org/eclipse/jetty/xml/configureWithAttr.xml", "org/eclipse/jetty/xml/configureWithElements.xml"}; } - @Test - public void testNewObject() throws Exception + @ParameterizedTest + @MethodSource("xmlConfigs") + public void testPassedObject(String configure) throws Exception { - for (String configure : _configure) + Map properties = new HashMap<>(); + properties.put("whatever", "xxx"); + TestConfiguration.VALUE = 77; + URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure); + assertNotNull(url); + XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(url)); + TestConfiguration tc = new TestConfiguration("tc"); + configuration.getProperties().putAll(properties); + configuration.configure(tc); + + assertEquals("SetValue", tc.testObject, "Set String"); + assertEquals(2, tc.testInt, "Set Type"); + + assertEquals(18080, tc.propValue); + + assertEquals("PutValue", tc.get("Test"), "Put"); + assertEquals("2", tc.get("TestDft"), "Put dft"); + assertEquals(2, tc.get("TestInt"), "Put type"); + + assertEquals("PutValue", tc.get("Trim"), "Trim"); + assertNull(tc.get("Null"), "Null"); + assertNull(tc.get("NullTrim"), "NullTrim"); + + assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim"); + assertEquals("-1String", tc.get("Objects"), "Objects"); + assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim"); + assertEquals("\n PutValue\n ", tc.get("String"), "String"); + assertEquals("", tc.get("NullString"), "NullString"); + assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace"); + assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString"); + assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString"); + assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString"); + + assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty"); + assertEquals(System.getenv("HOME"), tc.get("Env"), "Env"); + + assertEquals("xxx", tc.get("Property"), "Property"); + + assertEquals("Yes", tc.get("Called"), "Called"); + + assertTrue(TestConfiguration.called); + + assertEquals("Blah", tc.oa[0], "oa[0]"); + assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]"); + assertEquals(1.2345, tc.oa[2], "oa[2]"); + assertNull(tc.oa[3], "oa[3]"); + + assertEquals(1, tc.ia[0], "ia[0]"); + assertEquals(2, tc.ia[1], "ia[1]"); + assertEquals(3, tc.ia[2], "ia[2]"); + assertEquals(0, tc.ia[3], "ia[3]"); + + TestConfiguration tc2 = tc.nested; + assertNotNull(tc2); + assertEquals(true, tc2.get("Arg"), "Called(bool)"); + + assertNull(tc.get("Arg"), "nested config"); + assertEquals(true, tc2.get("Arg"), "nested config"); + + assertEquals("Call1", tc2.testObject, "nested config"); + assertEquals(4, tc2.testInt, "nested config"); + assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call"); + + assertEquals(tc.testField1, 77, "static to field"); + assertEquals(tc.testField2, 2, "field to field"); + assertEquals(TestConfiguration.VALUE, 42, "literal to static"); + + @SuppressWarnings("unchecked") + Map map = (Map)configuration.getIdMap().get("map"); + assertEquals(map.get("key0"), "value0"); + assertEquals(map.get("key1"), "value1"); + } + + @ParameterizedTest + @MethodSource("xmlConfigs") + public void testNewObject(String configure) throws Exception + { + TestConfiguration.VALUE = 71; + Map properties = new HashMap<>(); + properties.put("whatever", "xxx"); + + URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure); + assertNotNull(url); + AtomicInteger count = new AtomicInteger(0); + XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(url)) { - TestConfiguration.VALUE = 71; - Map properties = new HashMap<>(); - properties.put("whatever", "xxx"); - - URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure); - final AtomicInteger count = new AtomicInteger(0); - XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(url)) + @Override + public void initializeDefaults(Object object) { - @Override - public void initializeDefaults(Object object) + if (object instanceof TestConfiguration) { - if (object instanceof TestConfiguration) - { - count.incrementAndGet(); - ((TestConfiguration)object).setNested(null); - ((TestConfiguration)object).setTestString("NEW DEFAULT"); - } + count.incrementAndGet(); + ((TestConfiguration)object).setNested(null); + ((TestConfiguration)object).setTestString("NEW DEFAULT"); } - }; - configuration.getProperties().putAll(properties); - TestConfiguration tc = (TestConfiguration)configuration.configure(); + } + }; + configuration.getProperties().putAll(properties); + TestConfiguration tc = (TestConfiguration)configuration.configure(); - assertEquals(3, count.get()); + assertEquals(3, count.get()); - assertEquals("NEW DEFAULT", tc.getTestString()); - assertEquals("nested", tc.getNested().getTestString()); - assertEquals("NEW DEFAULT", tc.getNested().getNested().getTestString()); + assertEquals("NEW DEFAULT", tc.getTestString()); + assertEquals("nested", tc.getNested().getTestString()); + assertEquals("NEW DEFAULT", tc.getNested().getNested().getTestString()); - assertEquals("SetValue", tc.testObject, "Set String"); - assertEquals(2, tc.testInt, "Set Type"); + assertEquals("SetValue", tc.testObject, "Set String"); + assertEquals(2, tc.testInt, "Set Type"); - assertEquals(18080, tc.propValue); + assertEquals(18080, tc.propValue); - assertEquals("PutValue", tc.get("Test"), "Put"); - assertEquals("2", tc.get("TestDft"), "Put dft"); - assertEquals(2, tc.get("TestInt"), "Put type"); + assertEquals("PutValue", tc.get("Test"), "Put"); + assertEquals("2", tc.get("TestDft"), "Put dft"); + assertEquals(2, tc.get("TestInt"), "Put type"); - assertEquals("PutValue", tc.get("Trim"), "Trim"); - assertEquals(null, tc.get("Null"), "Null"); - assertEquals(null, tc.get("NullTrim"), "NullTrim"); + assertEquals("PutValue", tc.get("Trim"), "Trim"); + assertNull(tc.get("Null"), "Null"); + assertNull(tc.get("NullTrim"), "NullTrim"); - assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim"); - assertEquals("-1String", tc.get("Objects"), "Objects"); - assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim"); - assertEquals("\n PutValue\n ", tc.get("String"), "String"); - assertEquals("", tc.get("NullString"), "NullString"); - assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace"); - assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString"); - assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString"); - assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString"); + assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim"); + assertEquals("-1String", tc.get("Objects"), "Objects"); + assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim"); + assertEquals("\n PutValue\n ", tc.get("String"), "String"); + assertEquals("", tc.get("NullString"), "NullString"); + assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace"); + assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString"); + assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString"); + assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString"); - assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty"); - assertEquals("xxx", tc.get("Property"), "Property"); + assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty"); + assertEquals("xxx", tc.get("Property"), "Property"); - assertEquals("Yes", tc.get("Called"), "Called"); + assertEquals("Yes", tc.get("Called"), "Called"); - assertTrue(TestConfiguration.called); + assertTrue(TestConfiguration.called); - assertEquals("Blah", tc.oa[0], "oa[0]"); - assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]"); - assertEquals(1.2345, tc.oa[2], "oa[2]"); - assertEquals(null, tc.oa[3], "oa[3]"); + assertEquals("Blah", tc.oa[0], "oa[0]"); + assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]"); + assertEquals(1.2345, tc.oa[2], "oa[2]"); + assertNull(tc.oa[3], "oa[3]"); - assertEquals(1, tc.ia[0], "ia[0]"); - assertEquals(2, tc.ia[1], "ia[1]"); - assertEquals(3, tc.ia[2], "ia[2]"); - assertEquals(0, tc.ia[3], "ia[3]"); + assertEquals(1, tc.ia[0], "ia[0]"); + assertEquals(2, tc.ia[1], "ia[1]"); + assertEquals(3, tc.ia[2], "ia[2]"); + assertEquals(0, tc.ia[3], "ia[3]"); - TestConfiguration tc2 = tc.nested; - assertTrue(tc2 != null); - assertEquals(true, tc2.get("Arg"), "Called(bool)"); + TestConfiguration tc2 = tc.nested; + assertNotNull(tc2); + assertEquals(true, tc2.get("Arg"), "Called(bool)"); - assertEquals(null, tc.get("Arg"), "nested config"); - assertEquals(true, tc2.get("Arg"), "nested config"); + assertNull(tc.get("Arg"), "nested config"); + assertEquals(true, tc2.get("Arg"), "nested config"); - assertEquals("Call1", tc2.testObject, "nested config"); - assertEquals(4, tc2.testInt, "nested config"); - assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call"); + assertEquals("Call1", tc2.testObject, "nested config"); + assertEquals(4, tc2.testInt, "nested config"); + assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call"); - assertEquals(71, tc.testField1, "static to field"); - assertEquals(2, tc.testField2, "field to field"); - assertEquals(42, TestConfiguration.VALUE, "literal to static"); - } + assertEquals(71, tc.testField1, "static to field"); + assertEquals(2, tc.testField2, "field to field"); + assertEquals(42, TestConfiguration.VALUE, "literal to static"); } public XmlConfiguration asXmlConfiguration(String rawXml) throws IOException, SAXException { - Path testFile = workDir.getEmptyPathDir().resolve("raw.xml"); + if (rawXml.indexOf("!DOCTYPE") < 0) + rawXml = "\n" + + "\n" + + rawXml; + return asXmlConfiguration("raw.xml", rawXml); + } + + public XmlConfiguration asXmlConfiguration(String filename, String rawXml) throws IOException, SAXException + { + if (rawXml.indexOf("!DOCTYPE") < 0) + rawXml = "\n" + + "\n" + + rawXml; + Path testFile = workDir.getEmptyPathDir().resolve(filename); try (BufferedWriter writer = Files.newBufferedWriter(testFile, UTF_8)) { writer.write(rawXml); @@ -303,7 +332,7 @@ public class XmlConfigurationTest tc.setTestString("default"); configuration.configure(tc); assertEquals("default", tc.getTestString()); - assertEquals(configuration.getIdMap().get("test"), null); + assertNull(configuration.getIdMap().get("test")); } @Test @@ -327,7 +356,7 @@ public class XmlConfigurationTest tc.setTestString("default"); configuration.configure(tc); assertEquals("default", tc.getTestString()); - assertEquals(configuration.getIdMap().get("test"), null); + assertNull(configuration.getIdMap().get("test")); } @Test @@ -336,10 +365,7 @@ public class XmlConfigurationTest XmlConfiguration configuration = asXmlConfiguration(""); TestConfiguration tc = new TestConfiguration(); - NoSuchMethodException e = assertThrows(NoSuchMethodException.class, () -> - { - configuration.configure(tc); - }); + NoSuchMethodException e = assertThrows(NoSuchMethodException.class, () -> configuration.configure(tc)); assertThat(e.getMessage(), containsString("Found setters for int")); } @@ -347,9 +373,9 @@ public class XmlConfigurationTest @Test public void testListConstructorArg() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + "" - + STRING_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + "" + + STRING_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getList() returns null as it's not configured yet", tc.getList(), is(nullValue())); xmlConfiguration.configure(tc); @@ -360,11 +386,11 @@ public class XmlConfigurationTest @Test public void testTwoArgumentListConstructorArg() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + "" - + "" + STRING_ARRAY_XML + "" - + "" + STRING_ARRAY_XML + "" - + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + "" + + "" + STRING_ARRAY_XML + "" + + "" + STRING_ARRAY_XML + "" + + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getList() returns null as it's not configured yet", tc.getList(), is(nullValue())); xmlConfiguration.configure(tc); @@ -375,22 +401,19 @@ public class XmlConfigurationTest @Test public void testListNotContainingArray() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + "Some String"); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + "Some String"); TestConfiguration tc = new TestConfiguration(); - assertThrows(IllegalArgumentException.class, () -> - { - xmlConfiguration.configure(tc); - }); + assertThrows(IllegalArgumentException.class, () -> xmlConfiguration.configure(tc)); } @Test public void testSetConstructorArg() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + "" - + STRING_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + "" + + STRING_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getList() returns null as it's not configured yet", tc.getSet(), is(nullValue())); xmlConfiguration.configure(tc); @@ -401,20 +424,17 @@ public class XmlConfigurationTest @Test public void testSetNotContainingArray() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + "Some String"); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + "Some String"); TestConfiguration tc = new TestConfiguration(); - assertThrows(IllegalArgumentException.class, () -> - { - xmlConfiguration.configure(tc); - }); + assertThrows(IllegalArgumentException.class, () -> xmlConfiguration.configure(tc)); } @Test public void testListSetterWithStringArray() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + STRING_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + STRING_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getList() returns null as it's not configured yet", tc.getList(), is(nullValue())); xmlConfiguration.configure(tc); @@ -424,8 +444,8 @@ public class XmlConfigurationTest @Test public void testListSetterWithPrimitiveArray() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + INT_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + INT_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getList() returns null as it's not configured yet", tc.getList(), is(nullValue())); xmlConfiguration.configure(tc); @@ -435,21 +455,18 @@ public class XmlConfigurationTest @Test public void testNotSupportedLinkedListSetter() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + INT_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + INT_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getSet() returns null as it's not configured yet", tc.getList(), is(nullValue())); - assertThrows(NoSuchMethodException.class, () -> - { - xmlConfiguration.configure(tc); - }); + assertThrows(NoSuchMethodException.class, () -> xmlConfiguration.configure(tc)); } @Test public void testArrayListSetter() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + INT_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + INT_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getSet() returns null as it's not configured yet", tc.getList(), is(nullValue())); xmlConfiguration.configure(tc); @@ -459,8 +476,8 @@ public class XmlConfigurationTest @Test public void testSetSetter() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + STRING_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + STRING_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getSet() returns null as it's not configured yet", tc.getSet(), is(nullValue())); xmlConfiguration.configure(tc); @@ -470,8 +487,8 @@ public class XmlConfigurationTest @Test public void testSetSetterWithPrimitiveArray() throws Exception { - XmlConfiguration xmlConfiguration = asXmlConfiguration("" - + INT_ARRAY_XML + ""); + XmlConfiguration xmlConfiguration = asXmlConfiguration("" + + INT_ARRAY_XML + ""); TestConfiguration tc = new TestConfiguration(); assertThat("tc.getSet() returns null as it's not configured yet", tc.getSet(), is(nullValue())); xmlConfiguration.configure(tc); @@ -641,6 +658,72 @@ public class XmlConfigurationTest assertEquals("arg3", atc.getNested().getThird(), "nested third parameter not wired correctly"); } + private static class TestOrder + { + public void call() + { + } + + public void call(int o) + { + } + + public void call(Object o) + { + } + + public void call(String s) + { + } + + public void call(String... ss) + { + } + + public void call(String s, String... ss) + { + } + } + + @RepeatedTest(10) + public void testMethodOrdering() throws Exception + { + List methods = Arrays.stream(TestOrder.class.getMethods()).filter(m -> "call".equals(m.getName())).collect(Collectors.toList()); + Collections.shuffle(methods); + Collections.sort(methods, XmlConfiguration.EXECUTABLE_COMPARATOR); + assertThat(methods, Matchers.contains( + TestOrder.class.getMethod("call"), + TestOrder.class.getMethod("call", int.class), + TestOrder.class.getMethod("call", String.class), + TestOrder.class.getMethod("call", Object.class), + TestOrder.class.getMethod("call", String[].class), + TestOrder.class.getMethod("call", String.class, String[].class) + )); + } + + @Test + public void testOverloadedCall() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " 1" + + " " + + " " + + " 2" + + " " + + " " + + " 3" + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("1", atc.getFirst()); + assertEquals("2", atc.getSecond()); + assertEquals("3", atc.getThird()); + } + @Test public void testNestedConstructorNamedInjectionUnOrdered() throws Exception { @@ -695,6 +778,171 @@ public class XmlConfigurationTest assertEquals("arg3", atc.getNested().getThird(), "nested third parameter not wired correctly"); } + @Test + public void testCallNamedInjection() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " arg1 " + + " arg2 " + + " arg3 " + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly"); + assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly"); + assertEquals("arg3", atc.getThird(), "third parameter not wired correctly"); + } + + @Test + public void testCallNamedInjectionOrdered() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " arg1 " + + " arg2 " + + " arg3 " + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly"); + assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly"); + assertEquals("arg3", atc.getThird(), "third parameter not wired correctly"); + } + + @Test + public void testCallNamedInjectionUnOrdered() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " arg1 " + + " arg3 " + + " arg2 " + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly"); + assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly"); + assertEquals("arg3", atc.getThird(), "third parameter not wired correctly"); + } + + @Test + public void testCallNamedInjectionOrderedMixed() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " arg1 " + + " arg2 " + + " arg3 " + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly"); + assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly"); + assertEquals("arg3", atc.getThird(), "third parameter not wired correctly"); + } + + @Test + public void testCallNamedInjectionUnorderedMixed() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " arg3 " + + " arg2 " + + " arg1 " + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly"); + assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly"); + assertEquals("arg3", atc.getThird(), "third parameter not wired correctly"); + } + + @Test + public void testCallVarArgs() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " one " + + " twothree " + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("one", atc.getFirst(), "first parameter not wired correctly"); + assertEquals("two", atc.getSecond(), "second parameter not wired correctly"); + assertEquals("three", atc.getThird(), "third parameter not wired correctly"); + } + + @Test + public void testCallMissingVarArgs() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " arg1 " + + " arg2 " + + " arg3 " + + " " + + " one" + + " " + + ""); + + AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure(); + + assertEquals("one", atc.getFirst(), "first parameter not wired correctly"); + assertNull(atc.getSecond()); + assertNull(atc.getThird()); + } + + public static List typeTestData() + { + return Arrays.asList( + "byte", + "int", + "short", + "long", + "float", + "double", + "Byte", + "Integer", + "Short", + "Long", + "Float", + "Double"); + } + + @ParameterizedTest + @MethodSource("typeTestData") + public void testCallNumberConversion(String type) throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " 42" + + " " + + ""); + + TestConfiguration tc = (TestConfiguration)xmlConfiguration.configure(); + assertEquals(42.0D, tc.number); + } + @Test public void testArgumentsGetIgnoredMissingDTD() throws Exception { @@ -858,7 +1106,7 @@ public class XmlConfigurationTest " bad" + ""); - assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure()); + assertThrows(InvocationTargetException.class, xmlConfiguration::configure); } @Test @@ -869,7 +1117,7 @@ public class XmlConfigurationTest " 100 bas" + ""); - assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure()); + assertThrows(InvocationTargetException.class, xmlConfiguration::configure); } @Test @@ -936,7 +1184,7 @@ public class XmlConfigurationTest " 1.5" + ""); - assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure()); + assertThrows(InvocationTargetException.class, xmlConfiguration::configure); } @Test @@ -1053,7 +1301,7 @@ public class XmlConfigurationTest } @Test - public void testJettyStandardIdsAndProperties_JettyHome_JettyBase() throws Exception + public void testJettyStandardIdsAndPropertiesAndJettyHomeAndJettyBase() throws Exception { String[] propNames = new String[] { @@ -1082,7 +1330,7 @@ public class XmlConfigurationTest } @Test - public void testJettyStandardIdsAndProperties_JettyHomeUri_JettyBaseUri() throws Exception + public void testJettyStandardIdsAndPropertiesAndJettyHomeUriAndJettyBaseUri() throws Exception { String[] propNames = new String[] { @@ -1110,8 +1358,187 @@ public class XmlConfigurationTest } } + public static class BarNamed + { + private String foo; + private List zeds; + + public BarNamed(@Name("foo") String foo) + { + this.foo = foo; + } + + public void addZed(String zed) + { + if (zeds == null) + zeds = new ArrayList<>(); + zeds.add(zed); + } + + public List getZeds() + { + return zeds; + } + + public String getFoo() + { + return foo; + } + } + @Test - public void testJettyStandardIdsAndProperties_JettyWebappsUri() throws Exception + public void testConfiguredWithNamedArg() throws Exception + { + XmlConfiguration xmlFoo = asXmlConfiguration("foo.xml", + "\n" + + " \n" + + " foozball\n" + + " \n" + + ""); + XmlConfiguration xmlBar = asXmlConfiguration("bar.xml", + "\n" + + " \n" + + ""); + + ByteArrayOutputStream logBytes = captureLoggingBytes(() -> + { + Map idMap = mimicXmlConfigurationMain(xmlFoo, xmlBar); + Object obj = idMap.get("bar"); + assertThat("BarNamed instance created", obj, instanceOf(BarNamed.class)); + BarNamed bar = (BarNamed)obj; + assertThat("BarNamed has foo", bar.getFoo(), is("foozball")); + }); + + List warnings = Arrays.stream(logBytes.toString(UTF_8.name()).split(System.lineSeparator())) + .filter(line -> line.contains(":WARN")) + .collect(Collectors.toList()); + + assertThat("WARN logs size", warnings.size(), is(0)); + } + + @Test + public void testConfiguredWithArgNotUsingName() throws Exception + { + XmlConfiguration xmlFoo = asXmlConfiguration("foo.xml", + "\n" + + " \n" + + " foozball\n" + + " \n" + + ""); + XmlConfiguration xmlBar = asXmlConfiguration("bar.xml", + "\n" + + " \n" + // no name specified + ""); + + ByteArrayOutputStream logBytes = captureLoggingBytes(() -> + { + Map idMap = mimicXmlConfigurationMain(xmlFoo, xmlBar); + Object obj = idMap.get("bar"); + assertThat("BarNamed instance created", obj, instanceOf(BarNamed.class)); + BarNamed bar = (BarNamed)obj; + assertThat("BarNamed has foo", bar.getFoo(), is("foozball")); + }); + + List warnings = Arrays.stream(logBytes.toString(UTF_8.name()).split(System.lineSeparator())) + .filter(line -> line.contains(":WARN :")) + .collect(Collectors.toList()); + + assertThat("WARN logs size", warnings.size(), is(0)); + } + + @Test + public void testConfiguredWithBadNamedArg() throws Exception + { + XmlConfiguration xmlBar = asXmlConfiguration("bar.xml", + "\n" + + " foozball\n" + // wrong name specified + ""); + + IllegalStateException cause = assertThrows(IllegalStateException.class, () -> + mimicXmlConfigurationMain(xmlBar)); + + assertThat("Cause message", cause.getMessage(), containsString("No matching constructor")); + } + + @Test + public void testConfiguredWithTooManyNamedArgs() throws Exception + { + XmlConfiguration xmlBar = asXmlConfiguration("bar.xml", + "\n" + + " foozball\n" + + " soccer\n" + // neither should win + ""); + + IllegalStateException cause = assertThrows(IllegalStateException.class, () -> + mimicXmlConfigurationMain(xmlBar)); + + assertThat("Cause message", cause.getMessage(), containsString("No matching constructor")); + } + + @Test + public void testConfiguredSameWithNamedArgTwice() throws Exception + { + XmlConfiguration xmlFoo = asXmlConfiguration("foo.xml", + "\n" + + " \n" + + " foozball\n" + + " \n" + + ""); + XmlConfiguration xmlBar = asXmlConfiguration("bar.xml", + "\n" + + " \n" + + ""); + XmlConfiguration xmlAddZed = asXmlConfiguration("zed.xml", + "\n" + + " baz\n" + // the invalid line + " \n" + + " plain-zero\n" + + " \n" + + ""); + + ByteArrayOutputStream logBytes = captureLoggingBytes(() -> + { + Map idMap = mimicXmlConfigurationMain(xmlFoo, xmlBar, xmlAddZed); + Object obj = idMap.get("bar"); + assertThat("BarNamed instance created", obj, instanceOf(BarNamed.class)); + BarNamed bar = (BarNamed)obj; + assertThat("BarNamed has foo", bar.getFoo(), is("foozball")); + List zeds = bar.getZeds(); + assertThat("BarNamed has zeds", zeds, not(empty())); + assertThat("Zeds[0]", zeds.get(0), is("plain-zero")); + }); + + List warnings = Arrays.stream(logBytes.toString(UTF_8.name()).split(System.lineSeparator())) + .filter(line -> line.contains(":WARN :")) + .collect(Collectors.toList()); + + assertThat("WARN logs count", warnings.size(), is(1)); + + String actualWarn = warnings.get(0); + assertThat("WARN logs", actualWarn, + allOf(containsString("Ignored arg mimicXmlConfigurationMain(XmlConfiguration... configurations) throws Exception + { + XmlConfiguration last = null; + for (XmlConfiguration configuration : configurations) + { + if (last != null) + configuration.getIdMap().putAll(last.getIdMap()); + configuration.configure(); + last = configuration; + } + return last.getIdMap(); + } + + @Test + public void testJettyStandardIdsAndPropertiesJettyWebappsUri() throws Exception { Path war = MavenTestingUtils.getTargetPath("no.war"); XmlConfiguration configuration = @@ -1143,31 +1570,51 @@ public class XmlConfigurationTest " " + ""); - ByteArrayOutputStream logBytes = null; - Logger logger = Log.getLogger(XmlConfiguration.class); - if (logger instanceof StdErrLog) - { - StdErrLog stdErrLog = (StdErrLog)logger; - logBytes = new ByteArrayOutputStream(); - stdErrLog.setStdErrStream(new PrintStream(logBytes)); - } + ByteArrayOutputStream logBytes = captureLoggingBytes(xmlConfiguration::configure); - xmlConfiguration.configure(); + String[] lines = logBytes.toString(UTF_8.name()).split(System.lineSeparator()); + List warnings = Arrays.stream(lines) + .filter(line -> line.contains(":WARN :")) + .filter(line -> line.contains(testClass.getSimpleName())) + .collect(Collectors.toList()); + // 1. Deprecated constructor + // 2. Deprecated method + // 3. Deprecated method + // 4. Deprecated method + // 5. Deprecated field + // 6. Deprecated field + assertEquals(6, warnings.size()); + } - if (logBytes != null) + private ByteArrayOutputStream captureLoggingBytes(ThrowableAction action) throws Exception + { + Logger slf4jLogger = LoggerFactory.getLogger(XmlConfiguration.class); + Assumptions.assumeTrue(slf4jLogger instanceof JettyLogger); + + ByteArrayOutputStream logBytes = new ByteArrayOutputStream(); + JettyLogger jettyLogger = (JettyLogger)slf4jLogger; + StdErrAppender appender = (StdErrAppender)jettyLogger.getAppender(); + PrintStream oldStream = appender.getStream(); + int oldLevel = jettyLogger.getLevel(); + try { - String[] lines = logBytes.toString("UTF-8").split(System.lineSeparator()); - List warnings = Arrays.stream(lines) - .filter(line -> line.contains(":WARN:")) - .filter(line -> line.contains(testClass.getSimpleName())) - .collect(Collectors.toList()); - // 1. Deprecated constructor - // 2. Deprecated method - // 3. Deprecated method - // 4. Deprecated method - // 5. Deprecated field - // 6. Deprecated field - assertEquals(6, warnings.size()); + // capture events + appender.setStream(new PrintStream(logBytes, true)); + // make sure we are seeing WARN level events + jettyLogger.setLevel(Level.WARN); + + action.run(); } + finally + { + appender.setStream(oldStream); + jettyLogger.setLevel(oldLevel); + } + return logBytes; + } + + private interface ThrowableAction + { + void run() throws Exception; } } diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java index 91661dab8fb..24d1c84e4a5 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.xml; diff --git a/jetty-xml/src/test/resources/jetty-logging.properties b/jetty-xml/src/test/resources/jetty-logging.properties index 1759774266b..263223fbcc0 100644 --- a/jetty-xml/src/test/resources/jetty-logging.properties +++ b/jetty-xml/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl org.eclipse.jetty.xml.LEVEL=WARN org.eclipse.jetty.util.LEVEL=WARN \ No newline at end of file diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml index 6f68825706a..4c134422add 100644 --- a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml +++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configureWithElements.xml @@ -1,7 +1,8 @@ - + + org.eclipse.jetty.xml.TestConfiguration name SetValue @@ -69,7 +70,6 @@ String - java.lang.Integer @@ -87,25 +87,33 @@ 2.3 + + testId + org.eclipse.jetty.xml.TestConfiguration + nested + + - - org.eclipse.jetty.xml.TestConfiguration - nested + + testId - + - + + call - + + call false - + + call true put Call1 diff --git a/logos/jetty-avatar.svg b/logos/jetty-avatar.svg index f667369af46..3e7e3fd206d 100644 --- a/logos/jetty-avatar.svg +++ b/logos/jetty-avatar.svg @@ -1,44 +1,11 @@ - - - - - + + + + - - - - - + + + + - - - - + + + + - http://www.eclipse.org/jetty UTF-8 1.4 - 1.8.0-beta2 - 2.11.2 - 1.3.0-alpha4 + 8.20 + 2.0.0-alpha1 + 2.13.0 + 1.3.0-alpha5 5.1.1.RELEASE 1.2 - 4.0.2 - 9.0.19 + 4.0.3 + 1.1.2 + 9.0.29 9.4.8.Final - - undefined - 2.1.0 - 7.1 + 2.4.0 + 7.2 1.21 benchmarks - 1.2.0 - 1.1.5 + 1.4.0 + 1.1.7 5.5.1 3.6.0 1.3.1 - 2.4.5.Final + 3.1.2.Final 1.0.5 @@ -45,7 +45,7 @@ -Dfile.encoding=UTF-8 -Duser.language=en -Duser.region=US -showversion -Xmx1g -Xms1g -Xlog:gc:stderr:time,level,tags - 3.0.0-M3 + 3.0.0-M4 3.8.1 3.1.1 3.1.0 @@ -63,20 +63,20 @@ otherwise depending on Spring Boot might be chicken and egg issue :) --> 2.1.1.RELEASE 1.3.4 - 2.9.7 + 2.9.9 ${project.build.directory}/local-repo src/it/settings.xml - + 0 - Apache Software License - Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0 + Eclipse Public License - Version 2.0 + https://www.eclipse.org/legal/epl-2.0 - Eclipse Public License - Version 1.0 - http://www.eclipse.org/org/documents/epl-v10.php + Apache Software License - Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 @@ -88,6 +88,7 @@ build-resources + jetty-slf4j-impl jetty-ant jetty-util jetty-jmx @@ -97,6 +98,7 @@ jetty-server jetty-xml jetty-security + jetty-openid jetty-servlet jetty-webapp jetty-fcgi @@ -271,7 +273,7 @@ true false - javadoc:aggregate-jar deploy + deploy -Peclipse-release clean install forked-path @@ -282,13 +284,14 @@ maven-remote-resources-plugin + copy-shared-resources generate-resources process - org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.2 + org.eclipse.jetty:build-resources:${project.version} @@ -330,7 +333,7 @@ true true - ${project.inceptionYear}-2019 + ${project.inceptionYear}-2020 @@ -341,12 +344,14 @@ check -
        header-template-java.txt
        +
        header-template.txt
        DOUBLESLASH_STYLE + DOUBLESLASH_STYLE **/*.java + **/*.adoc jetty-util/src/main/java/org/eclipse/jetty/util/security/UnixCrypt.java @@ -358,22 +363,6 @@
        - - check-doc-headers - verify - - check - - -
        header-template-doc.txt
        - - DOUBLESLASH_STYLE - - - **/*.adoc - -
        -
        @@ -415,6 +404,43 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.0 + + jetty-checkstyle.xml + true + warning + true + + + ${project.build.sourceDirectory} + ${project.build.testSourceDirectory} + + + + + org.eclipse.jetty + build-resources + ${project.version} + + + com.puppycrawl.tools + checkstyle + ${checkstyle.version} + + + + + checkstyle-check + validate + + check + + + + @@ -436,28 +462,6 @@ - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.1.0 - - jetty-checkstyle.xml - jetty-suppressions.xml - checkstyle.suppressions.file - - - - org.eclipse.jetty - build-resources - 10.0.0-alpha0 - - - com.puppycrawl.tools - checkstyle - 8.20 - - - org.apache.maven.plugins maven-clean-plugin @@ -471,6 +475,11 @@ ${compiler.source} ${compiler.target} ${compiler.release} + true + + -Xlint:exports + + -nowarn @@ -504,8 +513,9 @@ org.apache.maven.plugins maven-invoker-plugin - 3.2.1-SNAPSHOT + 3.2.1 + true true org.eclipse.jetty.maven.its ${it.debug} @@ -550,7 +560,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.1 + 3.2.0 true true @@ -567,6 +577,7 @@ true true com.*:org.slf4j*:org.mortbay*:*.jmh*:org.eclipse.jetty.embedded*:org.eclipse.jetty.example.asyncrest*:org.eclipse.jetty.test* + apache-jstl,jetty-osgi-alpn,infinispan-common,infinispan-embedded,infinispan-embedded-query,infinispan-remote,infinispan-remote-query,jetty-plus,jetty-jndi,jetty-documentation,jetty-distribution,jetty-home,jetty-bom,jetty-all,jetty-runner @@ -582,7 +593,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.11.0 + 3.13.0 org.apache.maven.plugins @@ -597,7 +608,7 @@ org.apache.maven.plugins maven-remote-resources-plugin - 1.5 + 1.6.0 org.apache.maven.plugins @@ -607,7 +618,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.1 + 3.2.2 org.apache.maven.plugins @@ -631,6 +642,7 @@ maven-surefire-plugin ${maven.surefire.version} + ${surefire.rerunFailingTestsCount} 3600 @{argLine} ${jetty.surefire.argLine} @@ -638,6 +650,8 @@ false 1 true + + alphabetical ${project.build.directory} ${unix.socket.tmp} @@ -661,12 +675,12 @@ org.eclipse.jetty.toolchain jetty-version-maven-plugin - 2.5 + 2.6 org.jacoco jacoco-maven-plugin - 0.8.2 + 0.8.5 com.agilejava.docbkx @@ -691,11 +705,11 @@ ${bundle-symbolic-name} Jetty module for ${project.name} - JavaSE-1.8 + JavaSE-11 ${jetty.url} Eclipse Jetty Project . - Copyright (c) 2008-2019 Mort Bay Consulting Pty. Ltd. + Copyright (c) 2008-2020 Mort Bay Consulting Pty Ltd and others. <_provider-policy>$<range;[===,=+)> <_consumer-policy>$<range;[===,+)> <_noee>true @@ -918,7 +932,7 @@ com.github.madgnome h2spec-maven-plugin - 0.4 + 0.6 @@ -939,6 +953,12 @@ + + org.eclipse.jetty + jetty-slf4j-impl + ${project.version} + test + org.eclipse.jetty.toolchain jetty-servlet-api @@ -947,7 +967,7 @@ org.eclipse.jetty.toolchain jetty-javax-websocket-api - 1.1.1 + ${websocket.api.version} jakarta.annotation @@ -1083,7 +1103,17 @@ com.github.jnr jnr-unixsocket - 0.22 + 0.24 + + + org.apache.derby + derby + 10.14.2.0 + + + org.apache.derby + derbytools + 10.14.2.0 @@ -1280,6 +1310,7 @@ ci ${env.GLOBAL_MVN_SETTINGS} + 3 aggregates/jetty-all @@ -1316,7 +1347,6 @@ true false true - Tag for release: jetty-${project.version} jetty-documentation/.* examples/.* @@ -1404,21 +1434,11 @@ jetty-snapshots jetty-snapshots - http://oss.sonatype.org/content/repositories/jetty-snapshots + https://oss.sonatype.org/content/repositories/jetty-snapshots true - oss.snapshots OSS Snapshots @@ -1560,29 +1580,4 @@ scp://build.eclipse.org:/home/data/httpd/download.eclipse.org/jetty/${project.version}/ - - - - - apache.snapshots - https://repository.apache.org/content/repositories/snapshots - - false - - - true - - - - plexus-snapshots - https://oss.sonatype.org/content/repositories/plexus-snapshots - - false - - - true - - - - diff --git a/scripts/release-jetty.sh b/scripts/release-jetty.sh index 6dedce27661..408a639c68b 100755 --- a/scripts/release-jetty.sh +++ b/scripts/release-jetty.sh @@ -167,7 +167,7 @@ if proceedyn "Are you sure you want to release using above? (y/N)" n; then # This is equivalent to 'mvn release:perform' if proceedyn "Build/Deploy from tag $TAG_NAME? (Y/n)" y; then git checkout $TAG_NAME - mvn clean package source:jar javadoc:jar gpg:sign deploy \ + mvn clean package source:jar javadoc:jar gpg:sign javadoc:aggregate-jar deploy \ -Peclipse-release $DEPLOY_OPTS reportMavenTestFailures git checkout $GIT_BRANCH_ID @@ -190,7 +190,7 @@ if proceedyn "Are you sure you want to release using above? (y/N)" n; then fi if proceedyn "Push git commits to remote $GIT_REMOTE_ID? (Y/n)" y; then git push $GIT_REMOTE_ID $GIT_BRANCH_ID - git push $GIT_REMOTE_ID --tags + git push $GIT_REMOTE_ID $TAG_NAME fi else echo "Not performing release" diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/HttpTester.java b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/HttpTester.java index c7b847541e7..6f0c62e6cdb 100644 --- a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/HttpTester.java +++ b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/HttpTester.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.tools; @@ -39,8 +39,6 @@ import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; /** * A HTTP Testing helper class. @@ -70,8 +68,6 @@ import org.eclipse.jetty.util.log.Logger; */ public class HttpTester { - private static final Logger LOG = Log.getLogger(HttpTester.class); - public abstract static class Input { protected final ByteBuffer _buffer; @@ -462,6 +458,12 @@ public class HttpTester header = BufferUtil.allocate(8192); continue; + case HEADER_OVERFLOW: + if (header.capacity() >= 32 * 1024) + throw new BadMessageException(500, "Header too large"); + header = BufferUtil.allocate(32 * 1024); + continue; + case NEED_CHUNK: chunk = BufferUtil.allocate(HttpGenerator.CHUNK_SIZE); continue; @@ -508,18 +510,6 @@ public class HttpTester } public abstract MetaData getInfo(); - - @Override - public int getHeaderCacheSize() - { - return 0; - } - - @Override - public boolean isHeaderCacheCaseSensitive() - { - return false; - } } public static class Request extends Message implements HttpParser.RequestHandler @@ -528,12 +518,11 @@ public class HttpTester private String _uri; @Override - public boolean startRequest(String method, String uri, HttpVersion version) + public void startRequest(String method, String uri, HttpVersion version) { _method = method; _uri = uri; _version = version; - return false; } public String getMethod() @@ -580,12 +569,11 @@ public class HttpTester private String _reason; @Override - public boolean startResponse(HttpVersion version, int status, String reason) + public void startResponse(HttpVersion version, int status, String reason) { _version = version; _status = status; _reason = reason; - return false; } public int getStatus() diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java index 035182c77af..d46be1f396e 100644 --- a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java +++ b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.tools.matchers; diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java index 8495d163589..f109f08c16e 100644 --- a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java +++ b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.tools.matchers; diff --git a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java index d82465d59bb..b74737c360d 100644 --- a/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java +++ b/tests/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.tools.matchers; diff --git a/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/HttpTesterTest.java b/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/HttpTesterTest.java index 64950986289..c09db1f6497 100644 --- a/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/HttpTesterTest.java +++ b/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/HttpTesterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.tools; diff --git a/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java b/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java index 4748d68927b..f7572db8b73 100644 --- a/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java +++ b/tests/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.tools.matchers; @@ -55,7 +55,7 @@ public class HttpFieldsMatchersTest } @Test - public void testContainsHeader_MisMatch() + public void testContainsHeaderMisMatch() { HttpFields fields = new HttpFields(); fields.put("a", "foo"); @@ -71,7 +71,7 @@ public class HttpFieldsMatchersTest } @Test - public void testContainsHeaderValue_MisMatch_NoSuchHeader() + public void testContainsHeaderValueMisMatchNoSuchHeader() { HttpFields fields = new HttpFields(); fields.put("a", "foo"); @@ -87,7 +87,7 @@ public class HttpFieldsMatchersTest } @Test - public void testContainsHeaderValue_MisMatch_NoSuchValue() + public void testContainsHeaderValueMisMatchNoSuchValue() { HttpFields fields = new HttpFields(); fields.put("a", "foo"); diff --git a/tests/jetty-jmh/pom.xml b/tests/jetty-jmh/pom.xml index bc4827112ef..edf3878dfd9 100644 --- a/tests/jetty-jmh/pom.xml +++ b/tests/jetty-jmh/pom.xml @@ -97,6 +97,15 @@ org.eclipse.jetty.toolchain jetty-servlet-api + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java index ef7390240fd..c36f6ee1bb3 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.io.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java index 085d4cecd19..20eb5986240 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.requestlog.jmh; @@ -87,10 +87,11 @@ public class RequestLogBenchmark { MethodType logType = methodType(Void.TYPE, StringBuilder.class, String.class); - MethodHandle append = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class)); - MethodHandle logURI = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logURI", logType); - MethodHandle logAddr = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logAddr", logType); - MethodHandle logLength = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logLength", logType); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandle append = lookup.findStatic(RequestLogBenchmark.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class)); + MethodHandle logURI = lookup.findStatic(RequestLogBenchmark.class, "logURI", logType); + MethodHandle logAddr = lookup.findStatic(RequestLogBenchmark.class, "logAddr", logType); + MethodHandle logLength = lookup.findStatic(RequestLogBenchmark.class, "logLength", logType); // setup iteration iteratedLog = new Object[] diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/DeflaterPoolBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/DeflaterPoolBenchmark.java index 04172bb6b8a..72500ca72a0 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/DeflaterPoolBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/DeflaterPoolBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/ListVsMapBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/ListVsMapBenchmark.java index 001314781e5..7f61dbde47a 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/ListVsMapBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/ListVsMapBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringIsEmptyBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringIsEmptyBenchmark.java index de0c46ad91d..2aeb994d33c 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringIsEmptyBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringIsEmptyBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheBenchmark.java index ccceae86139..202f95b50f0 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTick.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTick.java index 929cbd4c4f7..85c95db3b27 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTick.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTick.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTickBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTickBenchmark.java index cfcbd907704..7ab35ad09f1 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTickBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTickBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormat.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormat.java index 3cef756975c..1b6e8076480 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormat.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormat.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormatBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormatBenchmark.java index edb205337c0..e10b72601ed 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormatBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormatBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/logs/LogCondensePackageStringBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/logs/LogCondensePackageStringBenchmark.java deleted file mode 100644 index 3bdb92ffafc..00000000000 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/logs/LogCondensePackageStringBenchmark.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -import java.util.concurrent.TimeUnit; - -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Param; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.Warmup; -import org.openjdk.jmh.infra.Blackhole; -import org.openjdk.jmh.profile.GCProfiler; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -@Fork(value = 5) -@State(Scope.Benchmark) - -@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) -public class LogCondensePackageStringBenchmark -{ - @Param({ - "com.acme.Dump", - "org.eclipse.jetty.websocket.common.extensions.compress.DeflateFrameExtension$Pool" - }) - String fqClassName; - - @Benchmark - public void testCondensePackage(Blackhole blackhole) - { - blackhole.consume(AbstractLogger.condensePackageString(fqClassName)); - } - - public static void main(String[] args) throws RunnerException - { - Options opt = new OptionsBuilder() - .include(LogCondensePackageStringBenchmark.class.getSimpleName()) - .addProfiler(GCProfiler.class) - .build(); - - new Runner(opt).run(); - } -} diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ThreadPoolBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ThreadPoolBenchmark.java index 02fb4aa1a89..2609e5fd857 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ThreadPoolBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ThreadPoolBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/EWYKBenchmark.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/EWYKBenchmark.java index 37343ffa0a9..cbf38c84df5 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/EWYKBenchmark.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/EWYKBenchmark.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread.strategy.jmh; diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestConnection.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestConnection.java index 4c946772026..ed168ffb98f 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestConnection.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestConnection.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread.strategy.jmh; @@ -25,13 +25,16 @@ import java.util.Queue; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; -import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.thread.ExecutionStrategy.Producer; import org.eclipse.jetty.util.thread.Invocable; import org.openjdk.jmh.infra.Blackhole; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestConnection implements Producer { + private static final Logger LOG = LoggerFactory.getLogger(TestConnection.class); + private final TestServer _server; private final String _sessionid; private final boolean _sleeping; @@ -125,7 +128,7 @@ public class TestConnection implements Producer } catch (InterruptedException e) { - Log.getLogger(TestConnection.class).ignore(e); + LOG.trace("IGNORED", e); } } else diff --git a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestServer.java b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestServer.java index 63b39beff68..a5356e2e80e 100644 --- a/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestServer.java +++ b/tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.util.thread.strategy.jmh; diff --git a/tests/jetty-jmh/src/main/resources/jetty-logging.properties b/tests/jetty-jmh/src/main/resources/jetty-logging.properties index 799aa62aed3..ab545e4ab63 100644 --- a/tests/jetty-jmh/src/main/resources/jetty-logging.properties +++ b/tests/jetty-jmh/src/main/resources/jetty-logging.properties @@ -1,4 +1,4 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.server.LEVEL=DEBUG #org.eclipse.jetty.http.LEVEL=DEBUG diff --git a/tests/jetty-jmh/src/main/resources/keystore b/tests/jetty-jmh/src/main/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/tests/jetty-jmh/src/main/resources/keystore and /dev/null differ diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index d2b68b0097d..59abe41b08b 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -14,15 +14,15 @@ - - org.slf4j - slf4j-simple - org.eclipse.jetty jetty-util ${project.version} + + org.slf4j + slf4j-api + org.apache.maven maven-artifact @@ -48,6 +48,11 @@ ${maven.resolver.version} + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty jetty-distribution @@ -76,7 +81,7 @@ org.eclipse.jetty.tests - test-cdi2-webapp + test-weld-cdi-webapp ${project.version} war test @@ -115,6 +120,13 @@ test war + + org.eclipse.jetty.tests + test-bad-websocket-webapp + ${project.version} + test + war + diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java index c7c4c84a537..aae25684091 100644 --- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java +++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; @@ -65,8 +65,8 @@ import org.eclipse.aether.transport.http.HttpTransporterFactory; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *

        Helper class to test the Jetty Distribution

        . @@ -97,7 +97,7 @@ import org.eclipse.jetty.util.log.Logger; * // Wait for Jetty to be fully started. * assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS)); * - * // Make a HTTP request to the web application. + * // Make an HTTP request to the web application. * HttpClient client = new HttpClient(); * client.start(); * ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp"); @@ -108,7 +108,7 @@ import org.eclipse.jetty.util.log.Logger; */ public class DistributionTester { - private static final Logger LOGGER = Log.getLogger(DistributionTester.class); + private static final Logger LOGGER = LoggerFactory.getLogger(DistributionTester.class); private Config config; @@ -127,6 +127,16 @@ public class DistributionTester return start(Arrays.asList(args)); } + public Path getJettyBase() + { + return config.jettyBase; + } + + public Path getJettyHome() + { + return config.jettyHome; + } + /** * Start the distribution with the arguments * @@ -469,9 +479,6 @@ public class DistributionTester consoleStreamers.forEach(ConsoleStreamer::stop); } - /** - * @see #destroy() - */ @Override public void close() { @@ -521,7 +528,7 @@ public class DistributionTester String line; while ((line = reader.readLine()) != null && !stop) { - LOGGER.info("{}", line); + LOGGER.info(line); logs.add(line); } } @@ -541,6 +548,11 @@ public class DistributionTester IO.close(reader); } } + + public Queue getLogs() + { + return logs; + } } public static class Builder diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java index 1050918ed13..42c7730e35d 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java index 190bc381743..237e0fa7b14 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; @@ -44,7 +44,7 @@ public class BadAppTests extends AbstractDistributionTest * It is expected that the server does not start and exits with an error code */ @Test - public void testXml_ThrowOnUnavailable_True() throws Exception + public void testXmlThrowOnUnavailableTrue() throws Exception { String jettyVersion = System.getProperty("jettyVersion"); DistributionTester distribution = DistributionTester.Builder.newInstance() @@ -81,7 +81,7 @@ public class BadAppTests extends AbstractDistributionTest * that it is unavailable. */ @Test - public void testXml_ThrowOnUnavailable_False() throws Exception + public void testXmlThrowOnUnavailableFalse() throws Exception { String jettyVersion = System.getProperty("jettyVersion"); DistributionTester distribution = DistributionTester.Builder.newInstance() @@ -103,13 +103,13 @@ public class BadAppTests extends AbstractDistributionTest int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/badapp/"); assertEquals(HttpStatus.SERVICE_UNAVAILABLE_503, response.getStatus()); - assertThat(response.getContentAsString(), containsString("Unavailable")); - assertThat(response.getContentAsString(), containsString("Problem accessing /badapp/")); + assertThat(response.getContentAsString(), containsString("

        HTTP ERROR 503 Service Unavailable

        ")); + assertThat(response.getContentAsString(), containsString("URI:/badapp/")); } } } @@ -123,7 +123,7 @@ public class BadAppTests extends AbstractDistributionTest * that it is unavailable. */ @Test - public void testNoXml_ThrowOnUnavailable_Default() throws Exception + public void testNoXmlThrowOnUnavailableDefault() throws Exception { String jettyVersion = System.getProperty("jettyVersion"); DistributionTester distribution = DistributionTester.Builder.newInstance() @@ -143,13 +143,13 @@ public class BadAppTests extends AbstractDistributionTest int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/badapp/"); assertEquals(HttpStatus.SERVICE_UNAVAILABLE_503, response.getStatus()); - assertThat(response.getContentAsString(), containsString("Unavailable")); - assertThat(response.getContentAsString(), containsString("Problem accessing /badapp/")); + assertThat(response.getContentAsString(), containsString("

        HTTP ERROR 503 Service Unavailable

        ")); + assertThat(response.getContentAsString(), containsString("URI:/badapp/")); } } } diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java index adbe7999bbd..754f4a4aaaf 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java @@ -1,103 +1,81 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.stream.Stream; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.http.HttpStatus; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled("Until issue is fixed at weld -> https://github.com/eclipse/jetty.project/issues/3803") public class CDITests extends AbstractDistributionTest { - /** - * Tests a WAR file that is CDI complete as it includes the weld - * library in its WEB-INF/lib directory. - */ - @Test - public void testCDI2_IncludedInWebapp() throws Exception + // Tests from here use these parameters + public static Stream tests() { - String jettyVersion = System.getProperty("jettyVersion"); - DistributionTester distribution = DistributionTester.Builder.newInstance() - .jettyVersion(jettyVersion) - .mavenLocalRepository(System.getProperty("mavenRepoPath")) - .build(); - - String[] args1 = { - "--create-startd", - "--approve-all-licenses", - "--add-to-start=http,deploy,annotations,jsp" - }; - try (DistributionTester.Run run1 = distribution.start(args1)) + Consumer renameJettyWebOwbXml = d -> { - assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); - assertEquals(0, run1.getExitValue()); - - File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-cdi2-webapp:war:" + jettyVersion); - distribution.installWarFile(war, "demo"); - - distribution.installBaseResource("cdi/demo_context.xml", "webapps/demo.xml"); - - int port = distribution.freePort(); - try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) + try { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); - - startHttpClient(); - ContentResponse response = client.GET("http://localhost:" + port + "/demo/greetings"); - assertEquals(HttpStatus.OK_200, response.getStatus()); - // Confirm Servlet based CDI - assertThat(response.getContentAsString(), containsString("Hello GreetingsServlet")); - // Confirm Listener based CDI (this has been a problem in the past, keep this for regression testing!) - assertThat(response.getHeaders().get("Server"), containsString("CDI-Demo-org.eclipse.jetty.test")); - - run2.stop(); - assertTrue(run2.awaitFor(5, TimeUnit.SECONDS)); + Path jettyWebOwbXml = d.getJettyBase().resolve("webapps/demo/WEB-INF/jetty-web-owb.xml"); + Path jettyWebXml = d.getJettyBase().resolve("webapps/demo/WEB-INF/jetty-web.xml"); + Files.move(jettyWebOwbXml, jettyWebXml); } - } + catch (IOException e) + { + throw new RuntimeException(e); + } + }; + + return Stream.of( + // -- Weld -- + Arguments.of("weld", "cdi-spi", null), // Weld >= 3.1.2 + Arguments.of("weld", "decorate", null), // Weld >= 3.1.2 + // TODO Arguments.of("weld", "cdi-decorate", null), // Weld >= 3.1.3 + + // -- Apache OpenWebBeans -- + Arguments.of("owb", "cdi-spi", null) + // Arguments.of("owb", "decorate", null), // Not supported + // Arguments.of("owb", "cdi-decorate", null) // Not supported + ); } /** - * Tests a WAR file that is expects CDI to be configured by the server. - * - *

        - * This means the WAR has the weld libs in its - * WEB-INF/lib directory. - *

        - * - *

        - * The expectation is that a context xml deployable file is not - * required when using this `cdi2` module, and the appropriate - * server side libs are made available to allow weld to function. - * (the required server side javax.el support comes from the cdi2 module) - *

        + * Tests a WAR file that includes the CDI + * library in its WEB-INF/lib directory. */ - @Test - public void testCDI2_ConfiguredByServer() throws Exception + @ParameterizedTest + @MethodSource("tests") + public void testCDIIncludedInWebapp(String implementation, String integration, Consumer configure) throws Exception { String jettyVersion = System.getProperty("jettyVersion"); DistributionTester distribution = DistributionTester.Builder.newInstance() @@ -108,23 +86,22 @@ public class CDITests extends AbstractDistributionTest String[] args1 = { "--create-startd", "--approve-all-licenses", - // standard entries - "--add-to-start=http,deploy,annotations", - // cdi2 specific entry (should transitively pull in what it needs, the user should not be expected to know the transitive entries) - "--add-to-start=cdi2" + "--add-to-start=http,deploy,annotations,jsp" + (integration == null ? "" : ("," + integration)) }; try (DistributionTester.Run run1 = distribution.start(args1)) { assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); assertEquals(0, run1.getExitValue()); - File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-cdi2-webapp:war:" + jettyVersion); + File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-" + implementation + "-cdi-webapp:war:" + jettyVersion); distribution.installWarFile(war, "demo"); + if (configure != null) + configure.accept(distribution); int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/demo/greetings"); diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java index 40828383857..9ac95f1c9dd 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java @@ -1,28 +1,31 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; +import java.net.URI; import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.util.FormContentProvider; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.util.Fields; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -56,7 +59,7 @@ public class DemoBaseTests extends AbstractDistributionTest try (DistributionTester.Run run1 = distribution.start(args)) { - assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS)); + assertTrue(run1.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + httpPort + "/test/jsp/dump.jsp"); @@ -88,7 +91,7 @@ public class DemoBaseTests extends AbstractDistributionTest try (DistributionTester.Run run1 = distribution.start(args)) { - assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS)); + assertTrue(run1.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response; @@ -133,13 +136,106 @@ public class DemoBaseTests extends AbstractDistributionTest try (DistributionTester.Run run1 = distribution.start(args)) { - assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS)); + assertTrue(run1.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS)); startHttpClient(); + + //test the async listener ContentResponse response = client.POST("http://localhost:" + httpPort + "/test-spec/asy/xx").send(); assertEquals(HttpStatus.OK_200, response.getStatus()); assertThat(response.getContentAsString(), containsString("PASS")); assertThat(response.getContentAsString(), not(containsString("FAIL"))); + + //test the servlet 3.1/4 features + response = client.POST("http://localhost:" + httpPort + "/test-spec/test/xx").send(); + assertThat(response.getContentAsString(), containsString("PASS")); + assertThat(response.getContentAsString(), not(containsString("FAIL"))); + + //test dynamic jsp + response = client.POST("http://localhost:" + httpPort + "/test-spec/dynamicjsp/xx").send(); + assertThat(response.getContentAsString(), containsString("Programmatically Added Jsp File")); + } + } + + @Test + public void testJPMS() throws Exception + { + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(Paths.get("demo-base")) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + int httpPort = distribution.freePort(); + int httpsPort = distribution.freePort(); + String[] args = { + "--jpms", + "jetty.http.port=" + httpPort, + "jetty.httpConfig.port=" + httpsPort, + "jetty.ssl.port=" + httpsPort + }; + try (DistributionTester.Run run = distribution.start(args)) + { + assertTrue(run.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/test/hello"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + } + } + + @Test + public void testSessionDump() throws Exception + { + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(Paths.get("demo-base")) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + int httpPort = distribution.freePort(); + int httpsPort = distribution.freePort(); + String[] args = { + "jetty.http.port=" + httpPort, + "jetty.httpConfig.port=" + httpsPort, + "jetty.ssl.port=" + httpsPort + }; + try (DistributionTester.Run run = distribution.start(args)) + { + assertTrue(run.awaitConsoleLogsFor("Started ", 10, TimeUnit.SECONDS)); + + startHttpClient(); + client.setFollowRedirects(true); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/test/session/"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + + // Submit "New Session" + Fields form = new Fields(); + form.add("Action", "New Session"); + response = client.POST("http://localhost:" + httpPort + "/test/session/") + .content(new FormContentProvider(form)) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + String content = response.getContentAsString(); + assertThat("Content", content, containsString("test: value
        ")); + assertThat("Content", content, containsString("WEBCL: {}
        ")); + + // Last Location + URI location = response.getRequest().getURI(); + + // Submit a "Set" for a new entry in the cookie + form = new Fields(); + form.add("Action", "Set"); + form.add("Name", "Zed"); + form.add("Value", "[alpha]"); + response = client.POST(location) + .content(new FormContentProvider(form)) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + content = response.getContentAsString(); + assertThat("Content", content, containsString("Zed: [alpha]
        ")); } } } diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java index 99bfbb945e0..b1225195332 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java @@ -1,46 +1,56 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; +import java.io.BufferedWriter; import java.io.File; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http2.client.HTTP2Client; import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2; +import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets; import org.eclipse.jetty.unixsocket.server.UnixSocketConnector; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnJre; import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -63,7 +73,7 @@ public class DistributionTests extends AbstractDistributionTest int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port); @@ -75,6 +85,57 @@ public class DistributionTests extends AbstractDistributionTest } } + @Test + public void testQuickStartGenerationAndRun() throws Exception + { + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + String[] args1 = { + "--create-startd", + "--approve-all-licenses", + "--add-to-start=resources,server,http,webapp,deploy,jsp,servlet,servlets,quickstart" + }; + + try (DistributionTester.Run run1 = distribution.start(args1)) + { + assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, run1.getExitValue()); + + File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion); + distribution.installWarFile(war, "test"); + + + try (DistributionTester.Run run2 = distribution.start("jetty.quickstart.mode=GENERATE")) + { + assertTrue(run2.awaitConsoleLogsFor("QuickStartGeneratorConfiguration:main: Generated", 10, TimeUnit.SECONDS)); + Path unpackedWebapp = distribution.getJettyBase().resolve("webapps").resolve("test"); + assertTrue(Files.exists(unpackedWebapp)); + Path webInf = unpackedWebapp.resolve("WEB-INF"); + assertTrue(Files.exists(webInf)); + Path quickstartWebXml = webInf.resolve("quickstart-web.xml"); + assertTrue(Files.exists(quickstartWebXml)); + assertNotEquals(0, Files.size(quickstartWebXml)); + + int port = distribution.freePort(); + + try (DistributionTester.Run run3 = distribution.start("jetty.http.port=" + port, "jetty.quickstart.mode=QUICKSTART")) + { + assertTrue(run3.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertThat(response.getContentAsString(), containsString("Hello")); + assertThat(response.getContentAsString(), not(containsString("<%"))); + } + } + } + } + @Test public void testSimpleWebAppWithJSP() throws Exception { @@ -100,7 +161,7 @@ public class DistributionTests extends AbstractDistributionTest int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp"); @@ -141,7 +202,7 @@ public class DistributionTests extends AbstractDistributionTest }; try (DistributionTester.Run run2 = distribution.start(args2)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp"); @@ -155,6 +216,18 @@ public class DistributionTests extends AbstractDistributionTest @Test @DisabledOnJre(JRE.JAVA_8) public void testSimpleWebAppWithJSPOverH2C() throws Exception + { + testSimpleWebAppWithJSPOverHTTP2(false); + } + + @Test + @DisabledOnJre(JRE.JAVA_8) + public void testSimpleWebAppWithJSPOverH2() throws Exception + { + testSimpleWebAppWithJSPOverHTTP2(true); + } + + private void testSimpleWebAppWithJSPOverHTTP2(boolean ssl) throws Exception { String jettyVersion = System.getProperty("jettyVersion"); DistributionTester distribution = DistributionTester.Builder.newInstance() @@ -164,7 +237,7 @@ public class DistributionTests extends AbstractDistributionTest String[] args1 = { "--create-startd", - "--add-to-start=http2c,jsp,deploy" + "--add-to-start=jsp,deploy," + (ssl ? "http2,test-keystore" : "http2c") }; try (DistributionTester.Run run1 = distribution.start(args1)) { @@ -175,13 +248,16 @@ public class DistributionTests extends AbstractDistributionTest distribution.installWarFile(war, "test"); int port = distribution.freePort(); - try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) + String portProp = ssl ? "jetty.ssl.port" : "jetty.http.port"; + try (DistributionTester.Run run2 = distribution.start(portProp + "=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); - HTTP2Client h2Client = new HTTP2Client(); + ClientConnector connector = new ClientConnector(); + connector.setSslContextFactory(new SslContextFactory.Client(true)); + HTTP2Client h2Client = new HTTP2Client(connector); startHttpClient(() -> new HttpClient(new HttpClientTransportOverHTTP2(h2Client))); - ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp"); + ContentResponse response = client.GET((ssl ? "https" : "http") + "://localhost:" + port + "/test/index.jsp"); assertEquals(HttpStatus.OK_200, response.getStatus()); assertThat(response.getContentAsString(), containsString("Hello")); assertThat(response.getContentAsString(), not(containsString("<%"))); @@ -229,7 +305,7 @@ public class DistributionTests extends AbstractDistributionTest try (DistributionTester.Run run2 = distribution.start("jetty.unixsocket.path=" + sockFile.toString())) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(() -> new HttpClient(new HttpClientTransportOverUnixSockets(sockFile.toString()))); ContentResponse response = client.GET("http://localhost/test/index.jsp"); @@ -272,7 +348,7 @@ public class DistributionTests extends AbstractDistributionTest int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp"); @@ -287,4 +363,94 @@ public class DistributionTests extends AbstractDistributionTest IO.delete(jettyBase.toFile()); } } + + @Test + public void testWebAppWithProxyAndJPMS() throws Exception + { + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + String[] args1 = { + "--create-startd", + "--add-to-start=http,webapp,deploy,resources" + }; + try (DistributionTester.Run run1 = distribution.start(args1)) + { + assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, run1.getExitValue()); + + Path logFile = distribution.getJettyBase().resolve("resources").resolve("jetty-logging.properties"); + try (BufferedWriter writer = Files.newBufferedWriter(logFile, StandardCharsets.UTF_8, StandardOpenOption.CREATE)) + { + writer.write("org.eclipse.jetty.LEVEL=INFO"); + } + + File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-proxy-webapp:war:" + jettyVersion); + distribution.installWarFile(war, "proxy"); + + int port = distribution.freePort(); + try (DistributionTester.Run run2 = distribution.start("--jpms", "jetty.http.port=" + port, "jetty.server.dumpAfterStart=true")) + { + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); + + startHttpClient(() -> new HttpClient(new HttpClientTransportOverHTTP(1))); + ContentResponse response = client.GET("http://localhost:" + port + "/proxy/current/"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + } + } + } + + @ParameterizedTest + @ValueSource(strings = { + "", + "--jpms", + }) + public void testSimpleWebAppWithWebsocket(String arg) throws Exception + { + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + String[] args1 = { + "--create-startd", + "--approve-all-licenses", + "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets,websocket" + }; + try (DistributionTester.Run run1 = distribution.start(args1)) + { + assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, run1.getExitValue()); + + File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-bad-websocket-webapp:war:" + jettyVersion); + distribution.installWarFile(war, "test1"); + distribution.installWarFile(war, "test2"); + + int port = distribution.freePort(); + String[] args2 = { + arg, + "jetty.http.port=" + port//, + //"jetty.server.dumpAfterStart=true" + }; + try (DistributionTester.Run run2 = distribution.start(args2)) + { + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); + assertFalse(run2.getLogs().stream().anyMatch(s -> s.contains("LinkageError"))); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + port + "/test1/index.jsp"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertThat(response.getContentAsString(), containsString("Hello")); + assertThat(response.getContentAsString(), not(containsString("<%"))); + + client.GET("http://localhost:" + port + "/test2/index.jsp"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertThat(response.getContentAsString(), containsString("Hello")); + assertThat(response.getContentAsString(), not(containsString("<%"))); + } + } + } } diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java index 86d0b2d10b0..f5542a47922 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java @@ -1,36 +1,37 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.util.IO; -import org.junit.jupiter.api.Test; - import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.util.IO; +import org.junit.jupiter.api.Test; + import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -40,7 +41,7 @@ public class DynamicListenerTests @Test public void testSimpleWebAppWithJSP() throws Exception { - Path jettyBase = Files.createTempDirectory( "jetty_base"); + Path jettyBase = Files.createTempDirectory("jetty_base"); String jettyVersion = System.getProperty("jettyVersion"); DistributionTester distribution = DistributionTester.Builder.newInstance() .jettyBase(jettyBase) @@ -58,11 +59,11 @@ public class DynamicListenerTests assertTrue(run1.awaitFor(5, TimeUnit.SECONDS)); assertEquals(0, run1.getExitValue()); - File war = distribution.resolveArtifact( "org.eclipse.jetty:test-jetty-webapp:war:" + jettyVersion); + File war = distribution.resolveArtifact("org.eclipse.jetty:test-jetty-webapp:war:" + jettyVersion); distribution.installWarFile(war, "test"); Path etc = Paths.get(jettyBase.toString(),"etc"); - if(!Files.exists(etc)) + if (!Files.exists(etc)) { Files.createDirectory(etc); } @@ -77,7 +78,7 @@ public class DynamicListenerTests int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/test/testservlet/foo"); @@ -89,7 +90,8 @@ public class DynamicListenerTests assertThat(content, containsString("requestInitialized")); assertThat(content, not(containsString("<%"))); } - } finally + } + finally { IO.delete(jettyBase.toFile()); } diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java index 09cb1ef8478..6ae594fea53 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.tests.distribution; @@ -57,7 +57,7 @@ public class OsgiAppTests extends AbstractDistributionTest int port = distribution.freePort(); try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port)) { - assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS)); startHttpClient(); ContentResponse response = client.GET("http://localhost:" + port + "/test/info"); diff --git a/tests/test-distribution/src/test/resources/cdi/demo_context.xml b/tests/test-distribution/src/test/resources/cdi/demo_context.xml deleted file mode 100644 index 1f2061332b6..00000000000 --- a/tests/test-distribution/src/test/resources/cdi/demo_context.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - /demo - /demo/ - - - -org.eclipse.jetty.util.Decorator - - - -org.eclipse.jetty.util.DecoratedObjectFactory - - - -org.eclipse.jetty.server.handler.ContextHandler. - - - -org.eclipse.jetty.server.handler.ContextHandler - - - -org.eclipse.jetty.servlet.ServletContextHandler - - - diff --git a/tests/test-distribution/src/test/resources/jetty-logging.properties b/tests/test-distribution/src/test/resources/jetty-logging.properties index d96a696f82e..56cc73e5d68 100644 --- a/tests/test-distribution/src/test/resources/jetty-logging.properties +++ b/tests/test-distribution/src/test/resources/jetty-logging.properties @@ -1,2 +1,2 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG diff --git a/tests/test-distribution/src/test/resources/test-realm.xml b/tests/test-distribution/src/test/resources/test-realm.xml index 72c6de06d68..0b4cf7f7c31 100644 --- a/tests/test-distribution/src/test/resources/test-realm.xml +++ b/tests/test-distribution/src/test/resources/test-realm.xml @@ -1,24 +1,29 @@ - + - - - - - - - - - - - Test Realm - - false - - - + + + + + + + + + + + Test Realm + + + + false + + + - - demo test-realm is deployed. DO NOT USE IN PRODUCTION! - + + org.eclipse.jetty + + demo test-realm is deployed. DO NOT USE IN PRODUCTION! + + diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index 84d9d7de5b9..034b1425cd8 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -41,6 +41,11 @@ + + org.slf4j + slf4j-api + test + org.eclipse.jetty jetty-alpn-java-client @@ -101,10 +106,14 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper - test diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java index dd9dace0e69..fc78688dc2b 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java index b4a8011e33e..c1bd4f8b925 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -39,7 +39,6 @@ import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; import javax.servlet.ReadListener; -import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; @@ -63,6 +62,7 @@ import org.eclipse.jetty.http2.HTTP2Session; import org.eclipse.jetty.http2.api.Session; import org.eclipse.jetty.http2.client.http.HttpConnectionOverHTTP2; import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpInput; @@ -70,10 +70,8 @@ import org.eclipse.jetty.server.HttpInput.Content; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; -import org.eclipse.jetty.unixsocket.server.UnixSocketConnector; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.FuturePromise; -import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Tag; @@ -82,6 +80,8 @@ import org.junit.jupiter.params.provider.ArgumentsSource; import static java.nio.ByteBuffer.wrap; import static org.eclipse.jetty.http.client.Transport.FCGI; +import static org.eclipse.jetty.http.client.Transport.H2C; +import static org.eclipse.jetty.http.client.Transport.HTTP; import static org.eclipse.jetty.util.BufferUtil.toArray; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -138,7 +138,7 @@ public class AsyncIOServletTest extends AbstractTest { - @Override - public void onContent(Response response, ByteBuffer content) - { - // System.err.println("Content: "+BufferUtil.toDetailString(content)); - } - }) - .onResponseFailure(new Response.FailureListener() - { - @Override - public void onFailure(Response response, Throwable failure) - { - clientLatch.countDown(); - } + // System.err.println("Content: "+BufferUtil.toDetailString(content)); }) + .onResponseFailure((response, failure) -> clientLatch.countDown()) .send(result -> { failed.set(result.isFailed()); @@ -581,7 +573,7 @@ public class AsyncIOServletTest extends AbstractTest @@ -852,7 +844,7 @@ public class AsyncIOServletTest extends AbstractTest responseLatch.countDown()); + .onResponseSuccess(response -> + { + if (transport == HTTP) + responseLatch.countDown(); + }) + .onResponseFailure((response, failure) -> + { + if (transport == H2C) + responseLatch.countDown(); + }); - if (scenario.connector instanceof UnixSocketConnector) - { - // skip rest of this test for unix socket - return; - } - - Destination destination = scenario.client.getDestination(scenario.getScheme(), - "localhost", - scenario.getNetworkConnectorLocalPortInt().get()); + Destination destination = scenario.client.resolveDestination(request); FuturePromise promise = new FuturePromise<>(); destination.newConnection(promise); org.eclipse.jetty.client.api.Connection connection = promise.get(5, TimeUnit.SECONDS); CountDownLatch clientLatch = new CountDownLatch(1); connection.send(request, result -> { - assertThat(result.getResponse().getStatus(), Matchers.equalTo(responseCode)); + switch (transport) + { + case HTTP: + assertThat(result.getResponse().getStatus(), Matchers.equalTo(responseCode)); + break; + case H2C: + // HTTP/2 does not attempt to write a response back, just a RST_STREAM. + assertTrue(result.isFailed()); + break; + default: + fail("Unhandled transport: " + transport); + } clientLatch.countDown(); }); @@ -1148,11 +1153,9 @@ public class AsyncIOServletTest extends AbstractTest @@ -1521,7 +1524,7 @@ public class AsyncIOServletTest extends AbstractTest return new HttpClientTransportOverHTTP(clientConnector) { @Override - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) throws IOException { - return new HttpConnectionOverHTTP(endPoint, destination, promise) + return new HttpConnectionOverHTTP(endPoint, context) { @Override protected HttpChannelOverHTTP newHttpChannel() @@ -210,9 +211,9 @@ public class HttpChannelAssociationTest extends AbstractTest return new HttpClientTransportOverUnixSockets(scenario.sockFile.toString()) { @Override - protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise promise) + public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map context) { - return new HttpConnectionOverHTTP(endPoint, destination, promise) + return new HttpConnectionOverHTTP(endPoint, context) { @Override protected HttpChannelOverHTTP newHttpChannel() diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientConnectTimeoutTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientConnectTimeoutTest.java index d9f8c7c51f8..ebbde01e123 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientConnectTimeoutTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientConnectTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java index 9cedb938ee2..3da4befe4c0 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -76,19 +76,19 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithOneContent_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithOneContentRespond100Continue(Transport transport) throws Exception { - test_Expect100Continue_Respond100Continue(transport, "data1".getBytes(StandardCharsets.UTF_8)); + testExpect100ContinueRespond100Continue(transport, "data1".getBytes(StandardCharsets.UTF_8)); } @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithMultipleContents_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithMultipleContentsRespond100Continue(Transport transport) throws Exception { - test_Expect100Continue_Respond100Continue(transport, "data1".getBytes(StandardCharsets.UTF_8), "data2".getBytes(StandardCharsets.UTF_8), "data3".getBytes(StandardCharsets.UTF_8)); + testExpect100ContinueRespond100Continue(transport, "data1".getBytes(StandardCharsets.UTF_8), "data2".getBytes(StandardCharsets.UTF_8), "data3".getBytes(StandardCharsets.UTF_8)); } - private void test_Expect100Continue_Respond100Continue(Transport transport, byte[]... contents) throws Exception + private void testExpect100ContinueRespond100Continue(Transport transport, byte[]... contents) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -124,7 +124,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithChunkedContent_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithChunkedContentRespond100Continue(Transport transport) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -173,19 +173,19 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithContent_Respond417ExpectationFailed(Transport transport) throws Exception + public void testExpect100ContinueWithContentRespond417ExpectationFailed(Transport transport) throws Exception { - test_Expect100Continue_WithContent_RespondError(transport, 417); + testExpect100ContinueWithContentRespondError(transport, 417); } @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithContent_Respond413RequestEntityTooLarge(Transport transport) throws Exception + public void testExpect100ContinueWithContentRespond413RequestEntityTooLarge(Transport transport) throws Exception { - test_Expect100Continue_WithContent_RespondError(transport, 413); + testExpect100ContinueWithContentRespondError(transport, 413); } - private void test_Expect100Continue_WithContent_RespondError(Transport transport, final int error) throws Exception + private void testExpect100ContinueWithContentRespondError(Transport transport, final int error) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -225,7 +225,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithContent_WithRedirect(Transport transport) throws Exception + public void testExpect100ContinueWithContentWithRedirect(Transport transport) throws Exception { init(transport); final String data = "success"; @@ -273,7 +273,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Redirect_WithExpect100Continue_WithContent(Transport transport) throws Exception + public void testRedirectWithExpect100ContinueWithContent(Transport transport) throws Exception { init(transport); // A request with Expect: 100-Continue cannot receive non-final responses like 3xx @@ -326,7 +326,7 @@ public class HttpClientContinueTest extends AbstractTest @ArgumentsSource(TransportProvider.class) @Tag("Slow") @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_Expect100Continue_WithContent_WithResponseFailure_Before100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithContentWithResponseFailureBefore100Continue(Transport transport) throws Exception { init(transport); final long idleTimeout = 1000; @@ -373,7 +373,7 @@ public class HttpClientContinueTest extends AbstractTest @ArgumentsSource(TransportProvider.class) @Tag("Slow") @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_Expect100Continue_WithContent_WithResponseFailure_After100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithContentWithResponseFailureAfter100Continue(Transport transport) throws Exception { init(transport); final long idleTimeout = 1000; @@ -419,7 +419,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithContent_WithResponseFailure_During100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithContentWithResponseFailureDuring100Continue(Transport transport) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -481,7 +481,7 @@ public class HttpClientContinueTest extends AbstractTest @ArgumentsSource(TransportProvider.class) @Tag("Slow") @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_Expect100Continue_WithDeferredContent_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithDeferredContentRespond100Continue(Transport transport) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -532,7 +532,7 @@ public class HttpClientContinueTest extends AbstractTest @ArgumentsSource(TransportProvider.class) @Tag("Slow") @DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review - public void test_Expect100Continue_WithInitialAndDeferredContent_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithInitialAndDeferredContentRespond100Continue(Transport transport) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -577,7 +577,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithConcurrentDeferredContent_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithConcurrentDeferredContentRespond100Continue(Transport transport) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -618,7 +618,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithInitialAndConcurrentDeferredContent_Respond100Continue(Transport transport) throws Exception + public void testExpect100ContinueWithInitialAndConcurrentDeferredContentRespond100Continue(Transport transport) throws Exception { init(transport); scenario.start(new AbstractHandler() @@ -677,7 +677,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_Expect100Continue_WithTwoResponsesInOneRead(Transport transport) throws Exception + public void testExpect100ContinueWithTwoResponsesInOneRead(Transport transport) throws Exception { init(transport); assumeTrue(scenario.transport.isHttp1Based()); @@ -737,13 +737,13 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_NoExpect_Respond100Continue(Transport transport) throws Exception + public void testNoExpectRespond100Continue(Transport transport) throws Exception { init(transport); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { jettyRequest.setHandled(true); // Force a 100 Continue response. @@ -766,7 +766,7 @@ public class HttpClientContinueTest extends AbstractTest @ParameterizedTest @ArgumentsSource(TransportProvider.class) - public void test_NoExpect_100Continue_ThenRedirect_Then100Continue_ThenResponse(Transport transport) throws Exception + public void testNoExpect100ContinueThenRedirectThen100ContinueThenResponse(Transport transport) throws Exception { init(transport); assumeTrue(scenario.transport.isHttp1Based()); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientDemandTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientDemandTest.java new file mode 100644 index 00000000000..ade1356d760 --- /dev/null +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientDemandTest.java @@ -0,0 +1,532 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http.client; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.nio.ByteBuffer; +import java.util.Queue; +import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.LongConsumer; +import java.util.zip.GZIPOutputStream; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.eclipse.jetty.client.util.BufferingResponseListener; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.Callback; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class HttpClientDemandTest extends AbstractTest +{ + @Override + public void init(Transport transport) throws IOException + { + setScenario(new TransportScenario(transport)); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testDemandInTwoChunks(Transport transport) throws Exception + { + init(transport); + + // Tests a special case where the first chunk is automatically + // delivered, and the second chunk is explicitly demanded and + // completes the response content. + CountDownLatch contentLatch = new CountDownLatch(1); + scenario.start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + try + { + response.setContentLength(2); + ServletOutputStream out = response.getOutputStream(); + out.write('A'); + out.flush(); + contentLatch.await(); + out.write('B'); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + }); + + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .send(new BufferingResponseListener() + { + private final AtomicInteger chunks = new AtomicInteger(); + + @Override + public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback) + { + callback.succeeded(); + if (chunks.incrementAndGet() == 1) + contentLatch.countDown(); + // Need to demand also after the second + // chunk to allow the parser to proceed + // and complete the response. + demand.accept(1); + } + + @Override + public void onComplete(Result result) + { + assertTrue(result.isSucceeded()); + Response response = result.getResponse(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + resultLatch.countDown(); + } + }); + + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testDemand(Transport transport) throws Exception + { + init(transport); + + int bufferSize = 512; + byte[] content = new byte[10 * bufferSize]; + new Random().nextBytes(content); + scenario.startServer(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentLength(content.length); + response.getOutputStream().write(content); + } + }); + scenario.startClient(client -> + { + // A small buffer size so the response content is read in multiple buffers. + client.setByteBufferPool(new MappedByteBufferPool(bufferSize)); + client.setResponseBufferSize(bufferSize); + }); + + Queue demandQueue = new ConcurrentLinkedQueue<>(); + Queue contentQueue = new ConcurrentLinkedQueue<>(); + Queue callbackQueue = new ConcurrentLinkedQueue<>(); + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .send(new BufferingResponseListener() + { + @Override + public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback) + { + // Don't demand and don't succeed callbacks. + demandQueue.offer(demand); + contentQueue.offer(content); + callbackQueue.offer(callback); + } + + @Override + public void onComplete(Result result) + { + assertTrue(result.isSucceeded()); + Response response = result.getResponse(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + resultLatch.countDown(); + } + }); + + // Wait for the client to receive data from the server. + // Wait a bit more to be sure it only receives 1 buffer. + Thread.sleep(1000); + assertEquals(1, demandQueue.size()); + assertEquals(1, contentQueue.size()); + assertEquals(1, callbackQueue.size()); + + // Demand more buffers. + int count = 2; + LongConsumer demand = demandQueue.poll(); + assertNotNull(demand); + demand.accept(count); + // The client should have received just `count` more buffers. + Thread.sleep(1000); + assertEquals(count, demandQueue.size()); + assertEquals(1 + count, contentQueue.size()); + assertEquals(1 + count, callbackQueue.size()); + + // Demand all the rest. + demand = demandQueue.poll(); + assertNotNull(demand); + demand.accept(Long.MAX_VALUE); + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + + byte[] received = new byte[content.length]; + AtomicInteger offset = new AtomicInteger(); + contentQueue.forEach(buffer -> + { + int length = buffer.remaining(); + buffer.get(received, offset.getAndAdd(length), length); + }); + assertArrayEquals(content, received); + + callbackQueue.forEach(Callback::succeeded); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testContentWhileStalling(Transport transport) throws Exception + { + init(transport); + + CountDownLatch serverContentLatch = new CountDownLatch(1); + scenario.start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + try + { + response.setContentLength(2); + ServletOutputStream out = response.getOutputStream(); + out.write('A'); + out.flush(); + serverContentLatch.await(); + out.write('B'); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + }); + + long delay = 1000; + AtomicReference demandRef = new AtomicReference<>(); + CountDownLatch clientContentLatch = new CountDownLatch(2); + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .onResponseContentDemanded((response, demand, content, callback) -> + { + try + { + if (demandRef.getAndSet(demand) == null) + { + // Produce more content just before stalling. + serverContentLatch.countDown(); + // Wait for the content to arrive to the client. + Thread.sleep(delay); + } + clientContentLatch.countDown(); + // Succeed the callback but don't demand. + callback.succeeded(); + } + catch (InterruptedException x) + { + callback.failed(x); + } + }) + .timeout(5, TimeUnit.SECONDS) + .send(result -> + { + assertFalse(result.isFailed(), String.valueOf(result.getFailure())); + Response response = result.getResponse(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + resultLatch.countDown(); + }); + + // We did not demand, so we only expect one chunk of content. + assertFalse(clientContentLatch.await(2 * delay, TimeUnit.MILLISECONDS)); + assertEquals(1, clientContentLatch.getCount()); + + // Now demand, we should be notified of the second chunk. + demandRef.get().accept(1); + + assertTrue(clientContentLatch.await(5, TimeUnit.SECONDS)); + demandRef.get().accept(1); + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testTwoListenersWithDifferentDemand(Transport transport) throws Exception + { + init(transport); + + int bufferSize = 512; + byte[] content = new byte[10 * bufferSize]; + new Random().nextBytes(content); + scenario.startServer(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentLength(content.length); + response.getOutputStream().write(content); + } + }); + scenario.startClient(client -> + { + client.setByteBufferPool(new MappedByteBufferPool(bufferSize)); + client.setResponseBufferSize(bufferSize); + }); + + AtomicInteger chunks = new AtomicInteger(); + Response.DemandedContentListener listener1 = (response, demand, content1, callback) -> + { + callback.succeeded(); + // The first time, demand infinitely. + if (chunks.incrementAndGet() == 1) + demand.accept(Long.MAX_VALUE); + }; + BlockingQueue contentQueue = new LinkedBlockingQueue<>(); + AtomicReference demandRef = new AtomicReference<>(); + AtomicReference demandLatch = new AtomicReference<>(new CountDownLatch(1)); + Response.DemandedContentListener listener2 = (response, demand, content12, callback) -> + { + contentQueue.offer(content12); + demandRef.set(demand); + demandLatch.get().countDown(); + }; + + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .onResponseContentDemanded(listener1) + .onResponseContentDemanded(listener2) + .send(result -> + { + assertFalse(result.isFailed(), String.valueOf(result.getFailure())); + Response response = result.getResponse(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + resultLatch.countDown(); + }); + + assertTrue(demandLatch.get().await(5, TimeUnit.SECONDS)); + LongConsumer demand = demandRef.get(); + assertNotNull(demand); + assertEquals(1, contentQueue.size()); + assertNotNull(contentQueue.poll()); + + // Must not get additional content because listener2 did not demand. + assertNull(contentQueue.poll(1, TimeUnit.SECONDS)); + + // Now demand, we should get content in both listeners. + demandLatch.set(new CountDownLatch(1)); + demand.accept(1); + + assertNotNull(contentQueue.poll(5, TimeUnit.SECONDS)); + assertEquals(2, chunks.get()); + + // Demand the rest and verify the result. + assertTrue(demandLatch.get().await(5, TimeUnit.SECONDS)); + demand = demandRef.get(); + assertNotNull(demand); + demand.accept(Long.MAX_VALUE); + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testGZippedResponseContentWithAsyncDemand(Transport transport) throws Exception + { + init(transport); + + int chunks = 64; + byte[] content = new byte[chunks * 1024]; + new Random().nextBytes(content); + + scenario.start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + try (GZIPOutputStream gzip = new GZIPOutputStream(response.getOutputStream())) + { + response.setHeader(HttpHeader.CONTENT_ENCODING.asString(), "gzip"); + for (int i = 0; i < chunks; ++i) + { + Thread.sleep(10); + gzip.write(content, i * 1024, 1024); + } + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + }); + + byte[] bytes = new byte[content.length]; + ByteBuffer received = ByteBuffer.wrap(bytes); + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .onResponseContentDemanded((response, demand, buffer, callback) -> + { + received.put(buffer); + callback.succeeded(); + new Thread(() -> demand.accept(1)).start(); + }) + .send(result -> + { + assertTrue(result.isSucceeded()); + assertEquals(HttpStatus.OK_200, result.getResponse().getStatus()); + resultLatch.countDown(); + }); + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + assertArrayEquals(content, bytes); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testDelayedBeforeContentDemand(Transport transport) throws Exception + { + init(transport); + + byte[] content = new byte[1024]; + new Random().nextBytes(content); + scenario.start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + response.setContentLength(content.length); + response.getOutputStream().write(content); + } + }); + + byte[] bytes = new byte[content.length]; + ByteBuffer received = ByteBuffer.wrap(bytes); + AtomicReference beforeContentDemandRef = new AtomicReference<>(); + CountDownLatch beforeContentLatch = new CountDownLatch(1); + CountDownLatch contentLatch = new CountDownLatch(1); + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .onResponseContentDemanded(new Response.DemandedContentListener() + { + @Override + public void onBeforeContent(Response response, LongConsumer demand) + { + // Do not demand now. + beforeContentDemandRef.set(demand); + beforeContentLatch.countDown(); + } + + @Override + public void onContent(Response response, LongConsumer demand, ByteBuffer buffer, Callback callback) + { + contentLatch.countDown(); + received.put(buffer); + callback.succeeded(); + demand.accept(1); + } + }) + .send(result -> + { + assertTrue(result.isSucceeded()); + assertEquals(HttpStatus.OK_200, result.getResponse().getStatus()); + resultLatch.countDown(); + }); + + assertTrue(beforeContentLatch.await(5, TimeUnit.SECONDS)); + LongConsumer demand = beforeContentDemandRef.get(); + + // Content must not be notified until we demand. + assertFalse(contentLatch.await(1, TimeUnit.SECONDS)); + + demand.accept(1); + + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + assertArrayEquals(content, bytes); + } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testDelayedBeforeContentDemandWithNoResponseContent(Transport transport) throws Exception + { + init(transport); + + scenario.start(new EmptyServerHandler()); + + AtomicReference beforeContentDemandRef = new AtomicReference<>(); + CountDownLatch beforeContentLatch = new CountDownLatch(1); + CountDownLatch contentLatch = new CountDownLatch(1); + CountDownLatch resultLatch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .onResponseContentDemanded(new Response.DemandedContentListener() + { + @Override + public void onBeforeContent(Response response, LongConsumer demand) + { + // Do not demand now. + beforeContentDemandRef.set(demand); + beforeContentLatch.countDown(); + } + + @Override + public void onContent(Response response, LongConsumer demand, ByteBuffer buffer, Callback callback) + { + contentLatch.countDown(); + callback.succeeded(); + demand.accept(1); + } + }) + .send(result -> + { + assertTrue(result.isSucceeded()); + assertEquals(HttpStatus.OK_200, result.getResponse().getStatus()); + resultLatch.countDown(); + }); + + assertTrue(beforeContentLatch.await(5, TimeUnit.SECONDS)); + LongConsumer demand = beforeContentDemandRef.get(); + + // Content must not be notified until we demand. + assertFalse(contentLatch.await(1, TimeUnit.SECONDS)); + + demand.accept(1); + + // Content must not be notified as there is no content. + assertFalse(contentLatch.await(1, TimeUnit.SECONDS)); + + assertTrue(resultLatch.await(5, TimeUnit.SECONDS)); + } +} diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientIdleTimeoutTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientIdleTimeoutTest.java index b26d0464b19..c1544a1534d 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientIdleTimeoutTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientIdleTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java index b127e5b7aef..8524afc7ffc 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -58,20 +58,20 @@ import org.eclipse.jetty.unixsocket.server.UnixSocketConnector; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.LeakDetector; import org.eclipse.jetty.util.ProcessorUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.Scheduler; import org.hamcrest.Matchers; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpClientLoadTest extends AbstractTest { - private final Logger logger = Log.getLogger(HttpClientLoadTest.class); + private final Logger logger = LoggerFactory.getLogger(HttpClientLoadTest.class); private final AtomicLong requestCount = new AtomicLong(); private final AtomicLong connectionLeaks = new AtomicLong(); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java index 51ec665f2a1..ade011eb6fa 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -43,7 +43,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -56,6 +58,7 @@ import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.client.util.InputStreamResponseListener; import org.eclipse.jetty.client.util.OutputStreamContentProvider; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; @@ -497,10 +500,10 @@ public class HttpClientStreamTest extends AbstractTest public void testInputStreamContentProviderThrowingWhileReading(Transport transport) throws Exception { init(transport); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - public void doNonErrorHandle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); IO.copy(request.getInputStream(), response.getOutputStream()); @@ -988,7 +991,9 @@ public class HttpClientStreamTest extends AbstractTest public void testUploadWithOutputStreamFailureToConnect(Transport transport) throws Exception { init(transport); - scenario.start(new EmptyServerHandler()); + + long connectTimeout = 1000; + scenario.start(new EmptyServerHandler(), httpClient -> httpClient.setConnectTimeout(connectTimeout)); final byte[] data = new byte[512]; final CountDownLatch latch = new CountDownLatch(1); @@ -1013,7 +1018,7 @@ public class HttpClientStreamTest extends AbstractTest } }); - assertTrue(latch.await(5, TimeUnit.SECONDS)); + assertTrue(latch.await(2 * connectTimeout, TimeUnit.SECONDS)); } @ParameterizedTest @@ -1070,7 +1075,9 @@ public class HttpClientStreamTest extends AbstractTest public void testUploadWithConnectFailureClosesStream(Transport transport) throws Exception { init(transport); - scenario.start(new EmptyServerHandler()); + + long connectTimeout = 1000; + scenario.start(new EmptyServerHandler(), httpClient -> httpClient.setConnectTimeout(connectTimeout)); final CountDownLatch closeLatch = new CountDownLatch(1); InputStream stream = new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8)) @@ -1097,7 +1104,7 @@ public class HttpClientStreamTest extends AbstractTest completeLatch.countDown(); }); - assertTrue(completeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(completeLatch.await(2 * connectTimeout, TimeUnit.SECONDS)); assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); } @@ -1260,4 +1267,77 @@ public class HttpClientStreamTest extends AbstractTest Result result = listener.await(5, TimeUnit.SECONDS); assertTrue(result.isSucceeded()); } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testClientDefersContentServerIdleTimeout(Transport transport) throws Exception + { + init(transport); + CountDownLatch dataLatch = new CountDownLatch(1); + CountDownLatch errorLatch = new CountDownLatch(1); + scenario.start(new HttpServlet() + { + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException + { + AsyncContext asyncContext = request.startAsync(); + asyncContext.setTimeout(0); + request.getInputStream().setReadListener(new ReadListener() + { + @Override + public void onDataAvailable() + { + dataLatch.countDown(); + } + + @Override + public void onAllDataRead() + { + dataLatch.countDown(); + } + + @Override + public void onError(Throwable t) + { + errorLatch.countDown(); + response.setStatus(HttpStatus.REQUEST_TIMEOUT_408); + asyncContext.complete(); + } + }); + } + }); + long idleTimeout = 1000; + scenario.setServerIdleTimeout(idleTimeout); + + CountDownLatch latch = new CountDownLatch(1); + byte[] bytes = "[{\"key\":\"value\"}]".getBytes(StandardCharsets.UTF_8); + OutputStreamContentProvider content = new OutputStreamContentProvider() + { + @Override + public long getLength() + { + return bytes.length; + } + }; + scenario.client.newRequest(scenario.newURI()) + .method(HttpMethod.POST) + .path(scenario.servletPath) + .content(content, "application/json;charset=UTF-8") + .onResponseSuccess(response -> + { + assertEquals(HttpStatus.REQUEST_TIMEOUT_408, response.getStatus()); + latch.countDown(); + }) + .send(null); + + // Wait for the server to idle timeout. + Thread.sleep(2 * idleTimeout); + + assertTrue(errorLatch.await(5, TimeUnit.SECONDS)); + + // Do not send the content to the server. + + assertFalse(dataLatch.await(1, TimeUnit.SECONDS)); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java index e7c1ad76fa3..35872c0da3c 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -21,6 +21,7 @@ package org.eclipse.jetty.http.client; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; +import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -35,6 +36,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.util.BytesContentProvider; import org.eclipse.jetty.client.util.FutureResponseListener; @@ -44,6 +46,7 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http2.FlowControlStrategy; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; @@ -354,7 +357,9 @@ public class HttpClientTest extends AbstractTest assertThrows(ExecutionException.class, () -> { - scenario.client.newRequest(scenario.newURI()) + // Use IP address since the certificate contains a host name. + int serverPort = ((ServerConnector)scenario.connector).getLocalPort(); + scenario.client.newRequest("https://127.0.0.1:" + serverPort) .timeout(5, TimeUnit.SECONDS) .send(); }); @@ -649,6 +654,30 @@ public class HttpClientTest extends AbstractTest assertEquals(0, response.getContent().length); } + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testOneDestinationPerUser(Transport transport) throws Exception + { + init(transport); + scenario.start(new EmptyServerHandler()); + + int runs = 4; + int users = 16; + for (int i = 0; i < runs; ++i) + { + for (int j = 0; j < users; ++j) + { + ContentResponse response = scenario.client.newRequest(scenario.newURI()) + .tag(j) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + } + } + + List destinations = scenario.client.getDestinations(); + assertEquals(users, destinations.size()); + } + private void sleep(long time) throws IOException { try diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java index a59dccd6fe3..e2044508693 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -189,14 +189,13 @@ public class HttpClientTimeoutTest extends AbstractTest long timeout = 1000; scenario.start(new TimeoutHandler(2 * timeout)); - final CountDownLatch latch = new CountDownLatch(1); - Destination destination = scenario.client.getDestination(scenario.getScheme(), "localhost", scenario.getNetworkConnectorLocalPortInt().get()); + Request request = scenario.client.newRequest(scenario.newURI()).timeout(timeout, TimeUnit.MILLISECONDS); + CountDownLatch latch = new CountDownLatch(1); + Destination destination = scenario.client.resolveDestination(request); FuturePromise futureConnection = new FuturePromise<>(); destination.newConnection(futureConnection); try (Connection connection = futureConnection.get(5, TimeUnit.SECONDS)) { - Request request = scenario.client.newRequest(scenario.newURI()) - .timeout(timeout, TimeUnit.MILLISECONDS); connection.send(request, result -> { assertTrue(result.isFailed()); @@ -217,14 +216,13 @@ public class HttpClientTimeoutTest extends AbstractTest long timeout = 1000; scenario.start(new TimeoutHandler(timeout)); - final CountDownLatch latch = new CountDownLatch(1); - Destination destination = scenario.client.getDestination(scenario.getScheme(), "localhost", scenario.getNetworkConnectorLocalPortInt().get()); + Request request = scenario.client.newRequest(scenario.newURI()).timeout(2 * timeout, TimeUnit.MILLISECONDS); + CountDownLatch latch = new CountDownLatch(1); + Destination destination = scenario.client.resolveDestination(request); FuturePromise futureConnection = new FuturePromise<>(); destination.newConnection(futureConnection); try (Connection connection = futureConnection.get(5, TimeUnit.SECONDS)) { - Request request = scenario.client.newRequest(scenario.newURI()) - .timeout(2 * timeout, TimeUnit.MILLISECONDS); connection.send(request, result -> { Response response = result.getResponse(); @@ -254,9 +252,11 @@ public class HttpClientTimeoutTest extends AbstractTest scenario.client = new HttpClient(scenario.provideClientTransport(transport, sslContextFactory)) { @Override - public ClientConnectionFactory newSslClientConnectionFactory(ClientConnectionFactory connectionFactory) + public ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory) { - return new SslClientConnectionFactory(getSslContextFactory(), getByteBufferPool(), getExecutor(), connectionFactory) + if (sslContextFactory == null) + sslContextFactory = getSslContextFactory(); + return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory) { @Override protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine) @@ -510,10 +510,9 @@ public class HttpClientTimeoutTest extends AbstractTest // Abort the test if we can connect. fail("Error: Should not have been able to connect to " + host + ":" + port); } - catch (SocketTimeoutException x) + catch (SocketTimeoutException ignored) { // Expected timeout during connect, continue the test. - return; } catch (Throwable x) { diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTransportDynamicTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTransportDynamicTest.java index e4c01700894..8649870c55a 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTransportDynamicTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTransportDynamicTest.java @@ -1,44 +1,50 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; import java.io.IOException; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Random; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; +import org.eclipse.jetty.client.AbstractConnectionPool; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpDestination; +import org.eclipse.jetty.client.HttpProxy; import org.eclipse.jetty.client.HttpRequest; -import org.eclipse.jetty.client.MultiplexHttpDestination; import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Destination; +import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; import org.eclipse.jetty.client.http.HttpClientConnectionFactory; -import org.eclipse.jetty.client.proxy.ProxyProtocolClientConnectionFactory; +import org.eclipse.jetty.client.util.BufferingResponseListener; +import org.eclipse.jetty.client.util.BytesContentProvider; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; @@ -57,13 +63,17 @@ import org.eclipse.jetty.server.ProxyConnectionFactory; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V1; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpClientTransportDynamicTest { @@ -87,6 +97,23 @@ public class HttpClientTransportDynamicTest server.setHandler(handler); } + private void startClient(HttpClientConnectionFactory.Info... infos) throws Exception + { + ClientConnector clientConnector = new ClientConnector(); + startClient(clientConnector, infos); + } + + private void startClient(ClientConnector clientConnector, HttpClientConnectionFactory.Info... infos) throws Exception + { + clientConnector.setSelectors(1); + clientConnector.setSslContextFactory(newClientSslContextFactory()); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + client = new HttpClient(new HttpClientTransportDynamic(clientConnector, infos)); + client.start(); + } + private ServerConnector h1(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); @@ -96,7 +123,7 @@ public class HttpClientTransportDynamicTest return connector; } - private ServerConnector h1_h2c(Server server) + private ServerConnector h1H2C(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); @@ -106,7 +133,7 @@ public class HttpClientTransportDynamicTest return connector; } - private ServerConnector ssl_alpn_h1(Server server) + private ServerConnector sslAlpnH1(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); @@ -118,7 +145,7 @@ public class HttpClientTransportDynamicTest return connector; } - private ServerConnector ssl_h1_h2c(Server server) + private ServerConnector sslH1H2C(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); @@ -130,7 +157,7 @@ public class HttpClientTransportDynamicTest return connector; } - private ServerConnector ssl_alpn_h1_h2(Server server) + private ServerConnector sslAlpnH1H2(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); @@ -144,7 +171,7 @@ public class HttpClientTransportDynamicTest return connector; } - private ServerConnector ssl_alpn_h2_h1(Server server) + private ServerConnector sslAlpnH2H1(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); @@ -157,7 +184,7 @@ public class HttpClientTransportDynamicTest return connector; } - private ServerConnector proxy_h1_h2c(Server server) + private ServerConnector proxyH1H2C(Server server) { HttpConfiguration httpConfiguration = new HttpConfiguration(); HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); @@ -193,7 +220,7 @@ public class HttpClientTransportDynamicTest private void configureSslContextFactory(SslContextFactory sslContextFactory) { - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); // The mandatory HTTP/2 cipher. sslContextFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); @@ -202,12 +229,11 @@ public class HttpClientTransportDynamicTest @Test public void testClearTextHTTP1() throws Exception { - startServer(this::h1_h2c, new EmptyServerHandler()); + startServer(this::h1H2C, new EmptyServerHandler()); + startClient(HttpClientConnectionFactory.HTTP11); - HttpClientConnectionFactory.Info h1c = HttpClientConnectionFactory.HTTP11; - client = new HttpClient(new HttpClientTransportDynamic(new ClientConnector(), h1c)); - client.start(); ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); } @@ -215,18 +241,14 @@ public class HttpClientTransportDynamicTest @Test public void testClearTextHTTP2() throws Exception { - startServer(this::h1_h2c, new EmptyServerHandler()); - - // TODO: why do we need HTTP2Client? we only use it for configuration, - // so the configuration can instead be moved to the CCF? + startServer(this::h1H2C, new EmptyServerHandler()); ClientConnector clientConnector = new ClientConnector(); HTTP2Client http2Client = new HTTP2Client(clientConnector); ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); - client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h2c)); - client.addBean(http2Client); - client.start(); + startClient(clientConnector, h2c); ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) // .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); } @@ -234,14 +256,14 @@ public class HttpClientTransportDynamicTest @Test public void testClearTextProtocolSelection() throws Exception { - startServer(this::h1_h2c, new EmptyServerHandler()); + startServer(this::h1H2C, new EmptyServerHandler()); testProtocolSelection(HttpScheme.HTTP); } @Test public void testEncryptedProtocolSelectionWithoutNegotiation() throws Exception { - startServer(this::ssl_h1_h2c, new EmptyServerHandler()); + startServer(this::sslH1H2C, new EmptyServerHandler()); testProtocolSelection(HttpScheme.HTTPS); } @@ -255,21 +277,21 @@ public class HttpClientTransportDynamicTest HttpClientTransportDynamic transport = new HttpClientTransportDynamic(clientConnector, h1, h2c) { @Override - public HttpDestination.Key newDestinationKey(HttpRequest request, Origin origin) + public Origin newOrigin(HttpRequest request) { // Use prior-knowledge, i.e. negotiate==false. List protocols = HttpVersion.HTTP_2 == request.getVersion() ? h2c.getProtocols() : h1.getProtocols(); - return new HttpDestination.Key(origin, new HttpDestination.Protocol(protocols, false)); + return new Origin(request.getScheme(), request.getHost(), request.getPort(), request.getTag(), new Origin.Protocol(protocols, false)); } }; client = new HttpClient(transport); - client.addBean(http2Client); client.start(); // Make a HTTP/1.1 request. ContentResponse h1cResponse = client.newRequest("localhost", connector.getLocalPort()) .scheme(scheme.asString()) .version(HttpVersion.HTTP_1_1) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h1cResponse.getStatus()); @@ -277,6 +299,7 @@ public class HttpClientTransportDynamicTest ContentResponse h2cResponse = client.newRequest("localhost", connector.getLocalPort()) .scheme(scheme.asString()) .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h2cResponse.getStatus()); @@ -285,8 +308,8 @@ public class HttpClientTransportDynamicTest assertEquals(2, destinations.size()); assertEquals(1, destinations.stream() .map(HttpDestination.class::cast) - .map(HttpDestination::getKey) - .map(HttpDestination.Key::getOrigin) + .map(HttpDestination::getOrigin) + .map(Origin::asString) .distinct() .count()); } @@ -294,20 +317,16 @@ public class HttpClientTransportDynamicTest @Test public void testEncryptedProtocolSelectionWithNegotiation() throws Exception { - startServer(this::ssl_alpn_h1_h2, new EmptyServerHandler()); - + startServer(this::sslAlpnH1H2, new EmptyServerHandler()); ClientConnector clientConnector = new ClientConnector(); - clientConnector.setSslContextFactory(newClientSslContextFactory()); - HttpClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; HTTP2Client http2Client = new HTTP2Client(clientConnector); ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); - client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h1, h2)); - client.addBean(http2Client); - client.start(); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2); // Make a request, should be HTTP/1.1 because of the order of protocols on server. ContentResponse h1cResponse = client.newRequest("localhost", connector.getLocalPort()) .scheme("https") + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h1cResponse.getStatus()); @@ -315,6 +334,7 @@ public class HttpClientTransportDynamicTest ContentResponse h2cResponse = client.newRequest("localhost", connector.getLocalPort()) .scheme("https") .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h2cResponse.getStatus()); @@ -323,8 +343,8 @@ public class HttpClientTransportDynamicTest assertEquals(2, destinations.size()); assertEquals(1, destinations.stream() .map(HttpDestination.class::cast) - .map(HttpDestination::getKey) - .map(HttpDestination.Key::getOrigin) + .map(HttpDestination::getOrigin) + .map(Origin::asString) .distinct() .count()); } @@ -332,20 +352,16 @@ public class HttpClientTransportDynamicTest @Test public void testServerOnlySpeaksEncryptedHTTP11ClientFallsBackToHTTP11() throws Exception { - startServer(this::ssl_alpn_h1, new EmptyServerHandler()); - + startServer(this::sslAlpnH1, new EmptyServerHandler()); ClientConnector clientConnector = new ClientConnector(); - clientConnector.setSslContextFactory(newClientSslContextFactory()); - HttpClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; HTTP2Client http2Client = new HTTP2Client(clientConnector); ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); - client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h2, h1)); - client.addBean(http2Client); - client.start(); + startClient(clientConnector, h2, HttpClientConnectionFactory.HTTP11); // The client prefers h2 over h1, and use of TLS and ALPN will allow the fallback to h1. ContentResponse h1cResponse = client.newRequest("localhost", connector.getLocalPort()) .scheme("https") + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h1cResponse.getStatus()); } @@ -354,19 +370,16 @@ public class HttpClientTransportDynamicTest public void testServerOnlySpeaksClearTextHTTP11ClientFailsHTTP2() throws Exception { startServer(this::h1, new EmptyServerHandler()); - ClientConnector clientConnector = new ClientConnector(); - HttpClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; HTTP2Client http2Client = new HTTP2Client(clientConnector); ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); - client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h1, h2c)); - client.addBean(http2Client); - client.start(); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); // The client forces HTTP/2, but the server cannot speak it, so the request fails. // There is no fallback to HTTP/1 because the protocol version is set explicitly. assertThrows(ExecutionException.class, () -> client.newRequest("localhost", connector.getLocalPort()) .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) .send()); } @@ -388,7 +401,7 @@ public class HttpClientTransportDynamicTest // client :1234 <-> :8888 proxy :5678 <-> server :8080 // client :2345 <-> :8888 proxy :6789 <-> server :8080 - startServer(this::proxy_h1_h2c, new EmptyServerHandler() + startServer(this::proxyH1H2C, new EmptyServerHandler() { @Override protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException @@ -397,48 +410,25 @@ public class HttpClientTransportDynamicTest response.getOutputStream().print(request.getRemotePort()); } }); - - ClientConnector clientConnector = new ClientConnector(); - clientConnector.setSslContextFactory(newClientSslContextFactory()); - ClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; - - Map mapping = new ConcurrentHashMap<>(); - client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h1) - { - @Override - public HttpDestination.Key newDestinationKey(HttpRequest request, Origin origin) - { - String kind = mapping.remove(request); - return new HttpDestination.Key(origin, new HttpDestination.Protocol(List.of("http/1.1"), false), kind); - } - - @Override - public HttpDestination newHttpDestination(HttpDestination.Key key) - { - // Here we want to wrap the destination with the PROXY - // protocol, for a specific remote client socket address. - return new MultiplexHttpDestination(client, key, factory -> new ProxyProtocolClientConnectionFactory(factory, () -> - { - String[] address = key.getKind().split(":"); - return new Origin.Address(address[0], Integer.parseInt(address[1])); - })); - } - }); - client.start(); + startClient(HttpClientConnectionFactory.HTTP11); // Simulate a proxy request to the server. HttpRequest proxyRequest1 = (HttpRequest)client.newRequest("localhost", connector.getLocalPort()); // Map the proxy request to client IP:port. int clientPort1 = ThreadLocalRandom.current().nextInt(1024, 65536); - mapping.put(proxyRequest1, "localhost:" + clientPort1); - ContentResponse proxyResponse1 = proxyRequest1.send(); + proxyRequest1.tag(new V1.Tag("localhost", clientPort1)); + ContentResponse proxyResponse1 = proxyRequest1 + .timeout(5, TimeUnit.SECONDS) + .send(); assertEquals(String.valueOf(clientPort1), proxyResponse1.getContentAsString()); // Simulate another request to the server, from a different client port. HttpRequest proxyRequest2 = (HttpRequest)client.newRequest("localhost", connector.getLocalPort()); int clientPort2 = ThreadLocalRandom.current().nextInt(1024, 65536); - mapping.put(proxyRequest2, "localhost:" + clientPort2); - ContentResponse proxyResponse2 = proxyRequest2.send(); + proxyRequest2.tag(new V1.Tag("localhost", clientPort2)); + ContentResponse proxyResponse2 = proxyRequest2 + .timeout(5, TimeUnit.SECONDS) + .send(); assertEquals(String.valueOf(clientPort2), proxyResponse2.getContentAsString()); // We must have 2 different destinations with the same origin. @@ -446,8 +436,8 @@ public class HttpClientTransportDynamicTest assertEquals(2, destinations.size()); assertEquals(1, destinations.stream() .map(HttpDestination.class::cast) - .map(HttpDestination::getKey) - .map(HttpDestination.Key::getOrigin) + .map(HttpDestination::getOrigin) + .map(Origin::asString) .distinct() .count()); } @@ -455,28 +445,25 @@ public class HttpClientTransportDynamicTest @Test public void testClearTextAndEncryptedHTTP2() throws Exception { - prepareServer(this::ssl_alpn_h2_h1, new EmptyServerHandler()); - ServerConnector clearConnector = h1_h2c(server); + prepareServer(this::sslAlpnH2H1, new EmptyServerHandler()); + ServerConnector clearConnector = h1H2C(server); server.start(); - ClientConnector clientConnector = new ClientConnector(); - clientConnector.setSslContextFactory(newClientSslContextFactory()); - HttpClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; HTTP2Client http2Client = new HTTP2Client(clientConnector); ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); - client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h2, h1, h2c)); - client.addBean(http2Client); - client.start(); + startClient(clientConnector, h2, HttpClientConnectionFactory.HTTP11, h2c); // Make a clear-text request using HTTP/1.1. ContentResponse h1cResponse = client.newRequest("localhost", clearConnector.getLocalPort()) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h1cResponse.getStatus()); // Make a clear-text request using HTTP/2. ContentResponse h2cResponse = client.newRequest("localhost", clearConnector.getLocalPort()) .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h2cResponse.getStatus()); @@ -485,6 +472,7 @@ public class HttpClientTransportDynamicTest // generate a different destination than an explicit HTTP/2 request (like below). ContentResponse h1Response = client.newRequest("localhost", connector.getLocalPort()) .scheme("https") + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h1Response.getStatus()); @@ -492,6 +480,7 @@ public class HttpClientTransportDynamicTest ContentResponse h2Response = client.newRequest("localhost", connector.getLocalPort()) .scheme("https") .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, h2Response.getStatus()); @@ -500,9 +489,251 @@ public class HttpClientTransportDynamicTest assertEquals(4, destinations.size()); assertEquals(2, destinations.stream() .map(HttpDestination.class::cast) - .map(HttpDestination::getKey) - .map(HttpDestination.Key::getOrigin) + .map(HttpDestination::getOrigin) + .map(Origin::asString) .distinct() .count()); } + + @Test + public void testHTTP11UpgradeToH2C() throws Exception + { + String content = "upgrade"; + startServer(this::h1H2C, new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/plain; charset=UTF-8"); + response.getOutputStream().print(content); + } + }); + ClientConnector clientConnector = new ClientConnector(); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); + + // Make an upgrade request from HTTP/1.1 to H2C. + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .header(HttpHeader.UPGRADE, "h2c") + .header(HttpHeader.HTTP2_SETTINGS, "") + .header(HttpHeader.CONNECTION, "Upgrade, HTTP2-Settings") + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(content, response.getContentAsString()); + // We must have 2 different destinations with the same origin. + List destinations = client.getDestinations(); + assertEquals(2, destinations.size()); + HttpDestination h1Destination = (HttpDestination)destinations.get(0); + HttpDestination h2Destination = (HttpDestination)destinations.get(1); + if (h2Destination.getOrigin().getProtocol().getProtocols().contains("http/1.1")) + { + HttpDestination swap = h1Destination; + h1Destination = h2Destination; + h2Destination = swap; + } + List protocols1 = h1Destination.getOrigin().getProtocol().getProtocols(); + assertEquals(1, protocols1.size()); + assertTrue(protocols1.contains("http/1.1")); + AbstractConnectionPool h1ConnectionPool = (AbstractConnectionPool)h1Destination.getConnectionPool(); + assertTrue(h1ConnectionPool.isEmpty()); + List protocols2 = h2Destination.getOrigin().getProtocol().getProtocols(); + assertEquals(1, protocols2.size()); + assertTrue(protocols2.contains("h2c")); + AbstractConnectionPool h2ConnectionPool = (AbstractConnectionPool)h2Destination.getConnectionPool(); + assertEquals(1, h2ConnectionPool.getConnectionCount()); + + // Make a normal HTTP/2 request. + response = client.newRequest("localhost", connector.getLocalPort()) + .version(HttpVersion.HTTP_2) + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(content, response.getContentAsString()); + // We still have 2 destinations. + assertEquals(2, client.getDestinations().size()); + // We still have 1 HTTP/2 connection. + assertEquals(1, h2ConnectionPool.getConnectionCount()); + + // Make a normal HTTP/1.1 request. + response = client.newRequest("localhost", connector.getLocalPort()) + .version(HttpVersion.HTTP_1_1) + .timeout(5, TimeUnit.SECONDS) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(content, response.getContentAsString()); + // We still have 2 destinations. + assertEquals(2, client.getDestinations().size()); + } + + @Test + public void testHTTP11UpgradeToH2CWithForwardProxy() throws Exception + { + String content = "upgrade"; + startServer(this::h1H2C, new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/plain; charset=UTF-8"); + response.getOutputStream().print(content); + } + }); + ClientConnector clientConnector = new ClientConnector(); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); + + int proxyPort = connector.getLocalPort(); + // The proxy speaks both http/1.1 and h2c. + Origin.Protocol proxyProtocol = new Origin.Protocol(List.of("http/1.1", "h2c"), false); + client.getProxyConfiguration().getProxies().add(new HttpProxy(new Origin.Address("localhost", proxyPort), false, proxyProtocol)); + + // Make an upgrade request from HTTP/1.1 to H2C. + int serverPort = proxyPort + 1; // Any port will do. + ContentResponse response = client.newRequest("localhost", serverPort) + .header(HttpHeader.UPGRADE, "h2c") + .header(HttpHeader.HTTP2_SETTINGS, "") + .header(HttpHeader.CONNECTION, "Upgrade, HTTP2-Settings") + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(content, response.getContentAsString()); + // Verify that we upgraded. + assertEquals(2, client.getDestinations().size()); + } + + @Test + public void testHTTP11UpgradeToH2COverTLS() throws Exception + { + String content = "upgrade"; + startServer(this::sslH1H2C, new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/plain; charset=UTF-8"); + response.getOutputStream().print(content); + } + }); + ClientConnector clientConnector = new ClientConnector(); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); + + // Make an upgrade request from HTTP/1.1 to H2C. + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .scheme(HttpScheme.HTTPS.asString()) + .header(HttpHeader.UPGRADE, "h2c") + .header(HttpHeader.HTTP2_SETTINGS, "") + .header(HttpHeader.CONNECTION, "Upgrade, HTTP2-Settings") + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertEquals(content, response.getContentAsString()); + // Verify that we upgraded. + assertEquals(2, client.getDestinations().size()); + } + + @Test + public void testHTTP11UpgradeToH2CWithRequestContentDoesNotUpgrade() throws Exception + { + startServer(this::h1H2C, new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + IO.copy(request.getInputStream(), response.getOutputStream()); + } + }); + ClientConnector clientConnector = new ClientConnector(); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); + + // Make a POST upgrade request from HTTP/1.1 to H2C. + // We don't support upgrades with request content because + // the application would need to read the request content in + // HTTP/1.1 format but write the response in HTTP/2 format. + byte[] bytes = new byte[1024 * 1024]; + new Random().nextBytes(bytes); + CountDownLatch latch = new CountDownLatch(1); + client.newRequest("localhost", connector.getLocalPort()) + .method(HttpMethod.POST) + .header(HttpHeader.UPGRADE, "h2c") + .header(HttpHeader.HTTP2_SETTINGS, "") + .header(HttpHeader.CONNECTION, "Upgrade, HTTP2-Settings") + .content(new BytesContentProvider(bytes)) + .timeout(5, TimeUnit.SECONDS) + .send(new BufferingResponseListener(bytes.length) + { + @Override + public void onComplete(Result result) + { + assertTrue(result.isSucceeded()); + assertArrayEquals(bytes, getContent()); + latch.countDown(); + } + }); + + assertTrue(latch.await(15, TimeUnit.SECONDS)); + + // Check that we did not upgrade. + assertEquals(1, client.getDestinations().size()); + } + + @Test + public void testHTTP11UpgradeToH2CFailedNoHTTP2Settings() throws Exception + { + startServer(this::h1H2C, new EmptyServerHandler()); + ClientConnector clientConnector = new ClientConnector(); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); + + // The upgrade request is missing the required HTTP2-Settings header. + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .header(HttpHeader.UPGRADE, "h2c") + .header(HttpHeader.CONNECTION, "Upgrade") + .timeout(5, TimeUnit.SECONDS) + .send(); + + assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus()); + } + + @Test + public void testHTTP11UpgradeToH2CFailedServerClose() throws Exception + { + startServer(this::h1H2C, new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + jettyRequest.getHttpChannel().getEndPoint().getConnection().close(); + } + }); + ClientConnector clientConnector = new ClientConnector(); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + startClient(clientConnector, HttpClientConnectionFactory.HTTP11, h2c); + + // Make an upgrade request from HTTP/1.1 to H2C. + CountDownLatch latch = new CountDownLatch(1); + client.newRequest("localhost", connector.getLocalPort()) + .header(HttpHeader.UPGRADE, "h2c") + .header(HttpHeader.HTTP2_SETTINGS, "") + .header(HttpHeader.CONNECTION, "Upgrade, HTTP2-Settings") + .send(result -> + { + if (result.isFailed()) + latch.countDown(); + }); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpTrailersTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpTrailersTest.java index fff8c3af90e..bd4bfca10ad 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpTrailersTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpTrailersTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -23,7 +23,9 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Random; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import javax.servlet.ServletInputStream; @@ -41,7 +43,6 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.server.handler.AbstractHandler; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -51,6 +52,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public class HttpTrailersTest extends AbstractTest { @@ -81,13 +83,11 @@ public class HttpTrailersTest extends AbstractTest { String trailerName = "Trailer"; String trailerValue = "value"; - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new EmptyServerHandler() { @Override - protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { - jettyRequest.setHandled(true); - // Read the content first. ServletInputStream input = jettyRequest.getInputStream(); while (true) @@ -120,13 +120,11 @@ public class HttpTrailersTest extends AbstractTest public void testEmptyRequestTrailers(Transport transport) throws Exception { init(transport); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new EmptyServerHandler() { @Override - protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { - jettyRequest.setHandled(true); - // Read the content first. ServletInputStream input = jettyRequest.getInputStream(); while (true) @@ -167,21 +165,22 @@ public class HttpTrailersTest extends AbstractTest private void testResponseTrailers(byte[] content) throws Exception { + AtomicBoolean once = new AtomicBoolean(); String trailerName = "Trailer"; String trailerValue = "value"; - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new EmptyServerHandler() { @Override - protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { - jettyRequest.setHandled(true); + Response jettyResponse = jettyRequest.getResponse(); - HttpFields trailers = new HttpFields(); - trailers.put(trailerName, trailerValue); - - Response jettyResponse = (Response)response; - jettyResponse.setTrailerFields(() -> - trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue))); + if (once.compareAndSet(false, true)) + { + HttpFields trailers = new HttpFields(); + trailers.put(trailerName, trailerValue); + jettyResponse.setTrailers(() -> trailers); + } if (content != null) response.getOutputStream().write(content); @@ -209,6 +208,26 @@ public class HttpTrailersTest extends AbstractTest .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); assertNull(failure.get()); + + // Subsequent requests should not have trailers. + response = scenario.client.newRequest(scenario.newURI()) + .onResponseSuccess(r -> + { + try + { + HttpResponse httpResponse = (HttpResponse)r; + assertNull(httpResponse.getTrailers()); + failure.set(null); + } + catch (Throwable x) + { + failure.set(x); + } + }) + .timeout(5, TimeUnit.SECONDS) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertNull(failure.get()); } @ParameterizedTest @@ -216,17 +235,13 @@ public class HttpTrailersTest extends AbstractTest public void testEmptyResponseTrailers(Transport transport) throws Exception { init(transport); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new EmptyServerHandler() { @Override - protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) { - jettyRequest.setHandled(true); - HttpFields trailers = new HttpFields(); - - Response jettyResponse = (Response)response; - jettyResponse.setTrailerFields(() -> + response.setTrailerFields(() -> trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue))); } }); @@ -262,18 +277,15 @@ public class HttpTrailersTest extends AbstractTest String trailerName = "Trailer"; String trailerValue = "value"; init(transport); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new EmptyServerHandler() { @Override - protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { - jettyRequest.setHandled(true); - HttpFields trailers = new HttpFields(); trailers.put(trailerName, trailerValue); - Response jettyResponse = (Response)response; - jettyResponse.setTrailerFields(() -> + response.setTrailerFields(() -> trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue))); // Write a large content @@ -309,4 +321,46 @@ public class HttpTrailersTest extends AbstractTest assertNotNull(trailers); assertEquals(trailerValue, trailers.get(trailerName)); } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testResponseResetAlsoResetsTrailers(Transport transport) throws Exception + { + init(transport); + scenario.start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + { + Response jettyResponse = jettyRequest.getResponse(); + HttpFields trailers = new HttpFields(); + trailers.put("name", "value"); + jettyResponse.setTrailers(() -> trailers); + // Fill some other response field. + response.setHeader("name", "value"); + response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); + response.getWriter(); + + // Reset the response. + response.reset(); + // Must not throw because we have called + // getWriter() above, since we have reset(). + response.getOutputStream(); + } + }); + + CountDownLatch latch = new CountDownLatch(1); + scenario.client.newRequest(scenario.newURI()) + .timeout(5, TimeUnit.SECONDS) + .send(result -> + { + HttpResponse response = (HttpResponse)result.getResponse(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + assertNull(response.getTrailers()); + assertNull(response.getHeaders().get("name")); + latch.countDown(); + }); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ProxyWithDynamicTransportTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ProxyWithDynamicTransportTest.java new file mode 100644 index 00000000000..7dbd499b063 --- /dev/null +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ProxyWithDynamicTransportTest.java @@ -0,0 +1,582 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.http.client; + +import java.net.ConnectException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; +import org.eclipse.jetty.client.AbstractConnectionPool; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.HttpDestination; +import org.eclipse.jetty.client.HttpProxy; +import org.eclipse.jetty.client.Origin; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Destination; +import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; +import org.eclipse.jetty.client.http.HttpClientConnectionFactory; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Cipher; +import org.eclipse.jetty.http2.HTTP2Connection; +import org.eclipse.jetty.http2.api.Session; +import org.eclipse.jetty.http2.api.Stream; +import org.eclipse.jetty.http2.client.HTTP2Client; +import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2; +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.http2.hpack.AuthorityHttpField; +import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; +import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; +import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.proxy.AsyncProxyServlet; +import org.eclipse.jetty.proxy.ConnectHandler; +import org.eclipse.jetty.server.ConnectionFactory; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.SecureRequestCustomizer; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.FuturePromise; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ProxyWithDynamicTransportTest +{ + private static final Logger LOG = LoggerFactory.getLogger(ProxyWithDynamicTransportTest.class); + + private Server server; + private ServerConnector serverConnector; + private ServerConnector serverTLSConnector; + private Server proxy; + private ServerConnector proxyConnector; + private ServerConnector proxyTLSConnector; + private HTTP2Client http2Client; + private HttpClient client; + + private void start(Handler handler) throws Exception + { + startServer(handler); + startProxy(new ConnectHandler()); + startClient(); + } + + private void startServer(Handler handler) throws Exception + { + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setUseCipherSuitesOrder(true); + sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); + + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + + HttpConfiguration httpConfig = new HttpConfiguration(); + HttpConnectionFactory h1c = new HttpConnectionFactory(httpConfig); + HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfig); + serverConnector = new ServerConnector(server, 1, 1, h1c, h2c); + server.addConnector(serverConnector); + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory h1 = new HttpConnectionFactory(httpsConfig); + HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig); + ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); + alpn.setDefaultProtocol(h1.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol()); + serverTLSConnector = new ServerConnector(server, 1, 1, ssl, alpn, h2, h1, h2c); + server.addConnector(serverTLSConnector); + server.setHandler(handler); + server.start(); + LOG.info("Started server on :{} and :{}", serverConnector.getLocalPort(), serverTLSConnector.getLocalPort()); + } + + private void startProxy(ConnectHandler connectHandler) throws Exception + { + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setUseCipherSuitesOrder(true); + sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); + + QueuedThreadPool proxyThreads = new QueuedThreadPool(); + proxyThreads.setName("proxy"); + proxy = new Server(proxyThreads); + + HttpConfiguration httpConfig = new HttpConfiguration(); + ConnectionFactory h1c = new HttpConnectionFactory(httpConfig); + ConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfig); + proxyConnector = new ServerConnector(proxy, 1, 1, h1c, h2c); + proxy.addConnector(proxyConnector); + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory h1 = new HttpConnectionFactory(httpsConfig); + HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig); + ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); + alpn.setDefaultProtocol(h1.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol()); + proxyTLSConnector = new ServerConnector(proxy, 1, 1, ssl, alpn, h2, h1, h2c); + proxy.addConnector(proxyTLSConnector); + + proxy.setHandler(connectHandler); + ServletContextHandler context = new ServletContextHandler(connectHandler, "/"); + ServletHolder holder = new ServletHolder(new AsyncProxyServlet() + { + @Override + protected HttpClient newHttpClient(ClientConnector clientConnector) + { + ClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; + HTTP2Client http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); + return new HttpClient(new HttpClientTransportDynamic(clientConnector, h1, h2c, h2)); + } + }); + context.addServlet(holder, "/*"); + proxy.start(); + LOG.info("Started proxy on :{} and :{}", proxyConnector.getLocalPort(), proxyTLSConnector.getLocalPort()); + } + + private void startClient() throws Exception + { + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSelectors(1); + clientConnector.setExecutor(clientThreads); + clientConnector.setSslContextFactory(new SslContextFactory.Client(true)); + http2Client = new HTTP2Client(clientConnector); + ClientConnectionFactory.Info h1 = HttpClientConnectionFactory.HTTP11; + ClientConnectionFactory.Info h2c = new ClientConnectionFactoryOverHTTP2.H2C(http2Client); + ClientConnectionFactory.Info h2 = new ClientConnectionFactoryOverHTTP2.H2(http2Client); + client = new HttpClient(new HttpClientTransportDynamic(clientConnector, h1, h2c, h2)); + client.start(); + } + + @AfterEach + public void dispose() throws Exception + { + if (server != null) + server.stop(); + if (proxy != null) + proxy.stop(); + if (client != null) + client.stop(); + } + + private static java.util.stream.Stream testParams() + { + var h1 = List.of("http/1.1"); + var h2c = List.of("h2c"); + var h2 = List.of("h2"); + return java.util.stream.Stream.of( + // HTTP/1.1 Proxy with HTTP/1.1 Server. + Arguments.of(new Origin.Protocol(h1, false), false, HttpVersion.HTTP_1_1, false), + Arguments.of(new Origin.Protocol(h1, false), false, HttpVersion.HTTP_1_1, true), + Arguments.of(new Origin.Protocol(h1, false), true, HttpVersion.HTTP_1_1, false), + Arguments.of(new Origin.Protocol(h1, false), true, HttpVersion.HTTP_1_1, true), + // HTTP/1.1 Proxy with HTTP/2 Server. + Arguments.of(new Origin.Protocol(h1, false), false, HttpVersion.HTTP_2, false), + Arguments.of(new Origin.Protocol(h1, false), false, HttpVersion.HTTP_2, true), + Arguments.of(new Origin.Protocol(h1, false), true, HttpVersion.HTTP_2, false), + Arguments.of(new Origin.Protocol(h1, false), true, HttpVersion.HTTP_2, true), + // HTTP/2 Proxy with HTTP/1.1 Server. + Arguments.of(new Origin.Protocol(h2c, false), false, HttpVersion.HTTP_1_1, false), + Arguments.of(new Origin.Protocol(h2c, false), false, HttpVersion.HTTP_1_1, true), + Arguments.of(new Origin.Protocol(h2, false), true, HttpVersion.HTTP_1_1, false), + Arguments.of(new Origin.Protocol(h2, false), true, HttpVersion.HTTP_1_1, true), + Arguments.of(new Origin.Protocol(h2, true), true, HttpVersion.HTTP_1_1, false), + Arguments.of(new Origin.Protocol(h2, true), true, HttpVersion.HTTP_1_1, true), + // HTTP/2 Proxy with HTTP/2 Server. + Arguments.of(new Origin.Protocol(h2c, false), false, HttpVersion.HTTP_2, false), + Arguments.of(new Origin.Protocol(h2c, false), false, HttpVersion.HTTP_2, true), + Arguments.of(new Origin.Protocol(h2, false), true, HttpVersion.HTTP_2, false), + Arguments.of(new Origin.Protocol(h2, false), true, HttpVersion.HTTP_2, true), + Arguments.of(new Origin.Protocol(h2, true), true, HttpVersion.HTTP_2, false), + Arguments.of(new Origin.Protocol(h2, true), true, HttpVersion.HTTP_2, true) + ); + } + + @ParameterizedTest(name = "proxyProtocol={0}, proxySecure={1}, serverProtocol={2}, serverSecure={3}") + @MethodSource("testParams") + public void testProxy(Origin.Protocol proxyProtocol, boolean proxySecure, HttpVersion serverProtocol, boolean serverSecure) throws Exception + { + int status = HttpStatus.NO_CONTENT_204; + start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + response.setStatus(status); + } + }); + + int proxyPort = proxySecure ? proxyTLSConnector.getLocalPort() : proxyConnector.getLocalPort(); + Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort); + HttpProxy proxy = new HttpProxy(proxyAddress, proxySecure, proxyProtocol); + client.getProxyConfiguration().getProxies().add(proxy); + + String scheme = serverSecure ? "https" : "http"; + int serverPort = serverSecure ? serverTLSConnector.getLocalPort() : serverConnector.getLocalPort(); + ContentResponse response1 = client.newRequest("localhost", serverPort) + .scheme(scheme) + .version(serverProtocol) + .timeout(5, TimeUnit.SECONDS) + .send(); + assertEquals(status, response1.getStatus()); + + // Make a second request to be sure it went through the same connection. + ContentResponse response2 = client.newRequest("localhost", serverPort) + .scheme(scheme) + .version(serverProtocol) + .timeout(5, TimeUnit.SECONDS) + .send(); + assertEquals(status, response2.getStatus()); + + List destinations = client.getDestinations().stream() + .filter(d -> d.getPort() == serverPort) + .collect(Collectors.toList()); + assertEquals(1, destinations.size()); + HttpDestination destination = (HttpDestination)destinations.get(0); + AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool(); + assertEquals(1, connectionPool.getConnectionCount()); + } + + @Test + public void testHTTP2TunnelClosedByClient() throws Exception + { + start(new EmptyServerHandler()); + + int proxyPort = proxyConnector.getLocalPort(); + Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort); + HttpProxy proxy = new HttpProxy(proxyAddress, false, new Origin.Protocol(List.of("h2c"), false)); + client.getProxyConfiguration().getProxies().add(proxy); + + long idleTimeout = 1000; + http2Client.setStreamIdleTimeout(idleTimeout); + + String serverScheme = "http"; + int serverPort = serverConnector.getLocalPort(); + ContentResponse response = client.newRequest("localhost", serverPort) + .scheme(serverScheme) + .version(HttpVersion.HTTP_1_1) + .timeout(5, TimeUnit.SECONDS) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + + // Client will close the HTTP2StreamEndPoint. + Thread.sleep(2 * idleTimeout); + + List destinations = client.getDestinations().stream() + .filter(d -> d.getPort() == serverPort) + .collect(Collectors.toList()); + assertEquals(1, destinations.size()); + HttpDestination destination = (HttpDestination)destinations.get(0); + AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool(); + assertEquals(0, connectionPool.getConnectionCount()); + + List serverConnections = proxyConnector.getConnectedEndPoints().stream() + .map(EndPoint::getConnection) + .map(HTTP2Connection.class::cast) + .collect(Collectors.toList()); + assertEquals(1, serverConnections.size()); + assertTrue(serverConnections.get(0).getSession().getStreams().isEmpty()); + } + + @Test + public void testProxyDown() throws Exception + { + start(new EmptyServerHandler()); + + int proxyPort = proxyConnector.getLocalPort(); + Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort); + HttpProxy httpProxy = new HttpProxy(proxyAddress, false, new Origin.Protocol(List.of("h2c"), false)); + client.getProxyConfiguration().getProxies().add(httpProxy); + proxy.stop(); + + CountDownLatch latch = new CountDownLatch(1); + client.newRequest("localhost", serverConnector.getLocalPort()) + .version(HttpVersion.HTTP_1_1) + .timeout(5, TimeUnit.SECONDS) + .send(result -> + { + assertTrue(result.isFailed()); + assertThat(result.getFailure(), Matchers.instanceOf(ConnectException.class)); + latch.countDown(); + }); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testHTTP2TunnelHardClosedByProxy() throws Exception + { + startServer(new EmptyServerHandler()); + CountDownLatch closeLatch = new CountDownLatch(1); + startProxy(new ConnectHandler() + { + @Override + protected void handleConnect(Request jettyRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress) + { + jettyRequest.getHttpChannel().getEndPoint().close(); + closeLatch.countDown(); + } + }); + startClient(); + + int proxyPort = proxyConnector.getLocalPort(); + Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort); + HttpProxy httpProxy = new HttpProxy(proxyAddress, false, new Origin.Protocol(List.of("h2c"), false)); + client.getProxyConfiguration().getProxies().add(httpProxy); + + CountDownLatch latch = new CountDownLatch(1); + client.newRequest("localhost", serverConnector.getLocalPort()) + .version(HttpVersion.HTTP_1_1) + .timeout(5, TimeUnit.SECONDS) + .send(result -> + { + assertTrue(result.isFailed()); + assertThat(result.getFailure(), Matchers.instanceOf(ClosedChannelException.class)); + latch.countDown(); + }); + assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + + List destinations = client.getDestinations().stream() + .filter(d -> d.getPort() == proxyPort) + .collect(Collectors.toList()); + assertEquals(1, destinations.size()); + HttpDestination destination = (HttpDestination)destinations.get(0); + AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool(); + assertEquals(0, connectionPool.getConnectionCount()); + } + + @Test + public void testHTTP2TunnelResetByClient() throws Exception + { + startServer(new EmptyServerHandler()); + CountDownLatch closeLatch = new CountDownLatch(2); + startProxy(new ConnectHandler() + { + @Override + protected DownstreamConnection newDownstreamConnection(EndPoint endPoint, ConcurrentMap context) + { + return new DownstreamConnection(endPoint, getExecutor(), getByteBufferPool(), context) + { + @Override + protected void close(Throwable failure) + { + super.close(failure); + closeLatch.countDown(); + } + }; + } + + @Override + protected UpstreamConnection newUpstreamConnection(EndPoint endPoint, ConnectContext connectContext) + { + return new UpstreamConnection(endPoint, getExecutor(), getByteBufferPool(), connectContext) + { + @Override + protected void close(Throwable failure) + { + super.close(failure); + closeLatch.countDown(); + } + }; + } + }); + startClient(); + + FuturePromise sessionPromise = new FuturePromise<>(); + http2Client.connect(new InetSocketAddress("localhost", proxyConnector.getLocalPort()), new Session.Listener.Adapter(), sessionPromise); + Session session = sessionPromise.get(5, TimeUnit.SECONDS); + String serverAddress = "localhost:" + serverConnector.getLocalPort(); + MetaData.ConnectRequest connect = new MetaData.ConnectRequest(HttpScheme.HTTP, new AuthorityHttpField(serverAddress), null, new HttpFields(), null); + HeadersFrame frame = new HeadersFrame(connect, null, false); + FuturePromise streamPromise = new FuturePromise<>(); + CountDownLatch tunnelLatch = new CountDownLatch(1); + CountDownLatch responseLatch = new CountDownLatch(1); + session.newStream(frame, streamPromise, new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + if (response.getStatus() == HttpStatus.OK_200) + tunnelLatch.countDown(); + } + + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + ByteBuffer data = frame.getData(); + String response = BufferUtil.toString(data, StandardCharsets.UTF_8); + if (response.startsWith("HTTP/1.1 200")) + responseLatch.countDown(); + } + }); + Stream stream = streamPromise.get(5, TimeUnit.SECONDS); + assertTrue(tunnelLatch.await(5, TimeUnit.SECONDS)); + + // Tunnel is established, send a HTTP/1.1 request. + String h1 = "GET / HTTP/1.1\r\n" + + "Host: " + serverAddress + "\r\n" + + "\r\n"; + stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(h1.getBytes(StandardCharsets.UTF_8)), false), Callback.NOOP); + assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); + + // Now reset the stream, tunnel must be closed. + stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); + assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testHTTP2TunnelProxyStreamTimeout() throws Exception + { + startServer(new EmptyServerHandler()); + CountDownLatch closeLatch = new CountDownLatch(2); + startProxy(new ConnectHandler() + { + @Override + protected DownstreamConnection newDownstreamConnection(EndPoint endPoint, ConcurrentMap context) + { + return new DownstreamConnection(endPoint, getExecutor(), getByteBufferPool(), context) + { + @Override + protected void close(Throwable failure) + { + super.close(failure); + closeLatch.countDown(); + } + }; + } + + @Override + protected UpstreamConnection newUpstreamConnection(EndPoint endPoint, ConnectContext connectContext) + { + return new UpstreamConnection(endPoint, getExecutor(), getByteBufferPool(), connectContext) + { + @Override + protected void close(Throwable failure) + { + super.close(failure); + closeLatch.countDown(); + } + }; + } + }); + startClient(); + + long streamIdleTimeout = 1000; + ConnectionFactory h2c = proxyConnector.getConnectionFactory("h2c"); + ((HTTP2CServerConnectionFactory)h2c).setStreamIdleTimeout(streamIdleTimeout); + + FuturePromise sessionPromise = new FuturePromise<>(); + http2Client.connect(new InetSocketAddress("localhost", proxyConnector.getLocalPort()), new Session.Listener.Adapter(), sessionPromise); + Session session = sessionPromise.get(5, TimeUnit.SECONDS); + String serverAddress = "localhost:" + serverConnector.getLocalPort(); + MetaData.ConnectRequest connect = new MetaData.ConnectRequest(HttpScheme.HTTP, new AuthorityHttpField(serverAddress), null, new HttpFields(), null); + HeadersFrame frame = new HeadersFrame(connect, null, false); + FuturePromise streamPromise = new FuturePromise<>(); + CountDownLatch tunnelLatch = new CountDownLatch(1); + CountDownLatch responseLatch = new CountDownLatch(1); + CountDownLatch resetLatch = new CountDownLatch(1); + session.newStream(frame, streamPromise, new Stream.Listener.Adapter() + { + @Override + public void onHeaders(Stream stream, HeadersFrame frame) + { + MetaData.Response response = (MetaData.Response)frame.getMetaData(); + if (response.getStatus() == HttpStatus.OK_200) + tunnelLatch.countDown(); + } + + @Override + public void onData(Stream stream, DataFrame frame, Callback callback) + { + callback.succeeded(); + ByteBuffer data = frame.getData(); + String response = BufferUtil.toString(data, StandardCharsets.UTF_8); + if (response.startsWith("HTTP/1.1 200")) + responseLatch.countDown(); + } + + @Override + public void onReset(Stream stream, ResetFrame frame) + { + resetLatch.countDown(); + } + }); + Stream stream = streamPromise.get(5, TimeUnit.SECONDS); + assertTrue(tunnelLatch.await(5, TimeUnit.SECONDS)); + + // Tunnel is established, send a HTTP/1.1 request. + String h1 = "GET / HTTP/1.1\r\n" + + "Host: " + serverAddress + "\r\n" + + "\r\n"; + stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(h1.getBytes(StandardCharsets.UTF_8)), false), Callback.NOOP); + assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); + + // Wait until the proxy stream idle times out. + Thread.sleep(2 * streamIdleTimeout); + + // Client should see a RST_STREAM. + assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); + // Tunnel must be closed. + assertTrue(closeLatch.await(5, TimeUnit.SECONDS)); + } +} diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java index 9d2f0117ce7..b95a0551477 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java index 4de6145f2f7..5d45defd73b 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -44,6 +44,7 @@ import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http2.FlowControlStrategy; import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; @@ -51,7 +52,6 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -204,10 +204,10 @@ public class ServerTimeoutsTest extends AbstractTest { init(transport); CountDownLatch handlerLatch = new CountDownLatch(1); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); AsyncContext asyncContext = request.startAsync(); @@ -270,10 +270,10 @@ public class ServerTimeoutsTest extends AbstractTest Assumptions.assumeFalse(scenario.transport == UNIX_SOCKET); CountDownLatch handlerLatch = new CountDownLatch(1); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); AsyncContext asyncContext = request.startAsync(); @@ -338,10 +338,10 @@ public class ServerTimeoutsTest extends AbstractTest scenario.requestLog.clear(); scenario.httpConfig.setMinRequestDataRate(bytesPerSecond); CountDownLatch handlerLatch = new CountDownLatch(1); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - public void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { try { @@ -402,10 +402,10 @@ public class ServerTimeoutsTest extends AbstractTest int bytesPerSecond = 20; scenario.httpConfig.setMinRequestDataRate(bytesPerSecond); CountDownLatch handlerLatch = new CountDownLatch(1); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); ServletInputStream input = request.getInputStream(); @@ -481,10 +481,10 @@ public class ServerTimeoutsTest extends AbstractTest long idleTimeout = 3 * httpIdleTimeout; scenario.httpConfig.setIdleTimeout(httpIdleTimeout); CountDownLatch handlerLatch = new CountDownLatch(1); - scenario.start(new AbstractHandler.ErrorDispatchHandler() + scenario.start(new AbstractHandler() { @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); AsyncContext asyncContext = request.startAsync(); @@ -665,7 +665,7 @@ public class ServerTimeoutsTest extends AbstractTest assertTrue(clientLatch.await(15, TimeUnit.SECONDS)); } - private static class BlockingReadHandler extends AbstractHandler.ErrorDispatchHandler + private static class BlockingReadHandler extends AbstractHandler { private final CountDownLatch handlerLatch; @@ -675,7 +675,7 @@ public class ServerTimeoutsTest extends AbstractTest } @Override - protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { baseRequest.setHandled(true); ServletInputStream input = request.getInputStream(); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/Transport.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/Transport.java index 88529b871d5..b76ca98871a 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/Transport.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/Transport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java index d0258b764e6..f56af9ed9be 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java index ac0af2d80b4..da381546d1c 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.http.client; @@ -62,18 +62,18 @@ import org.eclipse.jetty.unixsocket.server.UnixSocketConnector; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.SocketAddressResolver; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.Assumptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.eclipse.jetty.http.client.Transport.UNIX_SOCKET; import static org.junit.jupiter.api.Assumptions.assumeTrue; public class TransportScenario { - private static final Logger LOG = Log.getLogger(TransportScenario.class); + private static final Logger LOG = LoggerFactory.getLogger(TransportScenario.class); protected final HttpConfiguration httpConfig = new HttpConfiguration(); protected final Transport transport; @@ -365,10 +365,8 @@ public class TransportScenario private void configureSslContextFactory(SslContextFactory sslContextFactory) { - sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); - sslContextFactory.setTrustStorePassword("storepwd"); sslContextFactory.setUseCipherSuitesOrder(true); sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); } @@ -393,7 +391,7 @@ public class TransportScenario } catch (Exception x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } try @@ -402,7 +400,7 @@ public class TransportScenario } catch (Exception x) { - LOG.ignore(x); + LOG.trace("IGNORED", x); } if (sockFile != null) @@ -413,7 +411,7 @@ public class TransportScenario } catch (IOException e) { - LOG.warn(e); + LOG.warn("Unable to delete sockFile: {}", sockFile, e); } } } diff --git a/tests/test-http-client-transport/src/test/resources/jetty-logging.properties b/tests/test-http-client-transport/src/test/resources/jetty-logging.properties index 914cac87711..2d990e2cc40 100644 --- a/tests/test-http-client-transport/src/test/resources/jetty-logging.properties +++ b/tests/test-http-client-transport/src/test/resources/jetty-logging.properties @@ -1,6 +1,8 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.client.LEVEL=DEBUG +#org.eclipse.jetty.fcgi.LEVEL=DEBUG +#org.eclipse.jetty.proxy.LEVEL=DEBUG #org.eclipse.jetty.http2.LEVEL=DEBUG org.eclipse.jetty.http2.hpack.LEVEL=INFO #org.eclipse.jetty.http2.client.LEVEL=DEBUG diff --git a/tests/test-http-client-transport/src/test/resources/keystore.jks b/tests/test-http-client-transport/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/tests/test-http-client-transport/src/test/resources/keystore.jks and /dev/null differ diff --git a/tests/test-http-client-transport/src/test/resources/keystore.p12 b/tests/test-http-client-transport/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..089e9704a7a Binary files /dev/null and b/tests/test-http-client-transport/src/test/resources/keystore.p12 differ diff --git a/tests/test-http-client-transport/src/test/resources/truststore.jks b/tests/test-http-client-transport/src/test/resources/truststore.jks deleted file mode 100644 index 839cb8c3515..00000000000 Binary files a/tests/test-http-client-transport/src/test/resources/truststore.jks and /dev/null differ diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 565cb25e1e8..e058f77776f 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -93,6 +93,10 @@ jetty-client ${project.version} + + org.slf4j + slf4j-api + org.eclipse.jetty jetty-distribution @@ -105,6 +109,11 @@ ${project.version} test + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper @@ -134,19 +143,19 @@ org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} test org.eclipse.jetty.websocket - jetty-websocket-client + websocket-jetty-client ${project.version} test org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} test @@ -170,5 +179,10 @@ ${project.version} test + + ch.qos.logback + logback-classic + 1.2.3 + diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/AnnotatedAsyncListenerTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/AnnotatedAsyncListenerTest.java index 2e4c729d01e..2c3738903ad 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/AnnotatedAsyncListenerTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/AnnotatedAsyncListenerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/CustomRequestLogTest.java similarity index 84% rename from jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java rename to tests/test-integration/src/test/java/org/eclipse/jetty/test/CustomRequestLogTest.java index b2a816e887d..008b646e4e7 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/CustomRequestLogTest.java @@ -1,22 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // -package org.eclipse.jetty.server.handler; +package org.eclipse.jetty.test; import java.io.IOException; import java.io.InputStream; @@ -26,15 +26,25 @@ import java.net.NetworkInterface; import java.net.Socket; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.Enumeration; import java.util.Locale; +import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.UserStore; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.CustomRequestLog; import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.HttpConnectionFactory; @@ -44,8 +54,12 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.DateCache; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Credential; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -88,24 +102,70 @@ public class CustomRequestLogTest TestRequestLogWriter writer = new TestRequestLogWriter(); _log = new CustomRequestLog(writer, formatString); _server.setRequestLog(_log); - _server.setHandler(new TestHandler()); + ServletContextHandler contextHandler = new ServletContextHandler(); + contextHandler.setSecurityHandler(getSecurityHandler("username", "password", "testRealm")); + contextHandler.addServlet(new ServletHolder(new TestServlet()), "/"); + _server.setHandler(contextHandler); _server.start(); String host = _serverConnector.getHost(); if (host == null) - { host = "localhost"; - } + int localPort = _serverConnector.getLocalPort(); _serverURI = new URI(String.format("http://%s:%d/", host, localPort)); } + private static SecurityHandler getSecurityHandler(String username, String password, String realm) + { + HashLoginService loginService = new HashLoginService(); + UserStore userStore = new UserStore(); + userStore.addUser(username, Credential.getCredential(password), new String[]{"user"}); + loginService.setUserStore(userStore); + loginService.setName(realm); + + Constraint constraint = new Constraint(); + constraint.setName("auth"); + constraint.setAuthenticate(true); + constraint.setRoles(new String[]{"**"}); + + ConstraintMapping mapping = new ConstraintMapping(); + mapping.setPathSpec("/secure/*"); + mapping.setConstraint(constraint); + + ConstraintSecurityHandler security = new ConstraintSecurityHandler(); + security.addConstraintMapping(mapping); + security.setAuthenticator(new BasicAuthenticator()); + security.setLoginService(loginService); + + return security; + } + @AfterEach public void after() throws Exception { _server.stop(); } + @Test + public void testLogRemoteUser() throws Exception + { + String authHeader = HttpHeader.AUTHORIZATION + ": Basic " + Base64.getEncoder().encodeToString("username:password".getBytes()); + testHandlerServerStart("%u %{d}u"); + + _connector.getResponse("GET / HTTP/1.0\n\n\n"); + String log = _entries.poll(5, TimeUnit.SECONDS); + assertThat(log, is("- -")); + + _connector.getResponse("GET / HTTP/1.0\n" + authHeader + "\n\n\n"); + log = _entries.poll(5, TimeUnit.SECONDS); + assertThat(log, is("- username")); + + _connector.getResponse("GET /secure HTTP/1.0\n" + authHeader + "\n\n\n"); + log = _entries.poll(5, TimeUnit.SECONDS); + assertThat(log, is("username username")); + } + @Test public void testModifier() throws Exception { @@ -374,7 +434,7 @@ public class CustomRequestLogTest _connector.getResponse("GET / HTTP/1.0\n\n"); String log = _entries.poll(5, TimeUnit.SECONDS); long requestTime = requestTimes.poll(5, TimeUnit.SECONDS); - DateCache dateCache = new DateCache(_log.DEFAULT_DATE_FORMAT, Locale.getDefault(), "GMT"); + DateCache dateCache = new DateCache(CustomRequestLog.DEFAULT_DATE_FORMAT, Locale.getDefault(), "GMT"); assertThat(log, is("RequestTime: [" + dateCache.format(requestTime) + "]")); } @@ -549,11 +609,13 @@ public class CustomRequestLogTest } } - private class TestHandler extends AbstractHandler + private class TestServlet extends HttpServlet { @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Request baseRequest = Objects.requireNonNull(Request.getBaseRequest(request)); + if (request.getRequestURI().contains("error404")) { response.setStatus(404); @@ -596,10 +658,7 @@ public class CustomRequestLogTest if (request.getContentLength() > 0) { InputStream in = request.getInputStream(); - while (in.read() > 0) - { - ; - } + while (in.read() > 0); } } } diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java index b2f96d50956..33bee7897c2 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DefaultHandlerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; @@ -78,7 +78,7 @@ public class DefaultHandlerTest } @Test - public void testGET_URL() throws Exception + public void testGetURL() throws Exception { URL url = new URL("http://localhost:" + serverPort + "/tests/alpha.txt"); URLConnection conn = url.openConnection(); @@ -93,7 +93,7 @@ public class DefaultHandlerTest } @Test - public void testGET_Raw() throws Exception + public void testGetRaw() throws Exception { StringBuffer rawRequest = new StringBuffer(); rawRequest.append("GET /tests/alpha.txt HTTP/1.1\r\n"); @@ -118,7 +118,7 @@ public class DefaultHandlerTest } @Test - public void testGET_HttpTesting() throws Exception + public void testGetHttpTesting() throws Exception { HttpTester.Request request = HttpTester.newRequest(); request.setMethod("GET"); diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java index 2b4b0ab8730..d1a5b540da6 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorInitializer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorTest.java index 64b462b2c3a..8d823d125c9 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DeploymentErrorTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; @@ -40,6 +40,7 @@ import org.eclipse.jetty.deploy.providers.WebAppProvider; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.RuntimeIOException; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -52,7 +53,6 @@ import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.Configuration; @@ -161,7 +161,7 @@ public class DeploymentErrorTest * The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=true;}. */ @Test - public void testInitial_BadApp_UnavailableTrue() + public void testInitialBadAppUnavailableTrue() { assertThrows(NoClassDefFoundError.class, () -> { @@ -178,7 +178,7 @@ public class DeploymentErrorTest * The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=false;}. */ @Test - public void testInitial_BadApp_UnavailableFalse() throws Exception + public void testInitialBadAppUnavailableFalse() throws Exception { startServer(docroots -> copyBadApp("badapp-unavailable-false.xml", docroots)); @@ -193,7 +193,7 @@ public class DeploymentErrorTest assertThat("ContextHandler.isAvailable", context.isAvailable(), is(false)); WebAppContext webapp = (WebAppContext)context; TrackedConfiguration trackedConfiguration = null; - for (Configuration webappConfig : webapp.getWebAppConfigurations()) + for (Configuration webappConfig : webapp.getConfigurations()) { if (webappConfig instanceof TrackedConfiguration) trackedConfiguration = (TrackedConfiguration)webappConfig; @@ -215,7 +215,7 @@ public class DeploymentErrorTest * The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=true;}. */ @Test - public void testDelayedAdd_BadApp_UnavailableTrue() throws Exception + public void testDelayedAddBadAppUnavailableTrue() throws Exception { Path docroots = startServer(null); @@ -239,7 +239,7 @@ public class DeploymentErrorTest assertThat("ContextHandler.isAvailable", context.isAvailable(), is(false)); WebAppContext webapp = (WebAppContext)context; TrackedConfiguration trackedConfiguration = null; - for (Configuration webappConfig : webapp.getWebAppConfigurations()) + for (Configuration webappConfig : webapp.getConfigurations()) { if (webappConfig instanceof TrackedConfiguration) trackedConfiguration = (TrackedConfiguration)webappConfig; @@ -261,7 +261,7 @@ public class DeploymentErrorTest * The webapp is a WebAppContext with {@code throwUnavailableOnStartupException=false;}. */ @Test - public void testDelayedAdd_BadApp_UnavailableFalse() throws Exception + public void testDelayedAddBadAppUnavailableFalse() throws Exception { Path docroots = startServer(null); @@ -285,7 +285,7 @@ public class DeploymentErrorTest assertThat("ContextHandler.isAvailable", context.isAvailable(), is(false)); WebAppContext webapp = (WebAppContext)context; TrackedConfiguration trackedConfiguration = null; - for (Configuration webappConfig : webapp.getWebAppConfigurations()) + for (Configuration webappConfig : webapp.getConfigurations()) { if (webappConfig instanceof TrackedConfiguration) trackedConfiguration = (TrackedConfiguration)webappConfig; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java index 666046b48fe..930106598b9 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/DigestPostTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; @@ -80,7 +80,7 @@ public class DigestPostTest "How now brown cow.\n" + "The quick brown fox jumped over the lazy dog.\n"; - public volatile static String _received = null; + public static volatile String _received = null; private static Server _server; public static class TestLoginService extends AbstractLoginService @@ -100,18 +100,12 @@ public class DigestPostTest roles.put(username, rolenames); } - /** - * @see org.eclipse.jetty.security.AbstractLoginService#loadRoleInfo(org.eclipse.jetty.security.AbstractLoginService.UserPrincipal) - */ @Override protected String[] loadRoleInfo(UserPrincipal user) { return roles.get(user.getName()); } - /** - * @see org.eclipse.jetty.security.AbstractLoginService#loadUserInfo(java.lang.String) - */ @Override protected UserPrincipal loadUserInfo(String username) { diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/FailedSelectorTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/FailedSelectorTest.java new file mode 100644 index 00000000000..f31db9e212f --- /dev/null +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/FailedSelectorTest.java @@ -0,0 +1,394 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import java.io.IOException; +import java.net.URI; +import java.nio.channels.Selector; +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; +import java.util.function.Function; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.HttpClientTransport; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.ManagedSelector; +import org.eclipse.jetty.io.SelectorManager; +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.Scheduler; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FailedSelectorTest +{ + private static final Logger LOG = LoggerFactory.getLogger(FailedSelectorTest.class); + private HttpClient client; + private Server server; + private StacklessLogging stacklessManagedSelector; + + @AfterEach + public void stopServerAndClient() throws Exception + { + server.stop(); + client.stop(); + stacklessManagedSelector.close(); + } + + @BeforeEach + public void startClient() throws Exception + { + HttpClientTransport transport = new HttpClientTransportOverHTTP(1); + QueuedThreadPool qtp = new QueuedThreadPool(); + qtp.setName("Client"); + client = new HttpClient(transport); + client.setExecutor(qtp); + + client.setIdleTimeout(1000); + client.setMaxConnectionsPerDestination(1); + client.setMaxRequestsQueuedPerDestination(1); + client.start(); + } + + public void startServer(Function customizeServerConsumer) throws Exception + { + stacklessManagedSelector = new StacklessLogging(ManagedSelector.class); + + server = new Server(); + server.setStopTimeout(1000); + server.setStopAtShutdown(true); + + ServerConnector connector = customizeServerConsumer.apply(server); + server.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + context.addServlet(HelloServlet.class, "/hello"); + + ServletHolder closeHolder = new ServletHolder(new CloseSelectorServlet(connector)); + context.addServlet(closeHolder, "/selector/close"); + + HandlerList handlers = new HandlerList(); + handlers.addHandler(context); + handlers.addHandler(new DefaultHandler()); + + server.setHandler(handlers); + + server.start(); + } + + @Test + public void testRestartServerOnSelectFailure() throws Exception + { + CountDownLatch failedLatch = new CountDownLatch(1); + + startServer((server) -> + { + RestartSelectorCustomConnector connector = new RestartSelectorCustomConnector(server, 1, 1, new RestartServerTask(server, failedLatch)); + connector.setPort(0); + connector.setIdleTimeout(1000); + return connector; + }); + + // Request /hello + assertRequestHello(); + + // Request /selector/close + assertRequestSelectorClose(); + + // Wait for selectors to close from action above + assertTrue(failedLatch.await(2, TimeUnit.SECONDS)); + + // Request /hello + assertRequestHello(); + } + + @Test + public void testRestartSelectorOnSelectFailure() throws Exception + { + CountDownLatch failedLatch = new CountDownLatch(1); + + startServer((server) -> + { + RestartSelectorCustomConnector connector = new RestartSelectorCustomConnector(server, 1, 1, new RestartSelectorTask(failedLatch)); + connector.setPort(0); + connector.setIdleTimeout(1000); + return connector; + }); + + // Request /hello + assertRequestHello(); + + // Request /selector/close + assertRequestSelectorClose(); + + // Wait for selectors to close from action above + assertTrue(failedLatch.await(2, TimeUnit.SECONDS)); + + // Request /hello + assertRequestHello(); + } + + private void assertRequestSelectorClose() throws InterruptedException, ExecutionException, TimeoutException + { + URI dest = server.getURI().resolve("/selector/close"); + LOG.info("Requesting GET on {}", dest); + + ContentResponse response = client.newRequest(dest) + .method(HttpMethod.GET) + .header(HttpHeader.CONNECTION, "close") + .send(); + + assertThat(dest + " status", response.getStatus(), is(HttpStatus.OK_200)); + assertThat(dest + " response", response.getContentAsString(), startsWith("Closing selectors ")); + } + + private void assertRequestHello() throws InterruptedException, ExecutionException, TimeoutException + { + URI dest = server.getURI().resolve("/hello"); + LOG.info("Requesting GET on {}", dest); + ContentResponse response = client.newRequest(dest) + .method(HttpMethod.GET) + .header(HttpHeader.CONNECTION, "close") + .send(); + + assertThat(dest + " status", response.getStatus(), is(HttpStatus.OK_200)); + assertThat(dest + " response", response.getContentAsString(), startsWith("Hello ")); + } + + public static class HelloServlet extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setContentType("text/plain"); + resp.setCharacterEncoding("utf-8"); + resp.getWriter().printf("Hello %s:%d%n", req.getRemoteAddr(), req.getRemotePort()); + } + } + + public static class CloseSelectorServlet extends HttpServlet + { + private static final int DELAY_MS = 500; + private ServerConnector connector; + private ScheduledExecutorService scheduledExecutorService; + + public CloseSelectorServlet(ServerConnector connector) + { + this.connector = connector; + scheduledExecutorService = Executors.newScheduledThreadPool(5); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setContentType("text/plain"); + resp.setCharacterEncoding("utf-8"); + resp.setHeader("Connection", "close"); + resp.getWriter().printf("Closing selectors in %,d ms%n", DELAY_MS); + scheduledExecutorService.schedule(new ForceCloseSelectorTask(connector), DELAY_MS, TimeUnit.MILLISECONDS); + } + } + + public static class RestartSelectorCustomConnector extends ServerConnector + { + private final Consumer onSelectFailConsumer; + + public RestartSelectorCustomConnector(Server server, int acceptors, int selectors, Consumer onSelectFailConsumer) + { + super(server, acceptors, selectors); + this.onSelectFailConsumer = onSelectFailConsumer; + } + + @Override + protected SelectorManager newSelectorManager(Executor executor, Scheduler scheduler, int selectors) + { + return new ServerConnectorManager(executor, scheduler, selectors) + { + @Override + protected ManagedSelector newSelector(int id) + { + return new CustomManagedSelector(this, id, onSelectFailConsumer); + } + }; + } + } + + public static class CustomManagedSelector extends ManagedSelector + { + private final Set endpoints = ConcurrentHashMap.newKeySet(); + private final Consumer onSelectFailConsumer; + + public CustomManagedSelector(SelectorManager selectorManager, int id, Consumer onSelectFailConsumer) + { + super(selectorManager, id); + this.onSelectFailConsumer = onSelectFailConsumer; + } + + @Override + protected void endPointOpened(EndPoint endPoint) + { + super.endPointOpened(endPoint); + endpoints.add(endPoint); + } + + @Override + protected void endPointClosed(EndPoint endPoint) + { + super.endPointClosed(endPoint); + endpoints.remove(endPoint); + } + + @Override + protected void onSelectFailed(Throwable cause) + { + endpoints.forEach((endpoint) -> + { + if (endpoint.getConnection() != null) + { + IO.close(endpoint.getConnection()); + } + IO.close(endpoint); + }); + endpoints.clear(); + + new Thread(() -> onSelectFailConsumer.accept(this), "OnSelectFailedTask").start(); + } + } + + private static class RestartSelectorTask implements Consumer + { + private static final Logger LOG = LoggerFactory.getLogger(RestartSelectorTask.class); + private final CountDownLatch latch; + + public RestartSelectorTask(CountDownLatch latch) + { + this.latch = latch; + } + + @Override + public void accept(CustomManagedSelector customManagedSelector) + { + try + { + customManagedSelector.stop(); + customManagedSelector.start(); + } + catch (Exception e) + { + LOG.warn("Unable to restart selector: {}", customManagedSelector, e); + } + finally + { + latch.countDown(); + } + } + } + + private static class RestartServerTask implements Consumer + { + private static final Logger LOG = LoggerFactory.getLogger(RestartServerTask.class); + private final Server server; + private final CountDownLatch latch; + + public RestartServerTask(Server server, CountDownLatch latch) + { + this.server = server; + this.latch = latch; + } + + @Override + public void accept(CustomManagedSelector customManagedSelector) + { + try + { + server.stop(); + server.start(); + } + catch (Exception e) + { + LOG.warn("Unable to restart server {}", server, e); + } + finally + { + latch.countDown(); + } + } + } + + private static class ForceCloseSelectorTask implements Runnable + { + private static final Logger LOG = LoggerFactory.getLogger(ForceCloseSelectorTask.class); + private final ServerConnector connector; + + public ForceCloseSelectorTask(ServerConnector connector) + { + this.connector = connector; + } + + @Override + public void run() + { + SelectorManager selectorManager = connector.getSelectorManager(); + Collection managedSelectors = selectorManager.getBeans(ManagedSelector.class); + for (ManagedSelector managedSelector : managedSelectors) + { + if (managedSelector instanceof CustomManagedSelector) + { + CustomManagedSelector customManagedSelector = (CustomManagedSelector)managedSelector; + Selector selector = customManagedSelector.getSelector(); + LOG.debug("Closing selector {}}", selector); + IO.close(selector); + } + } + } + } +} diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java index 9f8cb4850ec..2474e1ad945 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; @@ -102,11 +102,9 @@ public class HttpInputIntegrationTest __server.addConnector(http); // SSL Context Factory for HTTPS and HTTP/2 - String jetty_distro = System.getProperty("jetty.distro", "../../jetty-distribution/target/distribution"); __sslContextFactory = new SslContextFactory.Server(); - __sslContextFactory.setKeyStorePath(jetty_distro + "/../../../jetty-server/src/test/config/etc/keystore"); - __sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - __sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + __sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + __sslContextFactory.setKeyStorePassword("storepwd"); // HTTPS Configuration __sslConfig = new HttpConfiguration(__config); diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/FakeJspServlet.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/FakeJspServlet.java index e1eb8bb07e3..e8862320935 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/FakeJspServlet.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/FakeJspServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.jsp; @@ -29,9 +29,6 @@ import javax.servlet.http.HttpServletResponse; public class FakeJspServlet extends HttpServlet { - /* - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException { diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java index e4b2239962d..1c3422f3b7c 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithAliasesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.jsp; @@ -35,13 +35,13 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -54,7 +54,7 @@ import static org.hamcrest.Matchers.not; */ public class JspAndDefaultWithAliasesTest { - private static final Logger LOG = Log.getLogger(JspAndDefaultWithAliasesTest.class); + private static final Logger LOG = LoggerFactory.getLogger(JspAndDefaultWithAliasesTest.class); private static Server server; private static URI serverURI; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java index 322d663c7ea..52559d577e7 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/jsp/JspAndDefaultWithoutAliasesTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.jsp; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java index 988740c96ec..3517b2a2229 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.rfcs; @@ -32,6 +32,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.tools.HttpTester; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.test.support.StringUtil; import org.eclipse.jetty.test.support.XmlBasedJettyServer; import org.eclipse.jetty.test.support.rawhttp.HttpSocket; @@ -39,7 +40,6 @@ import org.eclipse.jetty.test.support.rawhttp.HttpTesting; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.StringAssert; -import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; @@ -123,7 +123,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 3.3) */ @Test - public void test3_3() + public void test33() { Calendar expected = Calendar.getInstance(); expected.set(Calendar.YEAR, 1994); @@ -161,7 +161,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 3.6) */ @Test - public void test3_6() throws Throwable + public void test36() throws Throwable { // Chunk last StringBuffer req1 = new StringBuffer(); @@ -186,7 +186,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 3.6) */ @Test - public void test3_6_2() throws Throwable + public void test362() throws Throwable { // Chunked StringBuffer req2 = new StringBuffer(); @@ -239,7 +239,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 3.6) */ @Test - public void test3_6_3() throws Throwable + public void test363() throws Throwable { // Chunked StringBuffer req3 = new StringBuffer(); @@ -292,7 +292,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 3.6) */ @Test - public void test3_6_4() throws Throwable + public void test364() throws Throwable { // Chunked and keep alive StringBuffer req4 = new StringBuffer(); @@ -331,7 +331,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 3.9) */ @Test - public void test3_9() + public void test39() { HttpFields fields = new HttpFields(); @@ -351,7 +351,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 4.4) */ @Test - public void test4_4() throws Exception + public void test44() throws Exception { // 4.4.2 - transfer length is 'chunked' when the 'Transfer-Encoding' header // is provided with a value other than 'identity', unless the @@ -366,20 +366,11 @@ public abstract class RFC2616BaseTest req1.append("\n"); req1.append("123\r\n"); - req1.append("GET /echo/R2 HTTP/1.1\n"); - req1.append("Host: localhost\n"); - req1.append("Connection: close\n"); - req1.append("\n"); - List responses = http.requests(req1); - assertEquals(2, responses.size(), "Response Count"); + assertEquals(1, responses.size(), "Response Count"); HttpTester.Response response = responses.get(0); - assertThat("4.4.2 Message Length / Response Code", response.getStatus(), is(HttpStatus.OK_200)); - assertThat("4.4.2 Message Length / Body", response.getContent(), Matchers.containsString("123\n")); - response = responses.get(1); - assertThat("4.4.2 Message Length / Response Code", response.getStatus(), is(HttpStatus.OK_200)); - assertEquals("", response.getContent(), "4.4.2 Message Length / No Body"); + assertThat("4.4.2 Message Length / Response Code", response.getStatus(), is(HttpStatus.BAD_REQUEST_400)); // 4.4.3 - // Client - do not send 'Content-Length' if entity-length @@ -455,7 +446,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_DefaultHost() throws Exception + public void test52DefaultHost() throws Exception { // Default Host @@ -477,7 +468,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_VirtualHost() throws Exception + public void test52VirtualHost() throws Exception { // Virtual Host @@ -499,7 +490,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_VirtualHostInsensitive() throws Exception + public void test52VirtualHostInsensitive() throws Exception { // Virtual Host case insensitive @@ -521,7 +512,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_NoVirtualHost() throws Exception + public void test52NoVirtualHost() throws Exception { // No Virtual Host @@ -541,7 +532,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_BadVirtualHost() throws Exception + public void test52BadVirtualHost() throws Exception { // Bad Virtual Host @@ -563,7 +554,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_VirtualHostAbsoluteURI_Http11_WithoutHostHeader() throws Exception + public void test52VirtualHostAbsoluteURIHttp11WithoutHostHeader() throws Exception { // Virtual Host as Absolute URI @@ -584,7 +575,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_VirtualHostAbsoluteURI_Http10_WithoutHostHeader() throws Exception + public void test52VirtualHostAbsoluteURIHttp10WithoutHostHeader() throws Exception { // Virtual Host as Absolute URI @@ -605,7 +596,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 5.2) */ @Test - public void test5_2_VirtualHostAbsoluteURI_WithHostHeader() throws Exception + public void test52VirtualHostAbsoluteURIWithHostHeader() throws Exception { // Virtual Host as Absolute URI (with Host header) @@ -627,7 +618,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 8.1) */ @Test - public void test8_1() throws Exception + public void test81() throws Exception { StringBuffer req1 = new StringBuffer(); req1.append("GET /tests/R1.txt HTTP/1.1\n"); @@ -678,7 +669,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 8.2) */ @Test - public void test8_2_ExpectInvalid() throws Exception + public void test82ExpectInvalid() throws Exception { // Expect Failure @@ -702,7 +693,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 8.2) */ @Test - public void test8_2_ExpectWithBody() throws Exception + public void test82ExpectWithBody() throws Exception { // Expect with body @@ -730,7 +721,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 8.2) */ @Test - public void test8_2_UnexpectWithBody() throws Exception + public void test82UnexpectWithBody() throws Exception { // Expect with body @@ -765,7 +756,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 8.2) */ @Test - public void test8_2_ExpectNormal() throws Exception + public void test82ExpectNormal() throws Exception { // Expect 100 @@ -805,7 +796,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 9.2) */ @Test - public void test9_2_ServerOptions() throws Exception + public void test92ServerOptions() throws Exception { // Unsupported in Jetty. // Server can handle many webapps, each with their own set of supported OPTIONS. @@ -828,7 +819,7 @@ public abstract class RFC2616BaseTest // Header expected ... // Allow: GET, HEAD, POST, PUT, DELETE, MOVE, OPTIONS, TRACE String allow = response.get("Allow"); - String expectedMethods[] = + String[] expectedMethods = {"GET", "HEAD", "POST", "PUT", "DELETE", "MOVE", "OPTIONS", "TRACE"}; for (String expectedMethod : expectedMethods) { @@ -844,7 +835,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 9.2) */ @Test - public void test9_2_ResourceOptions() throws Exception + public void test92ResourceOptions() throws Exception { // Jetty is conditionally compliant. // Possible Bug in the Spec. @@ -875,7 +866,7 @@ public abstract class RFC2616BaseTest // Header expected ... // Allow: GET, HEAD, POST, TRACE, OPTIONS String allow = response.get("Allow"); - String expectedMethods[] = + String[] expectedMethods = {"GET", "HEAD", "POST", "OPTIONS", "TRACE"}; for (String expectedMethod : expectedMethods) { @@ -891,7 +882,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 9.4) */ @Test - public void test9_4() throws Exception + public void test94() throws Exception { /* Test GET first. (should have body) */ @@ -955,7 +946,7 @@ public abstract class RFC2616BaseTest */ @Test @Disabled("Introduction of fix for realm-less security constraints has rendered this test invalid due to default configuration preventing use of TRACE in webdefault.xml") - public void test9_8() throws Exception + public void test98() throws Exception { StringBuffer req1 = new StringBuffer(); @@ -978,7 +969,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 10.2.7) */ @Test - public void test10_2_7() throws Exception + public void test1027() throws Exception { // check to see if corresponding GET w/o range would return // a) ETag @@ -1057,7 +1048,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 10.3) */ @Test - public void test10_3_RedirectHttp10Path() throws Exception + public void test103RedirectHttp10Path() throws Exception { String specId; @@ -1081,7 +1072,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 10.3) */ @Test - public void test10_3_RedirectHttp11Path() throws Exception + public void test103RedirectHttp11Path() throws Exception { // HTTP/1.1 @@ -1116,7 +1107,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 10.3) */ @Test - public void test10_3_RedirectHttp10Resource() throws Exception + public void test103RedirectHttp10Resource() throws Exception { // HTTP/1.0 - redirect with resource/content @@ -1139,7 +1130,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 10.3) */ @Test - public void test10_3_RedirectHttp11Resource() throws Exception + public void test103RedirectHttp11Resource() throws Exception { // HTTP/1.1 - redirect with resource/content @@ -1164,7 +1155,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.3) */ @Test - public void test14_3_AcceptEncodingGzip() throws Exception + public void test143AcceptEncodingGzip() throws Exception { String specId; @@ -1190,7 +1181,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.16) */ @Test - public void test14_16_NoRange() throws Exception + public void test1416NoRange() throws Exception { // // calibrate with normal request (no ranges); if this doesnt @@ -1236,7 +1227,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.16) */ @Test - public void test14_16_PartialRange() throws Exception + public void test1416PartialRange() throws Exception { String alpha = ALPHA; @@ -1256,7 +1247,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.16) */ @Test - public void test14_16_PartialRange_MixedRanges() throws Exception + public void test1416PartialRangeMixedRanges() throws Exception { String alpha = ALPHA; @@ -1297,7 +1288,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.16) */ @Test - public void test14_16_PartialRange_MixedBytes() throws Exception + public void test1416PartialRangeMixedBytes() throws Exception { String alpha = ALPHA; @@ -1336,7 +1327,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.16) */ @Test - public void test14_16_PartialRange_MixedMultiple() throws Exception + public void test1416PartialRangeMixedMultiple() throws Exception { String alpha = ALPHA; @@ -1375,7 +1366,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.23) */ @Test - public void test14_23_Http10_NoHostHeader() throws Exception + public void test1423Http10NoHostHeader() throws Exception { // HTTP/1.0 OK with no host @@ -1394,7 +1385,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.23) */ @Test - public void test14_23_Http11_NoHost() throws Exception + public void test1423Http11NoHost() throws Exception { // HTTP/1.1 400 (bad request) with no host @@ -1413,7 +1404,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.23) */ @Test - public void test14_23_ValidHost() throws Exception + public void test1423ValidHost() throws Exception { // HTTP/1.1 - Valid host @@ -1433,7 +1424,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.23) */ @Test - public void test14_23_IncompleteHostHeader() throws Exception + public void test1423IncompleteHostHeader() throws Exception { // HTTP/1.1 - Incomplete (empty) Host header try (StacklessLogging stackless = new StacklessLogging(HttpParser.class)) @@ -1479,7 +1470,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.35) */ @Test - public void test14_35_Range() throws Exception + public void test1435Range() throws Exception { // // test various valid range specs that have not been @@ -1508,7 +1499,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.35) */ @Test - public void test14_35_Range_Multipart1() throws Exception + public void test1435RangeMultipart1() throws Exception { String rangedef = "23-23,-2"; // Request byte at offset 23, and the last 2 bytes @@ -1565,7 +1556,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.35) */ @Test - public void test14_35_PartialRange() throws Exception + public void test1435PartialRange() throws Exception { // // test various valid range specs that have not been @@ -1601,7 +1592,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.35) */ @Test - public void test14_35_BadRange_InvalidSyntax() throws Exception + public void test1435BadRangeInvalidSyntax() throws Exception { // server should ignore all range headers which include // at least one syntactically invalid range @@ -1618,7 +1609,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.39) */ @Test - public void test14_39_TEGzip() throws Exception + public void test1439TEGzip() throws Exception { if (STRICT) { @@ -1646,7 +1637,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 14.39) */ @Test - public void test14_39_TEDeflate() throws Exception + public void test1439TEDeflate() throws Exception { if (STRICT) { @@ -1672,7 +1663,7 @@ public abstract class RFC2616BaseTest * @see RFC 2616 (section 19.6) */ @Test - public void test19_6() throws Exception + public void test196() throws Exception { String specId; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java index 472a7d20948..a6e5f897eaa 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.rfcs; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java index 4218cc8fbe7..64068dab063 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616NIOHttpsTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.rfcs; @@ -49,10 +49,4 @@ public class RFC2616NIOHttpsTest extends RFC2616BaseTest { return new HttpsSocketImpl(); } - - @Override - public void test8_2_ExpectInvalid() throws Exception - { - super.test8_2_ExpectInvalid(); - } } diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/EchoHandler.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/EchoHandler.java index dc74b5b470b..e52716092d8 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/EchoHandler.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/EchoHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java index c0ac9cdff42..0e1afafc20d 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java @@ -1,38 +1,22 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support; -// -//======================================================================== -//------------------------------------------------------------------------ -//All rights reserved. This program and the accompanying materials -//are made available under the terms of the Eclipse Public License v1.0 -//and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -//You may elect to redistribute this code under either of these licenses. -//======================================================================== -// import java.io.BufferedReader; import java.io.File; @@ -671,7 +655,8 @@ public class JettyDistro Matcher mat = pat.getMatcher(line); if (mat.find()) { - int num = 0, count = mat.groupCount(); + int num = 0; + int count = mat.groupCount(); String[] match = new String[count]; while (num++ < count) { diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java index 2211e0e6ba7..2d08a076cd0 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/XmlBasedJettyServer.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/XmlBasedJettyServer.java index 3de74200ad8..6bef5cd697c 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/XmlBasedJettyServer.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/XmlBasedJettyServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support; @@ -35,11 +35,11 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -50,7 +50,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class XmlBasedJettyServer { - private static final Logger LOG = Log.getLogger(XmlBasedJettyServer.class); + private static final Logger LOG = LoggerFactory.getLogger(XmlBasedJettyServer.class); private List _xmlConfigurations; private final Map _properties = new HashMap<>(); private Server _server; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java index 568002a7fbd..4ace1005f91 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpRequestTesterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support.rawhttp; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java index 7900d57f2cd..8df059a1d07 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpResponseTesterTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support.rawhttp; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocket.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocket.java index c3a4d13cdc7..30b476a6382 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocket.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support.rawhttp; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocketImpl.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocketImpl.java index 4bfdc039b54..54beb7670be 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocketImpl.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpSocketImpl.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support.rawhttp; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java index bbe8699b184..c3735e9f8d9 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpTesting.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support.rawhttp; @@ -163,6 +163,7 @@ public class HttpTesting } } + // @checkstyle-disable-check : MethodName private void DEBUG(String msg) { if (debug) @@ -170,6 +171,7 @@ public class HttpTesting System.out.println(msg); } } + // @checkstyle-enable-check : MethodName public void enableDebug() { diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java index 6ca06d02d05..806f986d432 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/rawhttp/HttpsSocketImpl.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.support.rawhttp; @@ -29,16 +29,16 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An HTTPS Socket Impl */ public class HttpsSocketImpl implements HttpSocket { - private static final Logger LOG = Log.getLogger(HttpsSocketImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpsSocketImpl.class); private SSLContext sslContext; private SSLSocketFactory sslfactory; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxSimpleEchoSocket.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxSimpleEchoSocket.java index ebc0329caa4..a0b66e578ef 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxSimpleEchoSocket.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxSimpleEchoSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.websocket; @@ -27,8 +27,8 @@ import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.fail; @@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail; subprotocols = {"chat"}) public class JavaxSimpleEchoSocket { - private static final Logger LOG = Log.getLogger(JavaxSimpleEchoSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(JavaxSimpleEchoSocket.class); private Session session; public CountDownLatch messageLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); @@ -44,7 +44,7 @@ public class JavaxSimpleEchoSocket @OnError public void onError(Throwable t) { - LOG.warn(t); + LOG.warn("Error", t); fail(t.getMessage()); } diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxWebSocketTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxWebSocketTest.java index 24ccc4dfeae..0ec110f873d 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxWebSocketTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JavaxWebSocketTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.websocket; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettySimpleEchoSocket.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettySimpleEchoSocket.java index abd83fb2bec..6daebda51f0 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettySimpleEchoSocket.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettySimpleEchoSocket.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.websocket; @@ -21,14 +21,14 @@ package org.eclipse.jetty.test.websocket; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Basic Echo Client Socket @@ -36,7 +36,7 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; @WebSocket(maxTextMessageSize = 64 * 1024) public class JettySimpleEchoSocket { - private static final Logger LOG = Log.getLogger(JettySimpleEchoSocket.class); + private static final Logger LOG = LoggerFactory.getLogger(JettySimpleEchoSocket.class); private final CountDownLatch closeLatch; @SuppressWarnings("unused") private Session session; @@ -71,7 +71,7 @@ public class JettySimpleEchoSocket } catch (Throwable t) { - LOG.warn(t); + LOG.warn("Unable to send string+close", t); } } diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettyWebSocketTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettyWebSocketTest.java index 883b3448ff4..d1fe9f09eff 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettyWebSocketTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/websocket/JettyWebSocketTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.websocket; diff --git a/tests/test-integration/src/test/resources/DefaultHandler.xml b/tests/test-integration/src/test/resources/DefaultHandler.xml index d7fab77a311..992bea97225 100644 --- a/tests/test-integration/src/test/resources/DefaultHandler.xml +++ b/tests/test-integration/src/test/resources/DefaultHandler.xml @@ -13,7 +13,7 @@ 8192 true false - 4096 + 1024
        diff --git a/tests/test-integration/src/test/resources/RFC2616Base.xml b/tests/test-integration/src/test/resources/RFC2616Base.xml index acb64a9c4ab..ed55b90a72d 100644 --- a/tests/test-integration/src/test/resources/RFC2616Base.xml +++ b/tests/test-integration/src/test/resources/RFC2616Base.xml @@ -20,7 +20,7 @@ 8192 true false - 4096 + 1024 - compile + test diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java index c4549b3f1fc..c42e7b71b87 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -39,9 +39,6 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi FileTestHelper.teardown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java index 60d9bde5c60..86c2878d566 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -74,9 +74,6 @@ public class FileSessionDataStoreTest extends AbstractSessionDataStoreTest } } - /** - * - */ @Override public boolean checkSessionPersisted(SessionData data) throws Exception { diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java index dee4266ab15..234f8fe568b 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/TestFileSessions.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/TestFileSessions.java index 71588689bea..62e9a0aef5a 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/TestFileSessions.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/TestFileSessions.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-file-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-file-sessions/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..80576de17b7 --- /dev/null +++ b/tests/test-sessions/test-file-sessions/src/test/resources/jetty-logging.properties @@ -0,0 +1,3 @@ +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=WARN +log.LEVEL=WARN diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index 6b5ae8f14da..f7f47ce19af 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -36,26 +36,31 @@ org.eclipse.jetty jetty-server ${project.version} + test org.eclipse.jetty jetty-webapp ${project.version} + test org.eclipse.jetty jetty-client ${project.version} + test org.eclipse.jetty.tests test-sessions-common ${project.version} + test org.eclipse.jetty.gcloud jetty-gcloud-session-manager ${project.version} + test diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java index e2835d93f21..809b82ab1c5 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -46,9 +46,6 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi __testSupport.tearDown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java index 05533332c4f..ea1e2ed8daa 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -45,9 +45,6 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav __testSupport.tearDown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java index 17979feb7ed..0023b85ffa5 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -81,9 +81,6 @@ public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest return __testSupport.checkSessionExists(data.getId()); } - /** - * - */ @Override public boolean checkSessionPersisted(SessionData data) throws Exception { diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java index ba679d4bd33..661b57d150b 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -68,9 +68,6 @@ public class GCloudSessionTestSupport _d = d; } - /** - * @see org.eclipse.jetty.gcloud.session.GCloudSessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java index bd0842b3d17..88b47832e4e 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.gcloud.session; @@ -45,9 +45,6 @@ public class InvalidationSessionTest extends AbstractClusteredInvalidationSessio __testSupport.tearDown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index fa96894adad..22f7719be61 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -54,9 +54,6 @@ 45 240 - - ${project.build.testOutputDirectory}/logging.properties - @@ -66,38 +63,60 @@ org.eclipse.jetty jetty-server ${project.version} + test org.eclipse.jetty jetty-webapp ${project.version} + test org.eclipse.jetty jetty-client ${project.version} + test org.eclipse.jetty.tests test-sessions-common ${project.version} + test org.eclipse.jetty jetty-hazelcast ${project.version} + test org.eclipse.jetty jetty-jmx ${project.version} true + test org.eclipse.jetty.toolchain jetty-test-helper test + + org.slf4j + slf4j-api + test + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + test + + + org.eclipse.jetty + jetty-slf4j-impl + test + diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java index 77c50f2a5d0..aac2b34ad52 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; @@ -46,9 +46,6 @@ public class ClusteredOrphanedSessionTest _testHelper.tearDown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java index ddc67743c3c..620a044e8b8 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; @@ -46,9 +46,6 @@ public class ClusteredSessionScavengingTest _testHelper.tearDown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastClusteredInvalidationSessionTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastClusteredInvalidationSessionTest.java index 6c6cbcb996c..cb918df97be 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastClusteredInvalidationSessionTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastClusteredInvalidationSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java index 428c4e3325a..4e8db88b25c 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java index 9b2eba1467d..87fa2e2d4d3 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session; @@ -53,6 +53,15 @@ public class HazelcastTestHelper static { + // Wire up hazelcast logging to slf4j + System.setProperty("hazelcast.logging.class", "com.hazelcast.logging.Slf4jFactory"); + + // Wire up java.util.logging (used by hazelcast libs) to slf4j. + if (!org.slf4j.bridge.SLF4JBridgeHandler.isInstalled()) + { + org.slf4j.bridge.SLF4JBridgeHandler.install(); + } + _serializerConfig = new SerializerConfig().setImplementation(new SessionDataSerializer()).setTypeClass(SessionData.class); Config config = new Config(); config.setInstanceName(_hazelcastInstanceName); @@ -79,9 +88,9 @@ public class HazelcastTestHelper ClientConfig clientConfig = new ClientConfig() .setNetworkConfig(clientNetworkConfig); - SerializerConfig sc = new SerializerConfig(). - setImplementation(new SessionDataSerializer()). - setTypeClass(SessionData.class); + SerializerConfig sc = new SerializerConfig() + .setImplementation(new SessionDataSerializer()) + .setTypeClass(SessionData.class); clientConfig.getSerializationConfig().addSerializerConfig(sc); factory.setHazelcastInstance(HazelcastClient.newHazelcastClient(clientConfig)); diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java index a643a3c56d8..2a603ce62f7 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session.client; diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java index a814559e21c..30150d585fa 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session.client; diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java index ef309df8ee0..df2e2fc4b2f 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.hazelcast.session.client; diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-hazelcast-sessions/src/test/resources/jetty-logging.properties index 07faa86dbce..93a1284d6c4 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/resources/jetty-logging.properties +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/resources/jetty-logging.properties @@ -1 +1,5 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog \ No newline at end of file +# Jetty Logging using jetty-slf4j-impl +org.eclipse.jetty.logging.appender.NAME_CONDENSE=false +org.eclipse.jetty.logging.appender.MESSAGE_ESCAPE=false +# org.eclipse.jetty.LEVEL=WARN +log.LEVEL=WARN diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/resources/logging.properties b/tests/test-sessions/test-hazelcast-sessions/src/test/resources/logging.properties deleted file mode 100644 index 256dbe49265..00000000000 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/resources/logging.properties +++ /dev/null @@ -1,3 +0,0 @@ -handlers=java.util.logging.ConsoleHandler -.level=INFO -com.hazelcast.level=SEVERE \ No newline at end of file diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index c414f7f5848..f30c57237aa 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -65,32 +65,38 @@ org.eclipse.jetty jetty-server ${project.version} + test org.eclipse.jetty jetty-webapp ${project.version} + test org.eclipse.jetty jetty-client ${project.version} + test org.eclipse.jetty.tests test-sessions-common ${project.version} + test org.eclipse.jetty infinispan-remote-query ${project.version} + test org.eclipse.jetty jetty-jmx ${project.version} true + test org.eclipse.jetty.toolchain @@ -129,8 +135,18 @@ org.slf4j - slf4j-jdk14 - 1.7.25 + slf4j-api + test + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + test + + + org.eclipse.jetty + jetty-slf4j-impl test diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java index 6276d93b364..a9bdd98248b 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -27,6 +27,11 @@ import org.junit.jupiter.api.BeforeAll; */ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessionTest { + static + { + LoggingUtil.init(); + } + public static InfinispanTestSupport __testSupport; @BeforeAll @@ -42,9 +47,6 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi __testSupport.teardown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java new file mode 100644 index 00000000000..f7bdbdf12c7 --- /dev/null +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.server.session; + +import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +/** + * ClusteredSerializedSessionScavengingTest + */ +public class ClusteredSerializedSessionScavengingTest extends AbstractClusteredSessionScavengingTest +{ + public static InfinispanTestSupport __testSupport; + + @BeforeAll + public static void setup() throws Exception + { + __testSupport = new InfinispanTestSupport(); + __testSupport.setUseFileStore(true); + __testSupport.setSerializeSessionData(true); + __testSupport.setup(); + } + + @AfterAll + public static void teardown() throws Exception + { + if (__testSupport != null) + __testSupport.teardown(); + } + + @Override + @Test + public void testClusteredScavenge() + throws Exception + { + super.testClusteredScavenge(); + } + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory(); + factory.setCache(__testSupport.getCache()); + return factory; + } +} diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java index e1b7b7f144e..fe89e2bb4a5 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -28,6 +28,11 @@ import org.junit.jupiter.api.Test; */ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScavengingTest { + static + { + LoggingUtil.init(); + } + public InfinispanTestSupport _testSupport; @BeforeEach @@ -53,9 +58,6 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav super.testClusteredScavenge(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicEchoSocket.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java similarity index 62% rename from jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicEchoSocket.java rename to tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java index ebbfbff6d73..3ce2bc89f76 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/sockets/BasicEchoSocket.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -16,22 +16,22 @@ // ======================================================================== // -package org.eclipse.jetty.websocket.javax.tests.server.sockets; +package org.eclipse.jetty.server.session; -import javax.websocket.OnMessage; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; +import org.junit.jupiter.api.BeforeEach; /** - * Annotated echo socket + * HotInitInfinispanSessionDataStoreTest */ -@ServerEndpoint("/echo") -public class BasicEchoSocket +public class InfinispanFileSessionDataStoreTest extends InfinispanSessionDataStoreTest { - @OnMessage - public void echo(Session session, String msg) + + @BeforeEach + public void setup() throws Exception { - // reply with echo - session.getAsyncRemote().sendText(msg); + _testSupport = new InfinispanTestSupport(); + _testSupport.setUseFileStore(true); + _testSupport.setup(); } + } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java index 5bcedbaeb24..faa76ba22bb 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java @@ -1,30 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; -import java.util.ArrayList; -import java.util.List; - import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.session.infinispan.InfinispanSessionData; import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStore; import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory; -import org.infinispan.Cache; import org.infinispan.query.Search; import org.infinispan.query.dsl.Query; import org.infinispan.query.dsl.QueryFactory; @@ -32,8 +29,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; /** @@ -41,34 +37,38 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest { + static + { + LoggingUtil.init(); + } - public InfinispanTestSupport __testSupport; + public InfinispanTestSupport _testSupport; @BeforeEach public void setup() throws Exception { - __testSupport = new InfinispanTestSupport(); - __testSupport.setup(); + _testSupport = new InfinispanTestSupport(); + _testSupport.setup(); } @AfterEach public void teardown() throws Exception { - __testSupport.teardown(); + _testSupport.teardown(); } @Override public SessionDataStoreFactory createSessionDataStoreFactory() { InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory(); - factory.setCache(__testSupport.getCache()); + factory.setCache(_testSupport.getCache()); return factory; } @Override public void persistSession(SessionData data) throws Exception { - __testSupport.createSession(data); + _testSupport.createSession(data); } @Override @@ -80,7 +80,7 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest @Override public boolean checkSessionExists(SessionData data) throws Exception { - return __testSupport.checkSessionExists(data); + return _testSupport.checkSessionExists(data); } /** @@ -153,7 +153,7 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest Thread.currentThread().setContextClassLoader(_contextClassLoader); try { - return __testSupport.checkSessionPersisted(data); + return _testSupport.checkSessionPersisted(data); } finally { @@ -164,30 +164,26 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest @Test public void testQuery() throws Exception { - Cache cache = __testSupport.getCache(); + InfinispanSessionData sd1 = new InfinispanSessionData("sd1", "", "", 0, 0, 0, 1000); + sd1.setLastNode("fred1"); + _testSupport.getCache().put("session1", sd1); - SessionData sd1 = new SessionData("sd1", "", "", 0, 0, 0, 0); - SessionData sd2 = new SessionData("sd2", "", "", 0, 0, 0, 1000); - sd2.setExpiry(100L); //long ago - SessionData sd3 = new SessionData("sd3", "", "", 0, 0, 0, 0); + InfinispanSessionData sd2 = new InfinispanSessionData("sd2", "", "", 0, 0, 0, 2000); + sd2.setLastNode("fred2"); + _testSupport.getCache().put("session2", sd2); - cache.put("session1", sd1); - cache.put("session2", sd2); - cache.put("session3", sd3); + InfinispanSessionData sd3 = new InfinispanSessionData("sd3", "", "", 0, 0, 0, 3000); + sd3.setLastNode("fred3"); + _testSupport.getCache().put("session3", sd3); - QueryFactory qf = Search.getQueryFactory(cache); - Query q = qf.from(SessionData.class).select("id").having("expiry").lte(System.currentTimeMillis()).and().having("expiry").gt(0).toBuilder().build(); + QueryFactory qf = Search.getQueryFactory(_testSupport.getCache()); - List list = q.list(); - - List ids = new ArrayList<>(); - for (Object[] sl : list) + for (int i = 0; i <= 3; i++) { - ids.add((String)sl[0]); + long now = System.currentTimeMillis(); + Query q = qf.from(InfinispanSessionData.class).having("expiry").lt(now).build(); + assertEquals(i, q.list().size()); + Thread.sleep(1000); } - - assertFalse(ids.isEmpty()); - assertTrue(1 == ids.size()); - assertTrue(ids.contains("sd2")); } } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java index ba32afa409a..a9a158b9346 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -27,8 +27,8 @@ import org.eclipse.jetty.util.IO; import org.hibernate.search.cfg.Environment; import org.hibernate.search.cfg.SearchMapping; import org.infinispan.Cache; -import org.infinispan.configuration.cache.Configuration; import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.configuration.cache.ConfigurationChildBuilder; import org.infinispan.configuration.cache.Index; import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.manager.DefaultCacheManager; @@ -48,6 +48,7 @@ public class InfinispanTestSupport public ConfigurationBuilder _builder; private File _tmpdir; private boolean _useFileStore; + private boolean _serializeSessionData; private String _name; public static EmbeddedCacheManager _manager; @@ -82,6 +83,11 @@ public class InfinispanTestSupport _useFileStore = useFileStore; } + public void setSerializeSessionData(boolean serializeSessionData) + { + _serializeSessionData = serializeSessionData; + } + public Cache getCache() { return _cache; @@ -106,25 +112,33 @@ public class InfinispanTestSupport _tmpdir.delete(); _tmpdir.mkdir(); - Configuration config = _builder.indexing() + ConfigurationChildBuilder b = _builder.indexing() .index(Index.ALL) .addIndexedEntity(SessionData.class) .withProperties(properties) .persistence() .addSingleFileStore() - .location(_tmpdir.getAbsolutePath()) - .storeAsBinary() - .build(); - - _manager.defineConfiguration(_name, config); + .location(_tmpdir.getAbsolutePath()); + if (_serializeSessionData) + { + b = b.storeAsBinary().enable(); + } + + _manager.defineConfiguration(_name, b.build()); } else { - _manager.defineConfiguration(_name, _builder.indexing() + ConfigurationChildBuilder b = _builder.indexing() .withProperties(properties) .index(Index.ALL) - .addIndexedEntity(SessionData.class) - .build()); + .addIndexedEntity(SessionData.class); + + if (_serializeSessionData) + { + b = b.storeAsBinary().enable(); + } + + _manager.defineConfiguration(_name, b.build()); } _cache = _manager.getCache(_name); } @@ -163,6 +177,13 @@ public class InfinispanTestSupport public boolean checkSessionPersisted(SessionData data) throws Exception { + + //evicts the object from memory. Forces the cache to fetch the data from file + if (_useFileStore) + { + _cache.evict(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId()); + } + Object obj = _cache.get(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId()); if (obj == null) return false; diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LoggingUtil.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LoggingUtil.java new file mode 100644 index 00000000000..d63448fb665 --- /dev/null +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LoggingUtil.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +public final class LoggingUtil +{ + /** + * It's easier to setup logging in code for this test project, + * then it is to setup the various system properties and files for every test + * execution (maven, CI, and IDE). + */ + public static void init() + { + // Wire up jboss logging (used by infinispan) to slf4j + System.setProperty("org.jboss.logging.provider", "slf4j"); + + // Wire up java.util.logging (used by hibernate, infinispan, and others) to slf4j. + if (!org.slf4j.bridge.SLF4JBridgeHandler.isInstalled()) + { + org.slf4j.bridge.SLF4JBridgeHandler.install(); + } + } +} diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java new file mode 100644 index 00000000000..5f45903196b --- /dev/null +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java @@ -0,0 +1,186 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.server.session; + +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.session.infinispan.InfinispanSessionData; +import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStore; +import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory; +import org.infinispan.query.Search; +import org.infinispan.query.dsl.Query; +import org.infinispan.query.dsl.QueryFactory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * SerializedInfinispanSessionDataStoreTest + */ +public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest +{ + + public InfinispanTestSupport _testSupport; + + @BeforeEach + public void setup() throws Exception + { + _testSupport = new InfinispanTestSupport(); + _testSupport.setSerializeSessionData(true); + _testSupport.setup(); + } + + @AfterEach + public void teardown() throws Exception + { + _testSupport.teardown(); + } + + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory(); + factory.setCache(_testSupport.getCache()); + return factory; + } + + @Override + public void persistSession(SessionData data) throws Exception + { + _testSupport.createSession(data); + } + + @Override + public void persistUnreadableSession(SessionData data) throws Exception + { + //Not used by testLoadSessionFails() + } + + @Override + public boolean checkSessionExists(SessionData data) throws Exception + { + return _testSupport.checkSessionExists(data); + } + + /** + * This test deliberately sets the infinispan cache to null to + * try and provoke an exception in the InfinispanSessionDataStore.load() method. + */ + @Override + public void testLoadSessionFails() throws Exception + { + //create the SessionDataStore + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + SessionDataStoreFactory factory = createSessionDataStoreFactory(); + ((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC); + SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler()); + SessionContext sessionContext = new SessionContext("foo", context.getServletContext()); + store.initialize(sessionContext); + + //persist a session + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("222", 100, now, now - 1, -1); + data.setLastNode(sessionContext.getWorkerName()); + persistSession(data); + + store.start(); + + ((InfinispanSessionDataStore)store).setCache(null); + + //test that loading it fails + try + { + store.load("222"); + fail("Session should be unreadable"); + } + catch (UnreadableSessionDataException e) + { + //expected exception + } + } + + /** + * This test currently won't work for Infinispan - there is currently no + * means to query it to find sessions that have expired. + * + * @see org.eclipse.jetty.server.session.AbstractSessionDataStoreTest#testGetExpiredPersistedAndExpiredOnly() + */ + @Override + public void testGetExpiredPersistedAndExpiredOnly() throws Exception + { + + } + + /** + * This test won't work for Infinispan - there is currently no + * means to query infinispan to find other expired sessions. + */ + @Override + public void testGetExpiredDifferentNode() throws Exception + { + //Ignore + } + + /** + * + */ + @Override + public boolean checkSessionPersisted(SessionData data) throws Exception + { + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(_contextClassLoader); + try + { + return _testSupport.checkSessionPersisted(data); + } + finally + { + Thread.currentThread().setContextClassLoader(old); + } + } + + @Test + public void testQuery() throws Exception + { + InfinispanSessionData sd1 = new InfinispanSessionData("sd1", "", "", 0, 0, 0, 1000); + sd1.setLastNode("fred1"); + _testSupport.getCache().put("session1", sd1); + + InfinispanSessionData sd2 = new InfinispanSessionData("sd2", "", "", 0, 0, 0, 2000); + sd2.setLastNode("fred2"); + _testSupport.getCache().put("session2", sd2); + + InfinispanSessionData sd3 = new InfinispanSessionData("sd3", "", "", 0, 0, 0, 3000); + sd3.setLastNode("fred3"); + _testSupport.getCache().put("session3", sd3); + + QueryFactory qf = Search.getQueryFactory(_testSupport.getCache()); + + for (int i = 0; i <= 3; i++) + { + long now = System.currentTimeMillis(); + Query q = qf.from(InfinispanSessionData.class).having("expiry").lt(now).build(); + assertEquals(i, q.list().size()); + Thread.sleep(1000); + } + } +} diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredInvalidationSessionTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredInvalidationSessionTest.java index bb71012b71b..5e8d48610ca 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredInvalidationSessionTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredInvalidationSessionTest.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session.remote; import org.eclipse.jetty.server.session.AbstractClusteredInvalidationSessionTest; +import org.eclipse.jetty.server.session.LoggingUtil; import org.eclipse.jetty.server.session.SessionDataStoreFactory; import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory; import org.junit.jupiter.api.AfterAll; @@ -29,6 +30,10 @@ import org.junit.jupiter.api.BeforeAll; */ public class RemoteClusteredInvalidationSessionTest extends AbstractClusteredInvalidationSessionTest { + static + { + LoggingUtil.init(); + } public static RemoteInfinispanTestSupport __testSupport; @@ -45,9 +50,6 @@ public class RemoteClusteredInvalidationSessionTest extends AbstractClusteredInv __testSupport.teardown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredSessionScavengingTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredSessionScavengingTest.java index c947248ff12..73fe0223811 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteClusteredSessionScavengingTest.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session.remote; import org.eclipse.jetty.server.session.AbstractClusteredSessionScavengingTest; +import org.eclipse.jetty.server.session.LoggingUtil; import org.eclipse.jetty.server.session.SessionDataStoreFactory; import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory; import org.junit.jupiter.api.AfterAll; @@ -29,6 +30,10 @@ import org.junit.jupiter.api.BeforeAll; */ public class RemoteClusteredSessionScavengingTest extends AbstractClusteredSessionScavengingTest { + static + { + LoggingUtil.init(); + } public static RemoteInfinispanTestSupport __testSupport; @@ -45,9 +50,6 @@ public class RemoteClusteredSessionScavengingTest extends AbstractClusteredSessi __testSupport.teardown(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java index 4f8e3715194..91f0235d8a8 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session.remote; import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory; import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest; +import org.eclipse.jetty.server.session.LoggingUtil; import org.eclipse.jetty.server.session.SessionContext; import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.server.session.SessionDataStore; @@ -45,6 +46,10 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest { + static + { + LoggingUtil.init(); + } public static RemoteInfinispanTestSupport __testSupport; diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java index c45cdf760c1..1d3577df296 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session.remote; diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-infinispan-sessions/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..a5e96346170 --- /dev/null +++ b/tests/test-sessions/test-infinispan-sessions/src/test/resources/jetty-logging.properties @@ -0,0 +1,6 @@ +# Jetty Logging using jetty-slf4j-impl +org.eclipse.jetty.logging.appender.NAME_CONDENSE=false +org.eclipse.jetty.LEVEL=WARN +log.LEVEL=INFO +# org.hibernate.LEVEL=WARN +# org.infinispan.LEVEL=DEBUG \ No newline at end of file diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index ae24d2bd6b1..8eb0cc52e99 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -29,32 +29,44 @@ org.eclipse.jetty jetty-server ${project.version} + test org.eclipse.jetty jetty-webapp ${project.version} + test org.eclipse.jetty jetty-client ${project.version} + test org.eclipse.jetty.tests test-sessions-common ${project.version} + test + + + org.slf4j + slf4j-api + test org.apache.derby derby - 10.12.1.1 test org.apache.derby derbytools - 10.12.1.1 + test + + + org.eclipse.jetty + jetty-slf4j-impl test diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredInvalidationSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredInvalidationSessionTest.java index b4e04c20ae9..d81074084c1 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredInvalidationSessionTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredInvalidationSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -32,9 +32,6 @@ public class ClusteredInvalidationSessionTest extends AbstractClusteredInvalidat JdbcTestHelper.shutdown(null); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java index dfad2a1b222..7e0ee188959 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -25,9 +25,6 @@ import org.junit.jupiter.api.AfterEach; */ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessionTest { - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionMigrationTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionMigrationTest.java index 8351ce26627..96131d3edc6 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionMigrationTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionMigrationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -68,6 +68,7 @@ public class ClusteredSessionMigrationTest extends AbstractTestBase DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + cacheFactory.setSaveOnCreate(true); //immediately save the session when it is created so node2 can see it SessionDataStoreFactory storeFactory = createSessionDataStoreFactory(); ((AbstractSessionDataStoreFactory)storeFactory).setGracePeriodSec(TestServer.DEFAULT_SCAVENGE_SEC); @@ -80,8 +81,14 @@ public class ClusteredSessionMigrationTest extends AbstractTestBase server1.start(); int port1 = server1.getPort(); - TestServer server2 = new TestServer(0, TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC, - cacheFactory, storeFactory); + //Configure a cache and store same way for server2 + DefaultSessionCacheFactory cacheFactory2 = new DefaultSessionCacheFactory(); + cacheFactory2.setEvictionPolicy(SessionCache.NEVER_EVICT); + cacheFactory2.setSaveOnCreate(true); + SessionDataStoreFactory storeFactory2 = createSessionDataStoreFactory(); + + TestServer server2 = new TestServer(0,TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC, + cacheFactory2, storeFactory2); server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping); try @@ -109,8 +116,6 @@ public class ClusteredSessionMigrationTest extends AbstractTestBase request2.header("Cookie", sessionCookie); ContentResponse response2 = request2.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); - String response = response2.getContentAsString(); - assertEquals(response.trim(), String.valueOf(value)); } finally { @@ -131,6 +136,8 @@ public class ClusteredSessionMigrationTest extends AbstractTestBase public static class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; + + private static long createTime = 0; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException @@ -148,6 +155,7 @@ public class ClusteredSessionMigrationTest extends AbstractTestBase { if (session == null) session = request.getSession(true); + createTime = session.getCreationTime(); int value = Integer.parseInt(request.getParameter("value")); session.setAttribute("value", value); PrintWriter writer = response.getWriter(); @@ -156,12 +164,12 @@ public class ClusteredSessionMigrationTest extends AbstractTestBase } else if ("get".equals(action)) { - int value = (Integer)session.getAttribute("value"); - int x = session.getMaxInactiveInterval(); - assertTrue(x > 0); - PrintWriter writer = response.getWriter(); - writer.println(value); - writer.flush(); + //We cannot test if the session contains the attribute node1 + //set, because it may not have finished writing the attribute + //by the time its response returned to the client and the request + //was sent to node2. Just test the create time, which should be + //saved. + assertEquals(createTime, session.getCreationTime()); } } } diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java index ba0720f914a..b3b8a0232e4 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -25,9 +25,6 @@ import org.junit.jupiter.api.AfterEach; */ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScavengingTest { - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java index a6172475472..5a4a66a4871 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java index 6a66daadf65..58222190f94 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -173,9 +173,10 @@ public class JdbcTestHelper ResultSet result = null; try (Connection con = DriverManager.getConnection(DEFAULT_CONNECTION_URL);) { - statement = con.prepareStatement("select * from " + TABLE + - " where " + ID_COL + " = ? and " + CONTEXT_COL + - " = ? and virtualHost = ?"); + statement = con.prepareStatement( + "select * from " + TABLE + + " where " + ID_COL + " = ? and " + CONTEXT_COL + + " = ? and virtualHost = ?"); statement.setString(1, data.getId()); statement.setString(2, data.getContextPath()); statement.setString(3, data.getVhost()); @@ -199,16 +200,19 @@ public class JdbcTestHelper Blob blob = result.getBlob(MAP_COL); - SessionData tmp = new SessionData(data.getId(), data.getContextPath(), data.getVhost(), result.getLong(CREATE_COL), - result.getLong(ACCESS_COL), result.getLong(LAST_ACCESS_COL), result.getLong(MAX_IDLE_COL)); + SessionData tmp = + new SessionData(data.getId(), data.getContextPath(), data.getVhost(), result.getLong(CREATE_COL), + result.getLong(ACCESS_COL), result.getLong(LAST_ACCESS_COL), + result.getLong(MAX_IDLE_COL)); - try (InputStream is = blob.getBinaryStream(); - ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is)) + if (blob.length() > 0) { - - SessionData.deserializeAttributes(tmp, ois); + try (InputStream is = blob.getBinaryStream(); + ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is)) + { + SessionData.deserializeAttributes(tmp, ois); + } } - //same number of attributes assertEquals(data.getAllAttributes().size(), tmp.getAllAttributes().size()); //same keys diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java index d2511cf0335..17bcb26cb33 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -27,11 +27,10 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppContext; import org.junit.jupiter.api.AfterEach; @@ -100,7 +99,7 @@ public class ReloadedSessionMissingClassTest webApp.addServlet("Bar", "/bar"); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(ReloadedSessionMissingClassTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionTableSchemaTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionTableSchemaTest.java index 2a9a2ba3027..3c644ad2abb 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionTableSchemaTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionTableSchemaTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -50,9 +50,6 @@ public class SessionTableSchemaTest _da = new DatabaseAdaptor() { - /** - * @see org.eclipse.jetty.server.session.DatabaseAdaptor#isEmptyStringNull() - */ @Override public boolean isEmptyStringNull() { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java index 81b711f872a..c3a2b12c3d4 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/WebAppObjectInSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -28,9 +28,6 @@ import org.junit.jupiter.api.Test; public class WebAppObjectInSessionTest extends AbstractWebAppObjectInSessionTest { - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-jdbc-sessions/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..56cc73e5d68 --- /dev/null +++ b/tests/test-sessions/test-jdbc-sessions/src/test/resources/jetty-logging.properties @@ -0,0 +1,2 @@ +# Jetty Logging using jetty-slf4j-impl +#org.eclipse.jetty.LEVEL=DEBUG diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index 60ac2f524da..6226deb71b9 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -36,26 +36,31 @@ org.eclipse.jetty jetty-server ${project.version} + test org.eclipse.jetty jetty-webapp ${project.version} + test org.eclipse.jetty jetty-client ${project.version} + test org.eclipse.jetty.tests test-sessions-common ${project.version} + test org.eclipse.jetty.memcached jetty-memcached-sessions ${project.version} + test org.eclipse.jetty.toolchain @@ -63,9 +68,8 @@ test - org.slf4j - slf4j-simple - 1.7.9 + org.eclipse.jetty + jetty-slf4j-impl test diff --git a/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/CachingSessionDataStoreTest.java b/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/CachingSessionDataStoreTest.java index 7688305d4d8..9d72336de61 100644 --- a/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/CachingSessionDataStoreTest.java +++ b/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/CachingSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.memcached.sessions; diff --git a/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java b/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java index 1650c715861..bfe8a905044 100644 --- a/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java +++ b/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.memcached.sessions; @@ -122,9 +122,6 @@ public class MemcachedTestHelper public static class MockDataStoreFactory extends AbstractSessionDataStoreFactory { - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/tests/test-sessions/test-memcached-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-memcached-sessions/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..56cc73e5d68 --- /dev/null +++ b/tests/test-sessions/test-memcached-sessions/src/test/resources/jetty-logging.properties @@ -0,0 +1,2 @@ +# Jetty Logging using jetty-slf4j-impl +#org.eclipse.jetty.LEVEL=DEBUG diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 1c1f7718f8e..11e301fe167 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -63,32 +63,48 @@ org.eclipse.jetty jetty-server ${project.version} + test org.eclipse.jetty jetty-webapp ${project.version} + test org.eclipse.jetty jetty-client ${project.version} + test org.eclipse.jetty.tests test-sessions-common ${project.version} + test org.eclipse.jetty jetty-nosql ${project.version} + test org.eclipse.jetty jetty-jmx ${project.version} true + test + + + org.slf4j + slf4j-api + test + + + org.eclipse.jetty + jetty-slf4j-impl + test org.eclipse.jetty.toolchain diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java index dc647b02237..1d545059ea7 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredInvalidateSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredInvalidateSessionTest.java index 2ec91dd843d..8b2c0062d9f 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredInvalidateSessionTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredInvalidateSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; @@ -39,9 +39,6 @@ public class ClusteredInvalidateSessionTest extends AbstractClusteredInvalidatio MongoTestHelper.dropCollection(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredOrphanedSessionTest.java index 76e9e4836e4..fefbdea4ef8 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; @@ -43,9 +43,6 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi MongoTestHelper.dropCollection(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredSessionScavengingTest.java index 76b0d29fc7a..d841c48e8dc 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; @@ -39,9 +39,6 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav MongoTestHelper.dropCollection(); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() - */ @Override public SessionDataStoreFactory createSessionDataStoreFactory() { diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java index 8ab03eee8cc..c53d73d6342 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java index baf191548d4..28c0ebe0ca5 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.nosql.mongodb; @@ -32,8 +32,8 @@ import com.mongodb.MongoException; import com.mongodb.WriteConcern; import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.util.ClassLoadingObjectInputStream; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -44,7 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class MongoTestHelper { - private static final Logger LOG = Log.getLogger(MongoTestHelper.class); + private static final Logger LOG = LoggerFactory.getLogger(MongoTestHelper.class); public static final String DB_NAME = "HttpSessions"; public static final String COLLECTION_NAME = "testsessions"; diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties index fd2d21f9748..253433cae3a 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties +++ b/tests/test-sessions/test-mongodb-sessions/src/test/resources/jetty-logging.properties @@ -1,4 +1,3 @@ # Setup default logging implementation for during testing -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog - +# Jetty Logging using jetty-slf4j-impl #org.eclipse.jetty.server.LEVEL=DEBUG \ No newline at end of file diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/resources/keystore b/tests/test-sessions/test-mongodb-sessions/src/test/resources/keystore deleted file mode 100644 index b727bd0fb77..00000000000 Binary files a/tests/test-sessions/test-mongodb-sessions/src/test/resources/keystore and /dev/null differ diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index a423ae8630a..9f1dd27c356 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -29,6 +29,15 @@ jetty-client ${project.version} + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredInvalidationSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredInvalidationSessionTest.java index ecce32321af..b8139538573 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredInvalidationSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredInvalidationSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -65,8 +65,8 @@ public abstract class AbstractClusteredInvalidationSessionTest extends AbstractT TestServer server1 = new TestServer(0, maxInactiveInterval, scavengeInterval, cacheFactory1, storeFactory1); ServletContextHandler context = server1.addContext(contextPath); context.addServlet(TestServlet.class, servletMapping); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - context.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); try { @@ -103,8 +103,6 @@ public abstract class AbstractClusteredInvalidationSessionTest extends AbstractT assertEquals(HttpServletResponse.SC_OK, response1.getStatus()); String sessionCookie = response1.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); - // Mangle the cookie, replacing Path with $Path, etc. - sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path="); //ensure request is fully finished processing latch.await(5, TimeUnit.SECONDS); @@ -113,7 +111,6 @@ public abstract class AbstractClusteredInvalidationSessionTest extends AbstractT latch = new CountDownLatch(1); scopeListener.setExitSynchronizer(latch); Request request2 = client.newRequest(urls[1] + "?action=increment"); - request2.header("Cookie", sessionCookie); ContentResponse response2 = request2.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); @@ -153,6 +150,8 @@ public abstract class AbstractClusteredInvalidationSessionTest extends AbstractT public static class TestServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredOrphanedSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredOrphanedSessionTest.java index 2fc1eb65460..521086eb56d 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredOrphanedSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredOrphanedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredSessionScavengingTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredSessionScavengingTest.java index 2c45ab877b9..2b30e6e2337 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -61,13 +61,14 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes @Test public void testClusteredScavenge() throws Exception { - final String contextPath = "/"; - final String servletMapping = "/server"; - final int maxInactivePeriod = 5; //session will timeout after 5 seconds - final int scavengePeriod = 1; //scavenging occurs every 1 seconds + String contextPath = "/"; + String servletMapping = "/server"; + int maxInactivePeriod = 5; //session will timeout after 5 seconds + int scavengePeriod = 1; //scavenging occurs every 1 seconds DefaultSessionCacheFactory cacheFactory1 = new DefaultSessionCacheFactory(); cacheFactory1.setEvictionPolicy(SessionCache.NEVER_EVICT); //don't evict sessions + cacheFactory1.setFlushOnResponseCommit(true); SessionDataStoreFactory storeFactory1 = createSessionDataStoreFactory(); ((AbstractSessionDataStoreFactory)storeFactory1).setGracePeriodSec(scavengePeriod); ((AbstractSessionDataStoreFactory)storeFactory1).setSavePeriodSec(0); //always save when the session exits @@ -88,6 +89,7 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes DefaultSessionCacheFactory cacheFactory2 = new DefaultSessionCacheFactory(); cacheFactory2.setEvictionPolicy(SessionCache.NEVER_EVICT); //don't evict sessions + cacheFactory2.setFlushOnResponseCommit(true); SessionDataStoreFactory storeFactory2 = createSessionDataStoreFactory(); ((AbstractSessionDataStoreFactory)storeFactory2).setGracePeriodSec(scavengePeriod); ((AbstractSessionDataStoreFactory)storeFactory2).setSavePeriodSec(0); //always save when the session exits @@ -107,16 +109,17 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes // Perform one request to server1 to create a session ContentResponse response1 = client.GET("http://localhost:" + port1 + contextPath + servletMapping.substring(1) + "?action=init"); assertEquals(HttpServletResponse.SC_OK, response1.getStatus()); - assertEquals("test", response1.getContentAsString()); + assertTrue(response1.getContentAsString().startsWith("init")); String sessionCookie = response1.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); + String id = TestServer.extractSessionId(sessionCookie); assertEquals(1, ((DefaultSessionCache)m1.getSessionCache()).getSessionsCurrent()); assertEquals(1, ((DefaultSessionCache)m1.getSessionCache()).getSessionsMax()); assertEquals(1, ((DefaultSessionCache)m1.getSessionCache()).getSessionsTotal()); - // Mangle the cookie, replacing Path with $Path, etc. - sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path="); - String id = TestServer.extractSessionId(sessionCookie); - Session s1 = ((DefaultSessionCache)m1.getSessionCache()).get(id); + + + //Peek at the contents of the cache without doing all the reference counting etc + Session s1 = ((AbstractSessionCache)m1.getSessionCache()).doGet(id); assertNotNull(s1); long expiry = s1.getSessionData().getExpiry(); @@ -129,10 +132,9 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes while (time < end) { Request request = client.newRequest("http://localhost:" + port2 + contextPath + servletMapping.substring(1)); - request.header("Cookie", sessionCookie); //use existing session ContentResponse response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); - assertEquals("test", response2.getContentAsString()); + assertTrue(response2.getContentAsString().startsWith("test")); Thread.sleep(requestInterval); assertSessionCounts(1, 1, 1, m2); time = System.currentTimeMillis(); @@ -208,20 +210,22 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes if ("init".equals(action)) { HttpSession session = request.getSession(true); - session.setAttribute("test", "test"); + session.setAttribute("test", "init"); sendResult(session, httpServletResponse.getWriter()); } else { HttpSession session = request.getSession(false); - // if we node hopped we should get the session and test should already be present - sendResult(session, httpServletResponse.getWriter()); if (session != null) { session.setAttribute("test", "test"); } + + // if we node hopped we should get the session and test should already be present + sendResult(session, httpServletResponse.getWriter()); + } } @@ -229,11 +233,11 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes { if (session != null) { - writer.print(session.getAttribute("test")); + writer.println(session.getAttribute("test")); } else { - writer.print("null"); + writer.println("null"); } } } diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java index 6e9d09a275b..dc9d4ab22fa 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestBase.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestBase.java index 3d86b16496e..2ca3eb158d6 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestBase.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestBase.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java index 37963a5672c..dbe70cce2c1 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractWebAppObjectInSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -21,6 +21,8 @@ package org.eclipse.jetty.server.session; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; @@ -29,6 +31,7 @@ import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.webapp.WebAppContext; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -99,7 +102,10 @@ public abstract class AbstractWebAppObjectInSessionTest extends AbstractTestBase TestServer server1 = new TestServer(0, TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC, cacheFactory, storeFactory); - server1.addWebAppContext(warDir.getCanonicalPath(), contextPath).addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping); + WebAppContext wac1 = server1.addWebAppContext(warDir.getCanonicalPath(), contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); + wac1.addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping); try { @@ -120,16 +126,20 @@ public abstract class AbstractWebAppObjectInSessionTest extends AbstractTestBase try { // Perform one request to server1 to create a session + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); Request request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=set"); request.method(HttpMethod.GET); - ContentResponse response = request.send(); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); // Mangle the cookie, replacing Path with $Path, etc. sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path="); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + // Perform a request to server2 using the session cookie from the previous request Request request2 = client.newRequest("http://localhost:" + port2 + contextPath + servletMapping + "?action=get"); request2.method(HttpMethod.GET); diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/Foo.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/Foo.java index ade26e02fae..1f260677fc4 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/Foo.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/Foo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/FooInvocationHandler.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/FooInvocationHandler.java index 2a56dcd724e..06cda94580f 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/FooInvocationHandler.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/FooInvocationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestContextScopeListener.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestContextScopeListener.java deleted file mode 100644 index bf1362ac5ea..00000000000 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestContextScopeListener.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; - -import org.eclipse.jetty.server.handler.ContextHandler.Context; -import org.eclipse.jetty.server.handler.ContextHandler.ContextScopeListener; - -public class TestContextScopeListener implements ContextScopeListener -{ - AtomicReference _exitSynchronizer = new AtomicReference<>(); - - /** - * @return the exitSynchronizer - */ - public CountDownLatch getExitSynchronizer() - { - return _exitSynchronizer.get(); - } - - /** - * @param exitSynchronizer the exitSynchronizer to set - */ - public void setExitSynchronizer(CountDownLatch exitSynchronizer) - { - _exitSynchronizer.set(exitSynchronizer); - } - - @Override - public void enterScope(Context context, org.eclipse.jetty.server.Request request, Object reason) - { - //noop - } - - @Override - public void exitScope(Context context, org.eclipse.jetty.server.Request request) - { - if (_exitSynchronizer.get() != null) - _exitSynchronizer.get().countDown(); - } -} diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestFoo.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestFoo.java index 383049f9f2a..6be94cce5d8 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestFoo.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestFoo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpChannelCompleteListener.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpChannelCompleteListener.java new file mode 100644 index 00000000000..d7031ca9941 --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpChannelCompleteListener.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jetty.server.HttpChannel.Listener; +import org.eclipse.jetty.server.Request; + +public class TestHttpChannelCompleteListener implements Listener +{ + AtomicReference _exitSynchronizer = new AtomicReference<>(); + + /** + * @param exitSynchronizer the exitSynchronizer to set + */ + public void setExitSynchronizer(CountDownLatch exitSynchronizer) + { + _exitSynchronizer.set(exitSynchronizer); + } + + @Override + public void onComplete(Request request) + { + if (_exitSynchronizer.get() != null) + _exitSynchronizer.get().countDown(); + } +} diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListener.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListener.java index fb903344bd9..a5acb51dfed 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListener.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java index 978dadcf585..d22e2f09108 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestServer.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestServer.java index a8e6be63f10..12f29282db2 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestServer.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestServer.java @@ -1,25 +1,26 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -93,6 +94,11 @@ public class TestServer return h; } + public ServerConnector getServerConnector() + { + return _server.getBean(ServerConnector.class); + } + public void start() throws Exception { // server -> contexts collection -> context handler -> session handler -> servlet handler diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java index 805ffdaeb12..cc916c0732c 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -79,8 +79,8 @@ public class TestSessionDataStore extends AbstractSessionDataStore @Override public void doStore(String id, SessionData data, long lastSaveTime) throws Exception { - _numSaves.addAndGet(1); _map.put(id, data); + _numSaves.addAndGet(1); } @Override diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStoreFactory.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStoreFactory.java index 75fdfdf0167..30fcb71e995 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStoreFactory.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStoreFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -24,9 +24,6 @@ package org.eclipse.jetty.server.session; public class TestSessionDataStoreFactory extends AbstractSessionDataStoreFactory { - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionHandler.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionHandler.java index 6726cd6059f..24cf2b05de5 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionHandler.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java index 0d53a46ebb7..b781c32b48f 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/main/resources/Foo.java b/tests/test-sessions/test-sessions-common/src/main/resources/Foo.java index 70c561179fc..7abe566e126 100644 --- a/tests/test-sessions/test-sessions-common/src/main/resources/Foo.java +++ b/tests/test-sessions/test-sessions-common/src/main/resources/Foo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // public class Foo implements java.io.Serializable diff --git a/tests/test-sessions/test-sessions-common/src/main/resources/Proxyable.java b/tests/test-sessions/test-sessions-common/src/main/resources/Proxyable.java index 1953911c468..892fbc84054 100644 --- a/tests/test-sessions/test-sessions-common/src/main/resources/Proxyable.java +++ b/tests/test-sessions/test-sessions-common/src/main/resources/Proxyable.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // public interface Proxyable diff --git a/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableFactory.java b/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableFactory.java index 97abb2d3901..5c983c2ced2 100644 --- a/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableFactory.java +++ b/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableFactory.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import java.lang.reflect.Proxy; diff --git a/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableInvocationHandler.java b/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableInvocationHandler.java index c984da9c294..896791ee02a 100644 --- a/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableInvocationHandler.java +++ b/tests/test-sessions/test-sessions-common/src/main/resources/ProxyableInvocationHandler.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // import java.io.Serializable; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AbstractSessionCacheTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AbstractSessionCacheTest.java new file mode 100644 index 00000000000..d67ca6785ff --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AbstractSessionCacheTest.java @@ -0,0 +1,618 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionActivationListener; +import javax.servlet.http.HttpSessionEvent; + +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Base class for all tests on all flavours of SessionCache + */ +public abstract class AbstractSessionCacheTest +{ + public static class UnreadableSessionDataStore extends AbstractSessionDataStore + { + int _count; + int _calls; + SessionData _data; + + public UnreadableSessionDataStore(int count, SessionData data) + { + _count = count; + _data = data; + } + + @Override + public boolean isPassivating() + { + return false; + } + + @Override + public boolean exists(String id) throws Exception + { + return _data != null; + } + + @Override + public boolean delete(String id) throws Exception + { + _data = null; + return true; + } + + @Override + public void doStore(String id, SessionData data, long lastSaveTime) throws Exception + { + } + + @Override + public SessionData doLoad(String id) throws Exception + { + ++_calls; + if (_calls <= _count) + throw new UnreadableSessionDataException(id, _context, new IllegalStateException("Throw for test")); + else + return _data; + } + + @Override + public Set doGetExpired(Set candidates) + { + return null; + } + } + + public static class TestSessionActivationListener implements HttpSessionActivationListener + { + public int passivateCalls = 0; + public int activateCalls = 0; + + @Override + public void sessionWillPassivate(HttpSessionEvent se) + { + ++passivateCalls; + } + + @Override + public void sessionDidActivate(HttpSessionEvent se) + { + ++activateCalls; + } + } + + public abstract AbstractSessionCacheFactory newSessionCacheFactory(int evictionPolicy, boolean saveOnCreate, + boolean saveOnInactiveEvict, boolean removeUnloadableSessions, + boolean flushOnResponseCommit); + + /** + * Test that a session that exists in the datastore, but that cannot be + * read will be invalidated and deleted, and thus a request to re-use that + * same id will not succeed. + * + * @throws Exception + */ + @Test + public void testUnreadableSession() throws Exception + { + Server server = new Server(); + server.setSessionIdManager(new DefaultSessionIdManager(server)); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + server.setHandler(context); + + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + //prefill the datastore with a session that will be treated as unreadable + UnreadableSessionDataStore store = new UnreadableSessionDataStore(1, new SessionData("1234", "/test", "0.0.0.0", System.currentTimeMillis(), 0,0, -1)); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + server.start(); + + try (StacklessLogging stackless = new StacklessLogging(AbstractSessionCacheTest.class.getPackage())) + { + //check that session 1234 cannot be read, ie returns null AND + //that it is deleted in the datastore + Session session = context.getSessionHandler().getSession("1234"); + assertNull(session); + assertFalse(store.exists("1234")); + + //now try to make a session with the same id as if from a request with + //a SESSION_ID cookie set - the id from the cookie should not be able to + //be re-used because we just deleted the session with that id. Ids cannot + //be re-used (unless another context is already using that same id (ie cross + //context dispatch), which is not the case in this test). + Request request = new Request(null, null); + request.setRequestedSessionId("1234"); + HttpSession newSession = context.getSessionHandler().newHttpSession(request); + assertNotEquals("1234", newSession.getId()); + } + finally + { + server.stop(); + } + } + + /** + * Test that a new Session object can be created from + * previously persisted data (SessionData). + */ + @Test + public void testNewSessionFromPersistedData() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(true);//fake passivation + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + + context.start(); + + long now = System.currentTimeMillis(); + //fake persisted data + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + Session session = cache.newSession(data); + assertNotNull(session); + assertEquals("1234", session.getId()); + } + + + /** + * Test that the cache can load from the SessionDataStore + */ + @Test + public void testGetSessionNotInCache() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //put session data into the store + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + store.store("1234", data); + + assertFalse(cache.contains("1234")); + + Session session = cache.get("1234"); + assertEquals(1, session.getRequests()); + assertNotNull(session); + assertEquals("1234", session.getId()); + assertEquals(now - 20, session.getCreationTime()); + } + + @Test + public void testCommit() throws Exception + { + //Test state of session with call to commit + + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + //flushOnResponseCommit is true + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, true); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //Mimic various states of a session when a response is about + //to be committed: + + //call commit: session has not changed, should not be written + store._numSaves.set(0); //clear save counter + Session session = createUnExpiredSession(cache, store, "1234"); + cache.add("1234", session); + session.getSessionData().setLastSaved(100);//simulate previously saved + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + + //call commit: session has changed, should be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "456"); + cache.add("456", session); + session.getSessionData().setLastSaved(100);//simulate previously saved + session.setAttribute("foo", "bar"); + commitAndCheckSaveState(cache, store, session, true, true, false, false, 0, 1); + + //call commit: only the metadata has changed will not be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "678"); + cache.add("678", session); + session.getSessionData().setLastSaved(100);//simulate previously saved + session.getSessionData().calcAndSetExpiry(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + + //Test again with a savePeriod set - as savePeriod only + //affects saving when the session is not dirty, the savePeriod + //should not affect whether or not the session is saved on call + //to commit + store.setSavePeriodSec(60); + + //call commit: session has not changed, should not be written anyway + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "890"); + cache.add("890", session); + session.getSessionData().setLastSaved(100);//simulate previously saved + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + + //call commit: session has changed so session must be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "012"); + cache.add("012", session); + session.getSessionData().setLastSaved(100);//simulate previously saved + session.setAttribute("foo", "bar"); + commitAndCheckSaveState(cache, store, session, true, true, false, false, 0, 1); + + //call commit: only the metadata has changed will not be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "234"); + session.getSessionData().setMetaDataDirty(true); + cache.add("234", session); + session.getSessionData().setLastSaved(100);//simulate previously saved + session.getSessionData().calcAndSetExpiry(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + } + + @Test + public void testCommitAndRelease() throws Exception + { + //test what happens with various states of a session when commit + //is called before release + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + //flushOnResponseCommit is true + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, true); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //Mimic various states of a session when a response is about + //to be committed: + + //call commit: session has not changed, should not be written + Session session = createUnExpiredSession(cache, store, "1234"); + cache.add("1234", session); + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + //call release: session has not changed, but metadata has, should be written + cache.release("1234", session); + assertEquals(1, store._numSaves.get()); + assertFalse(session.getSessionData().isDirty()); + assertFalse(session.getSessionData().isMetaDataDirty()); + + //call commit: session has changed, should be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "456"); + cache.add("456", session); + session.setAttribute("foo", "bar"); + session.getSessionData().setLastSaved(100);//simulate not "new" session, ie has been previously saved + commitAndCheckSaveState(cache, store, session, true, true, false, false, 0, 1); + //call release: session not dirty but release changes metadata, so it will be saved + cache.release("456", session); + assertEquals(2, store._numSaves.get()); + assertFalse(session.getSessionData().isDirty()); + assertFalse(session.getSessionData().isMetaDataDirty()); + + //call commit: only the metadata has changed will not be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "678"); + session.getSessionData().calcAndSetExpiry(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + session.getSessionData().setLastSaved(100); //simulate session not being "new", ie never previously saved + cache.add("678", session); + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + //call release: the metadata is dirty session should be written + cache.release("678", session); + assertEquals(1, store._numSaves.get()); + assertFalse(session.getSessionData().isDirty()); + assertFalse(session.getSessionData().isMetaDataDirty()); + + //Test again with a savePeriod set - only save if time last saved exceeds 60sec + store.setSavePeriodSec(60); + + //call commit: session has not changed, should not be written anyway + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "890"); + cache.add("890", session); + session.getSessionData().setLastSaved(100); //simulate last save long time ago + session.getSessionData().setMetaDataDirty(false); + commitAndCheckSaveState(cache, store, session, false, false, false, false, 0, 0); + //call release: not dirty but release sets metadata true, plus save period exceeded so write + cache.release("1234", session); + assertEquals(1, store._numSaves.get()); + assertFalse(session.getSessionData().isDirty()); + assertFalse(session.getSessionData().isMetaDataDirty()); + + //call commit: session has changed so session must be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "012"); + cache.add("012", session); + session.getSessionData().setLastSaved(100);//simulate previously saved session + session.setAttribute("foo", "bar"); + session.getSessionData().setMetaDataDirty(false); + commitAndCheckSaveState(cache, store, session, true, false, false, false, 0, 1); + //call release: not dirty, release sets metadirty true (recalc expiry) but previous save too recent to exceed save period --> no write + cache.release("012", session); + assertEquals(1, store._numSaves.get()); + assertFalse(session.getSessionData().isDirty()); + assertTrue(session.getSessionData().isMetaDataDirty()); + + //call commit: only the metadata has changed will not be written + store._numSaves.set(0); //clear save counter + session = createUnExpiredSession(cache, store, "234"); + session.getSessionData().calcAndSetExpiry(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + session.getSessionData().setLastSaved(System.currentTimeMillis());//simulate session last saved recently + commitAndCheckSaveState(cache, store, session, false, true, false, true, 0, 0); + //call release: not dirty, release sets metadirty true (recalc expiry) but not within saveperiod so skip write + cache.release("1234", session); + assertEquals(0, store._numSaves.get()); + assertFalse(session.getSessionData().isDirty()); + assertTrue(session.getSessionData().isMetaDataDirty()); + } + + /** + * Test the exist method. + */ + @Test + public void testExists() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = (SessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //test one that doesn't exist at all + assertFalse(cache.exists("1234")); + + //test one that only exists in the store + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + store.store("1234", data); + assertTrue(cache.exists("1234")); + + //test one that exists in the cache also + Session session = cache.newSession(data); + cache.add("1234", session); + assertTrue(cache.exists("1234")); + } + + /** + * Test the delete method. + */ + @Test + public void testDelete() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, true, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //test remove non-existent session + Session session = cache.delete("1234"); + assertNull(session); + + //test remove of existing session in store only + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + store.store("1234", data); + session = cache.delete("1234"); + assertNotNull(session); + assertFalse(store.exists("1234")); + assertFalse(cache.contains("1234")); + + //test remove of session in both store and cache + session = cache.newSession(null, "1234",now - 20, TimeUnit.MINUTES.toMillis(10));//saveOnCreate ensures write to store + cache.add("1234", session); + assertTrue(store.exists("1234")); + assertTrue(cache.contains("1234")); + session = cache.delete("1234"); + assertNotNull(session); + assertFalse(store.exists("1234")); + assertFalse(cache.contains("1234")); + } + + @Test + public void testExpiration() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //test no candidates, no data in store + Set result = cache.checkExpiration(Collections.emptySet()); + assertTrue(result.isEmpty()); + + //test candidates that are in the cache and NOT expired + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); + Session session = cache.newSession(data); + cache.add("1234", session); + cache.release("1234", session); + assertTrue(cache.exists("1234")); + result = cache.checkExpiration(Collections.singleton("1234")); + assertTrue(result.isEmpty()); + + //test candidates that are in the cache AND expired + data.setExpiry(1); + result = cache.checkExpiration(Collections.singleton("1234")); + assertEquals(1, result.size()); + assertEquals("1234", result.iterator().next()); + + //test candidates that are not in the cache + SessionData data2 = store.newSessionData("567", now - 50, now - 40, now - 30, TimeUnit.MINUTES.toMillis(10)); + data2.setExpiry(1); + store.store("567", data2); + + result = cache.checkExpiration(Collections.emptySet()); + assertThat(result, containsInAnyOrder("1234", "567")); + } + + @Test + public void testSaveOnCreateTrue() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, true, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + long now = System.currentTimeMillis(); + cache.newSession(null, "1234", now, TimeUnit.MINUTES.toMillis(10)); + assertTrue(store.exists("1234")); + } + + @Test + public void testSaveOnCreateFalse() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + long now = System.currentTimeMillis(); + cache.newSession(null, "1234", now, TimeUnit.MINUTES.toMillis(10)); + assertFalse(store.exists("1234")); + } + + public void commitAndCheckSaveState(SessionCache cache, TestSessionDataStore store, Session session, + boolean expectedBeforeDirty, boolean expectedBeforeMetaDirty, + boolean expectedAfterDirty, boolean expectedAfterMetaDirty, + int expectedBeforeNumSaves, int expectedAfterNumSaves) + throws Exception + { + assertEquals(expectedBeforeDirty, session.getSessionData().isDirty()); + assertEquals(expectedBeforeMetaDirty, session.getSessionData().isMetaDataDirty()); + assertEquals(expectedBeforeNumSaves, store._numSaves.get()); + cache.commit(session); + assertEquals(expectedAfterDirty, session.getSessionData().isDirty()); + assertEquals(expectedAfterMetaDirty, session.getSessionData().isMetaDataDirty()); + assertEquals(expectedAfterNumSaves, store._numSaves.get()); + } + + public Session createUnExpiredSession(SessionCache cache, SessionDataStore store, String id) + { + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData(id, now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); + return cache.newSession(data); + } +} diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AsyncTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AsyncTest.java index 1794eb066ce..06fb0b7872d 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AsyncTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/AsyncTest.java @@ -1,25 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; import java.io.IOException; import java.lang.reflect.Proxy; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; @@ -31,10 +33,9 @@ import javax.servlet.http.HttpSession; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -48,15 +49,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class AsyncTest { - public static class LatchServlet extends HttpServlet - { - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - resp.getWriter().println("Latched"); - } - } - @Test public void testSessionWithAsyncDispatch() throws Exception { @@ -71,33 +63,33 @@ public class AsyncTest String mapping = "/server"; ServletContextHandler contextHandler = server.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); contextHandler.addServlet(holder, mapping); - LatchServlet latchServlet = new LatchServlet(); - ServletHolder latchHolder = new ServletHolder(latchServlet); - contextHandler.addServlet(latchHolder, "/latch"); server.start(); int port = server.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(AsyncTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); String url = "http://localhost:" + port + contextPath + mapping + "?action=async"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); - - //make another request, when this is handled, the first request is definitely finished being handled - response = client.GET("http://localhost:" + port + contextPath + "/latch"); - assertEquals(HttpServletResponse.SC_OK, response.getStatus()); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //session should now be evicted from the cache after request exited String id = TestServer.extractSessionId(sessionCookie); assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); @@ -123,35 +115,35 @@ public class AsyncTest String mapping = "/server"; ServletContextHandler contextHandler = server.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); contextHandler.addServlet(holder, mapping); - LatchServlet latchServlet = new LatchServlet(); - ServletHolder latchHolder = new ServletHolder(latchServlet); - contextHandler.addServlet(latchHolder, "/latch"); server.start(); int port = server.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(AsyncTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); String url = "http://localhost:" + port + contextPath + mapping + "?action=asyncComplete"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); + String id = TestServer.extractSessionId(sessionCookie); - //make another request, when this is handled, the first request is definitely finished being handled - response = client.GET("http://localhost:" + port + contextPath + "/latch"); - assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); //session should now be evicted from the cache after request exited - String id = TestServer.extractSessionId(sessionCookie); assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); assertTrue(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); } @@ -173,6 +165,8 @@ public class AsyncTest TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory); ServletContextHandler contextA = server.addContext("/ctxA"); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); //just pick one of the contexts to register the listener CrossContextServlet ccServlet = new CrossContextServlet(); ServletHolder ccHolder = new ServletHolder(ccServlet); contextA.addServlet(ccHolder, "/*"); @@ -181,29 +175,28 @@ public class AsyncTest TestServlet testServlet = new TestServlet(); ServletHolder testHolder = new ServletHolder(testServlet); contextB.addServlet(testHolder, "/*"); - LatchServlet latchServlet = new LatchServlet(); - ServletHolder latchHolder = new ServletHolder(latchServlet); - contextB.addServlet(latchHolder, "/latch"); + server.start(); int port = server.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(AsyncTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); String url = "http://localhost:" + port + "/ctxA/test?action=async"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); - //make another request, when this is handled, the first request is definitely finished being handled - response = client.GET("http://localhost:" + port + "/ctxB/latch"); - assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); //session should now be evicted from the cache after request exited String id = TestServer.extractSessionId(sessionCookie); @@ -216,6 +209,59 @@ public class AsyncTest } } + @Test + public void testSessionCreatedBeforeDispatch() throws Exception + { + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + cacheFactory.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory); + + String contextPath = ""; + String mapping = "/server"; + + ServletContextHandler contextHandler = server.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); + + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + contextHandler.addServlet(holder, mapping); + + + server.start(); + int port = server.getPort(); + + try (StacklessLogging stackless = new StacklessLogging(AsyncTest.class.getPackage())) + { + HttpClient client = new HttpClient(); + client.start(); + String url = "http://localhost:" + port + contextPath + mapping + "?action=asyncWithSession"; + + //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); + ContentResponse response = client.GET(url); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + + String sessionCookie = response.getHeaders().get("Set-Cookie"); + assertTrue(sessionCookie != null); + String id = TestServer.extractSessionId(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + + //session should now be evicted from the cache after request exited + assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); + assertTrue(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); + } + finally + { + server.stop(); + } + } + @Test public void testSessionWithCrossContextAsyncComplete() throws Exception { @@ -229,6 +275,8 @@ public class AsyncTest TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory); ServletContextHandler contextA = server.addContext("/ctxA"); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); CrossContextServlet ccServlet = new CrossContextServlet(); ServletHolder ccHolder = new ServletHolder(ccServlet); contextA.addServlet(ccHolder, "/*"); @@ -237,29 +285,28 @@ public class AsyncTest TestServlet testServlet = new TestServlet(); ServletHolder testHolder = new ServletHolder(testServlet); contextB.addServlet(testHolder, "/*"); - LatchServlet latchServlet = new LatchServlet(); - ServletHolder latchHolder = new ServletHolder(latchServlet); - contextB.addServlet(latchHolder, "/latch"); server.start(); int port = server.getPort(); + HttpClient client = new HttpClient(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(AsyncTest.class.getPackage())) { - HttpClient client = new HttpClient(); + client.start(); String url = "http://localhost:" + port + "/ctxA/test?action=asyncComplete"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); + assertTrue(sessionCookie != null); - - //make another request, when this is handled, the first request is definitely finished being handled - response = client.GET("http://localhost:" + port + "/ctxB/latch"); - assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); //session should now be evicted from the cache A after request exited String id = TestServer.extractSessionId(sessionCookie); @@ -268,6 +315,7 @@ public class AsyncTest } finally { + client.stop(); server.stop(); } } @@ -315,6 +363,22 @@ public class AsyncTest response.getWriter().println("OK"); } } + else if ("asyncWithSession".equals(action)) + { + if (request.getAttribute("asyncWithSession") == null) + { + request.setAttribute("asyncWithSession", Boolean.TRUE); + AsyncContext acontext = request.startAsync(); + HttpSession session = request.getSession(true); + acontext.dispatch(); + return; + } + else + { + response.getWriter().println("OK"); + } + + } else if ("asyncComplete".equals(action)) { AsyncContext acontext = request.startAsync(); @@ -326,7 +390,7 @@ public class AsyncTest { if (out.isReady()) { - request.getSession(true); + HttpSession s = request.getSession(true); out.print("OK\n"); acontext.complete(); } diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java index 1363f0b7480..f6a6c6458ed 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -82,12 +82,11 @@ public class ClientCrossContextSessionTest assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); - // Mangle the cookie, replacing Path with $Path, etc. - sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path="); + String sessionId = TestServer.extractSessionId(sessionCookie); // Perform a request to contextB with the same session cookie Request request = client.newRequest("http://localhost:" + port + contextB + servletMapping); - request.header("Cookie", sessionCookie); + request.header("Cookie", "JSESSIONID=" + sessionId); ContentResponse responseB = request.send(); assertEquals(HttpServletResponse.SC_OK, responseB.getStatus()); assertEquals(servletA.sessionId, servletB.sessionId); diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java index a0bfbe3e216..a675afa5a10 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -33,11 +33,10 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -76,14 +75,14 @@ public class CreationTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler contextHandler = server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); @@ -113,10 +112,10 @@ public class CreationTest Request request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=test"); response = request.send(); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); - + //ensure request has finished being handled synchronizer.await(5, TimeUnit.SECONDS); - + //session should now be evicted from the cache again assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(TestServer.extractSessionId(sessionCookie))); } @@ -145,14 +144,14 @@ public class CreationTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler contextHandler = server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); @@ -197,14 +196,14 @@ public class CreationTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler contextHandler = server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); @@ -245,14 +244,14 @@ public class CreationTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler contextHandler = server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); @@ -299,15 +298,15 @@ public class CreationTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler contextHandler = server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); ServletContextHandler ctxB = server1.addContext(contextB); ctxB.addServlet(TestServletB.class, servletMapping); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); @@ -354,15 +353,15 @@ public class CreationTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler contextHandler = server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); ServletContextHandler ctxB = server1.addContext(contextB); ctxB.addServlet(TestServletB.class, servletMapping); server1.start(); int port1 = server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); @@ -406,6 +405,7 @@ public class CreationTest if (action != null && action.startsWith("forward")) { HttpSession session = request.getSession(true); + _id = session.getId(); session.setAttribute("value", 1); @@ -414,7 +414,9 @@ public class CreationTest dispatcherB.forward(request, httpServletResponse); if (action.endsWith("inv")) + { session.invalidate(); + } else { session = request.getSession(false); diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DefaultSessionCacheTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DefaultSessionCacheTest.java index 27d10fed62e..d9326cb25b0 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DefaultSessionCacheTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DefaultSessionCacheTest.java @@ -1,150 +1,176 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; -import java.util.Collections; -import java.util.Set; +import java.util.Random; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpSessionActivationListener; -import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSession; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.servlet.ServletContextHandler; import org.junit.jupiter.api.Test; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * DefaultSessionCacheTest */ -public class DefaultSessionCacheTest +public class DefaultSessionCacheTest extends AbstractSessionCacheTest { - public static class TestSessionActivationListener implements HttpSessionActivationListener + @Override + public AbstractSessionCacheFactory newSessionCacheFactory(int evictionPolicy, boolean saveOnCreate, + boolean saveOnInactiveEvict, boolean removeUnloadableSessions, + boolean flushOnResponseCommit) { - public int passivateCalls = 0; - public int activateCalls = 0; - - @Override - public void sessionWillPassivate(HttpSessionEvent se) - { - ++passivateCalls; - } - - @Override - public void sessionDidActivate(HttpSessionEvent se) - { - ++activateCalls; - } + DefaultSessionCacheFactory factory = new DefaultSessionCacheFactory(); + factory.setEvictionPolicy(evictionPolicy); + factory.setSaveOnCreate(saveOnCreate); + factory.setSaveOnInactiveEvict(saveOnInactiveEvict); + factory.setRemoveUnloadableSessions(removeUnloadableSessions); + factory.setFlushOnResponseCommit(flushOnResponseCommit); + return factory; } @Test - public void testRenewIdMultipleRequests() throws Exception + public void testRenewWithInvalidate() throws Exception { //Test that invalidation happens on ALL copies of the session that are in-use by requests - Server server = new Server(); + int inactivePeriod = 20; + int scavengePeriod = 3; - SessionIdManager sessionIdManager = new DefaultSessionIdManager(server); - server.setSessionIdManager(sessionIdManager); - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - context.getSessionHandler().setMaxInactiveInterval((int)TimeUnit.DAYS.toSeconds(1)); - context.getSessionHandler().setSessionIdManager(sessionIdManager); + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setSaveOnCreate(true); //ensures that a session is persisted as soon as it is created + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + TestServer server = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory); + ServletContextHandler contextHandler = server.addContext("/test"); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); TestHttpSessionListener listener = new TestHttpSessionListener(); - context.getSessionHandler().addEventListener(listener); + contextHandler.getSessionHandler().addEventListener(listener); - server.setHandler(context); try { server.start(); - //create a new session - Session s = (Session)context.getSessionHandler().newHttpSession(null); - String id = s.getId(); - context.getSessionHandler().access(s, false); //simulate accessing the request - context.getSessionHandler().complete(s); //simulate completing the request + //Make a session + Request req0 = new Request(null, null); + HttpSession session = contextHandler.getSessionHandler().newHttpSession(req0); //pretend request created session + String id = session.getId(); + req0.onCompleted(); //pretend request exited - //make 1st request - final Session session = context.getSessionHandler().getSession(id); //get the session again - assertNotNull(session); - context.getSessionHandler().access(session, false); //simulate accessing the request + assertTrue(contextHandler.getSessionHandler().getSessionCache().contains(id)); - //make 2nd request - final Session session2 = context.getSessionHandler().getSession(id); //get the session again - context.getSessionHandler().access(session2, false); //simulate accessing the request - assertNotNull(session2); - assertTrue(session == session2); + //Make a fake request that does not exit the session + Request req1 = new Request(null, null); + HttpSession s1 = contextHandler.getSessionHandler().getHttpSession(id); + assertNotNull(s1); + assertSame(session, s1); + req1.enterSession(s1); + req1.setSessionHandler(contextHandler.getSessionHandler()); + assertTrue(contextHandler.getSessionHandler().getSessionCache().contains(id)); + assertEquals(1, ((Session)session).getRequests()); - Thread t2 = new Thread(new Runnable() + //Make another fake request that does not exit the session + Request req2 = new Request(null, null); + HttpSession s2 = contextHandler.getSessionHandler().getHttpSession(id); + assertNotNull(s2); + assertSame(session, s2); + req2.enterSession(s2); + req2.setSessionHandler(contextHandler.getSessionHandler()); + assertEquals(2, ((Session)session).getRequests()); + + //Renew the session id + Request req3 = new Request(null, null); + final HttpSession s3 = contextHandler.getSessionHandler().getHttpSession(id); + assertNotNull(s3); + assertSame(session, s3); + req3.enterSession(s3); + req3.setSessionHandler(contextHandler.getSessionHandler()); + + //Invalidate the session + Request req4 = new Request(null, null); + final HttpSession s4 = contextHandler.getSessionHandler().getHttpSession(id); + assertNotNull(s4); + assertSame(session, s4); + req4.enterSession(s4); + req4.setSessionHandler(contextHandler.getSessionHandler()); + + Thread renewThread = new Thread(new Runnable() { @Override public void run() { - System.err.println("Starting session id renewal"); - session2.renewId(new Request(null, null)); - System.err.println("Finished session id renewal"); - } - }); - t2.start(); + //simulate req3 calling Request.changeSessionId + String oldid = ((Session)s3).getId(); //old id - Thread t = new Thread(new Runnable() - { - - @Override - public void run() - { - System.err.println("Starting invalidation"); + //Session may already be invalid depending on timing try { - Thread.sleep(1000L); + ((Session)s3).renewId(req3); + //After this call, the session must have changed id, and it may also be + //invalid, depending on timing. + assertFalse(oldid.equals(((Session)s3).getId())); } - catch (Exception e) + catch (IllegalStateException e) { - e.printStackTrace(); + //the session was invalid before we called renewId } - session.invalidate(); - System.err.println("Finished invalidation"); + catch (Throwable e) + { + //anything else is a failure + fail(e); + } + } + } + ); + + Thread invalidateThread = new Thread(() -> + { + //simulate req4 doing an invalidate that we hope overlaps with req3 renewId + try + { + Random random = new Random(); + if ((random.nextInt(10) % 2) == 0) + Thread.currentThread().sleep(2); //small sleep to try and make timing more random + ((Session)s4).invalidate(); + assertFalse(((Session)s4).isValid()); + } + catch (InterruptedException e) + { + // no op } } ); - t.start(); - t.join(); - t2.join(); + invalidateThread.start(); + renewThread.start(); + renewThread.join(); + invalidateThread.join(); + } finally { @@ -165,8 +191,7 @@ public class DefaultSessionCacheTest context.setContextPath("/test"); context.setServer(server); - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); TestSessionDataStore store = new TestSessionDataStore(true);//fake passivation @@ -180,10 +205,10 @@ public class DefaultSessionCacheTest SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); Session session = cache.newSession(data); TestSessionActivationListener listener = new TestSessionActivationListener(); - cache.put("1234", session); + cache.add("1234", session); assertTrue(cache.contains("1234")); session.setAttribute("aaa", listener); - cache.put("1234", session); + cache.release("1234", session); assertTrue(store.exists("1234")); assertTrue(cache.contains("1234")); @@ -196,38 +221,6 @@ public class DefaultSessionCacheTest assertEquals(1, listener.activateCalls); } - /** - * Test that a new Session object can be created from - * previously persisted data (SessionData). - */ - @Test - public void testNewSessionFromPersistedData() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(true);//fake passivation - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - - context.start(); - - long now = System.currentTimeMillis(); - //fake persisted data - SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); - Session session = cache.newSession(data); - assertNotNull(session); - assertEquals("1234", session.getId()); - } - /** * Test that a session id can be renewed. */ @@ -255,7 +248,7 @@ public class DefaultSessionCacheTest long now = System.currentTimeMillis(); SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); Session session = cache.newSession(data); - cache.put("1234", session); + cache.add("1234", session); assertTrue(cache.contains("1234")); cache.renewSessionId("1234", "5678", "1234.foo", "5678.foo"); @@ -280,8 +273,7 @@ public class DefaultSessionCacheTest context.setContextPath("/test"); context.setServer(server); - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); TestSessionDataStore store = new TestSessionDataStore(); @@ -293,17 +285,15 @@ public class DefaultSessionCacheTest SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); Session session = cache.newSession(data); - //put the session in the cache - cache.put("1234", session); + //ensure the session is in the cache + cache.add("1234", session); - assertNotNull(cache.get("1234")); + //peek into the cache and see if it is there + assertTrue(((AbstractSessionCache)cache).contains("1234")); } - /** - * Test that the cache can load from the SessionDataStore - */ @Test - public void testGetSessionNotInCache() + public void testAdd() throws Exception { Server server = new Server(); @@ -312,8 +302,7 @@ public class DefaultSessionCacheTest context.setContextPath("/test"); context.setServer(server); - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); TestSessionDataStore store = new TestSessionDataStore(); @@ -321,52 +310,23 @@ public class DefaultSessionCacheTest context.getSessionHandler().setSessionCache(cache); context.start(); - //put session data into the store - long now = System.currentTimeMillis(); - SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); - store.store("1234", data); - - assertFalse(cache.contains("1234")); - - Session session = cache.get("1234"); - assertNotNull(session); - assertEquals("1234", session.getId()); - assertEquals(now - 20, session.getCreationTime()); - } - - @Test - public void testPutRequestsStillActive() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - context.start(); - - //make a session + //add data for a session to the store long now = System.currentTimeMillis(); SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); + + //create a session for the existing session data, add it to the cache Session session = cache.newSession(data); - session.access(now); //simulate request still active - cache.put("1234", session); + cache.add("1234", session); + + assertEquals(1, session.getRequests()); assertTrue(session.isResident()); assertTrue(cache.contains("1234")); assertFalse(store.exists("1234")); } @Test - public void testPutLastRequest() + public void testRelease() throws Exception { Server server = new Server(); @@ -375,8 +335,7 @@ public class DefaultSessionCacheTest context.setContextPath("/test"); context.setServer(server); - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); TestSessionDataStore store = new TestSessionDataStore(); @@ -384,14 +343,19 @@ public class DefaultSessionCacheTest context.getSessionHandler().setSessionCache(cache); context.start(); - //make a session + //create data for a session in the store long now = System.currentTimeMillis(); SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); + + //make a session for the existing id, add to cache Session session = cache.newSession(data); - session.access(now); //simulate request still active - session.complete(); //simulate request exiting - cache.put("1234", session); + cache.add("1234", session); + + //release use of newly added session + cache.release("1234", session); + + assertEquals(0, session.getRequests()); assertTrue(session.isResident()); assertTrue(cache.contains("1234")); assertTrue(store.exists("1234")); @@ -410,9 +374,8 @@ public class DefaultSessionCacheTest context.setContextPath("/test"); context.setServer(server); - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = (SessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); TestSessionDataStore store = new TestSessionDataStore(); cache.setSessionDataStore(store); @@ -426,145 +389,10 @@ public class DefaultSessionCacheTest long now = System.currentTimeMillis(); SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); Session session = cache.newSession(data); - - //put the session in the cache - cache.put("1234", session); + cache.add("1234", session); assertTrue(cache.contains("1234")); } - /** - * Test the exist method. - */ - @Test - public void testExists() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - context.start(); - - //test one that doesn't exist at all - assertFalse(cache.exists("1234")); - - //test one that only exists in the store - long now = System.currentTimeMillis(); - SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); - store.store("1234", data); - assertTrue(cache.exists("1234")); - - //test one that exists in the cache also - Session session = cache.newSession(data); - cache.put("1234", session); - assertTrue(cache.exists("1234")); - } - - /** - * Test the delete method. - */ - @Test - public void testDelete() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - context.start(); - - //test remove non-existent session - Session session = cache.delete("1234"); - assertNull(session); - - //test remove of existing session in store only - long now = System.currentTimeMillis(); - SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); - store.store("1234", data); - session = cache.delete("1234"); - assertNotNull(session); - assertFalse(store.exists("1234")); - assertFalse(cache.contains("1234")); - - //test remove of session in both store and cache - data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); - session = cache.newSession(data); - cache.put("1234", session); - assertTrue(store.exists("1234")); - assertTrue(cache.contains("1234")); - session = cache.delete("1234"); - assertNotNull(session); - assertFalse(store.exists("1234")); - assertFalse(cache.contains("1234")); - } - - @Test - public void testExpiration() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - context.start(); - - //test no candidates, no data in store - Set result = cache.checkExpiration(Collections.emptySet()); - assertTrue(result.isEmpty()); - - //test candidates that are in the cache and NOT expired - long now = System.currentTimeMillis(); - SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); - data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); - Session session = cache.newSession(data); - cache.put("1234", session); - assertTrue(cache.exists("1234")); - result = cache.checkExpiration(Collections.singleton("1234")); - assertTrue(result.isEmpty()); - - //test candidates that are in the cache AND expired - data.setExpiry(1); - cache.put("1234", session); - result = cache.checkExpiration(Collections.singleton("1234")); - assertEquals(1, result.size()); - assertEquals("1234", result.iterator().next()); - - //test candidates that are not in the cache - SessionData data2 = store.newSessionData("567", now - 50, now - 40, now - 30, TimeUnit.MINUTES.toMillis(10)); - data2.setExpiry(1); - store.store("567", data2); - - result = cache.checkExpiration(Collections.emptySet()); - assertThat(result, containsInAnyOrder("1234", "567")); - } - @Test public void testCheckInactiveSession() throws Exception @@ -597,7 +425,8 @@ public class DefaultSessionCacheTest //ie nothing happens to the session //test session that is resident but not valid - cache.put("1234", session); + cache.add("1234", session); + cache.release("1234", session); //this will write session session._state = Session.State.INVALID; cache.checkInactiveSession(session); assertTrue(store.exists("1234")); @@ -627,7 +456,7 @@ public class DefaultSessionCacheTest SessionData data2 = store.newSessionData("567", now, now - TimeUnit.SECONDS.toMillis(30), now - TimeUnit.SECONDS.toMillis(40), TimeUnit.MINUTES.toMillis(10)); data2.setExpiry(now + TimeUnit.DAYS.toMillis(1));//not expired Session session2 = cache.newSession(data2); - cache.put("567", session2);//ensure session is in cache + cache.add("567", session2);//ensure session is in cache cache.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT); session2.access(System.currentTimeMillis());//simulate 1 request in session assertTrue(cache.contains("567")); @@ -636,7 +465,7 @@ public class DefaultSessionCacheTest //test EVICT_ON_SESSION_EXIT - requests not active //this should not affect the session because this is an idle test only - session2.complete(); //simulate last request leaving session + session2.complete(); //NOTE:don't call cache.release as this will remove the session cache.checkInactiveSession(session2); assertTrue(cache.contains("567")); } @@ -665,64 +494,17 @@ public class DefaultSessionCacheTest SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); Session session = cache.newSession(data); - cache.put("1234", session); //make it resident + cache.add("1234", session); //make it resident assertTrue(cache.contains("1234")); long accessed = now - TimeUnit.SECONDS.toMillis(30); //make it idle data.setAccessed(accessed); + cache.release("1234", session); + assertTrue(cache.contains("1234")); + assertTrue(session.isResident()); cache.checkInactiveSession(session); assertFalse(cache.contains("1234")); assertFalse(session.isResident()); SessionData retrieved = store.load("1234"); assertEquals(accessed, retrieved.getAccessed()); //check that we persisted the session before we evicted } - - @Test - public void testSaveOnCreateTrue() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - cacheFactory.setSaveOnCreate(true); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - context.start(); - - long now = System.currentTimeMillis(); - cache.newSession(null, "1234", now, TimeUnit.MINUTES.toMillis(10)); - assertTrue(store.exists("1234")); - } - - @Test - public void testSaveOnCreateFalse() - throws Exception - { - Server server = new Server(); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/test"); - context.setServer(server); - - DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); - cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); - cacheFactory.setSaveOnCreate(false); - DefaultSessionCache cache = (DefaultSessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); - - TestSessionDataStore store = new TestSessionDataStore(); - cache.setSessionDataStore(store); - context.getSessionHandler().setSessionCache(cache); - context.start(); - - long now = System.currentTimeMillis(); - cache.newSession(null, "1234", now, TimeUnit.MINUTES.toMillis(10)); - assertFalse(store.exists("1234")); - } } diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java index 6913d87acc3..02c1e3edeee 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -31,10 +31,9 @@ import javax.servlet.http.HttpSession; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -104,9 +103,6 @@ public class DeleteUnloadableSessionTest public static class DelSessionDataStoreFactory extends AbstractSessionDataStoreFactory { - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { @@ -151,14 +147,14 @@ public class DeleteUnloadableSessionTest TestServer server = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory); ServletContextHandler context = server.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - context.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); context.addServlet(holder, servletMapping); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(DeleteUnloadableSessionTest.class.getPackage())) { server.start(); int port = server.getPort(); diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DirtyAttributeTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DirtyAttributeTest.java index 6dfc3f0686c..325cd51786b 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DirtyAttributeTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DirtyAttributeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -58,9 +58,6 @@ public class DirtyAttributeTest public class TestPassivatingSessionDataStore extends TestSessionDataStore { - /** - * @see org.eclipse.jetty.server.session.TestSessionDataStore#isPassivating() - */ @Override public boolean isPassivating() { @@ -71,9 +68,6 @@ public class DirtyAttributeTest public class TestPassivatingSessionDataStoreFactory extends AbstractSessionDataStoreFactory { - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { @@ -94,8 +88,8 @@ public class DirtyAttributeTest ServletContextHandler ctxA = server.addContext("/mod"); ctxA.addServlet(TestDirtyServlet.class, "/test"); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - ctxA.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); server.start(); int port = server.getPort(); @@ -106,21 +100,26 @@ public class DirtyAttributeTest try { // Perform a request to create a session + CountDownLatch latch = new CountDownLatch(1); + scopeListener.setExitSynchronizer(latch); ContentResponse response = client.GET("http://localhost:" + port + "/mod/test?action=create"); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); + + //ensure request finished + latch.await(5, TimeUnit.SECONDS); //do another request to change the session attribute - CountDownLatch latch = new CountDownLatch(1); + latch = new CountDownLatch(1); scopeListener.setExitSynchronizer(latch); Request request = client.newRequest("http://localhost:" + port + "/mod/test?action=setA"); response = request.send(); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); //ensure request fully finished processing - latch.await(5, TimeUnit.SECONDS); + assertTrue(latch.await(5, TimeUnit.SECONDS)); A_VALUE.assertPassivatesEquals(1); A_VALUE.assertActivatesEquals(1); @@ -172,18 +171,12 @@ public class DirtyAttributeTest int binds = 0; int unbinds = 0; - /** - * @see javax.servlet.http.HttpSessionActivationListener#sessionWillPassivate(javax.servlet.http.HttpSessionEvent) - */ @Override public void sessionWillPassivate(HttpSessionEvent se) { ++passivates; } - /** - * @see javax.servlet.http.HttpSessionActivationListener#sessionDidActivate(javax.servlet.http.HttpSessionEvent) - */ @Override public void sessionDidActivate(HttpSessionEvent se) { @@ -210,18 +203,12 @@ public class DirtyAttributeTest assertEquals(expected, unbinds); } - /** - * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent) - */ @Override public void valueBound(HttpSessionBindingEvent event) { ++binds; } - /** - * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent) - */ @Override public void valueUnbound(HttpSessionBindingEvent event) { diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DuplicateCookieTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DuplicateCookieTest.java new file mode 100644 index 00000000000..a254d2fe3cd --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DuplicateCookieTest.java @@ -0,0 +1,224 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.StringUtil; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Test having multiple session cookies in a request. + */ +public class DuplicateCookieTest +{ + @Test + public void testMultipleSessionCookiesOnlyOneExists() throws Exception + { + String contextPath = ""; + String servletMapping = "/server"; + HttpClient client = null; + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + + TestServer server1 = new TestServer(0, -1, -1, cacheFactory, storeFactory); + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + ServletContextHandler contextHandler = server1.addContext(contextPath); + contextHandler.addServlet(holder, servletMapping); + server1.start(); + int port1 = server1.getPort(); + + try (StacklessLogging stackless = new StacklessLogging(DuplicateCookieTest.class.getPackage())) + { + //create a valid session + createUnExpiredSession(contextHandler.getSessionHandler().getSessionCache(), + contextHandler.getSessionHandler().getSessionCache().getSessionDataStore(), + "4422"); + + client = new HttpClient(); + client.start(); + + //make a request with another session cookie in there that does not exist + Request request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=check"); + request.header("Cookie", "JSESSIONID=123"); //doesn't exist + request.header("Cookie", "JSESSIONID=4422"); //does exist + ContentResponse response = request.send(); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + assertEquals("4422", response.getContentAsString()); + } + finally + { + server1.stop(); + client.stop(); + } + } + + @Test + public void testMultipleSessionCookiesOnlyOneValid() throws Exception + { + String contextPath = ""; + String servletMapping = "/server"; + HttpClient client = null; + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + + TestServer server1 = new TestServer(0, -1, -1, cacheFactory, storeFactory); + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + ServletContextHandler contextHandler = server1.addContext(contextPath); + contextHandler.addServlet(holder, servletMapping); + server1.start(); + int port1 = server1.getPort(); + + try (StacklessLogging stackless = new StacklessLogging(DuplicateCookieTest.class.getPackage())) + { + //create a valid session + createUnExpiredSession(contextHandler.getSessionHandler().getSessionCache(), + contextHandler.getSessionHandler().getSessionCache().getSessionDataStore(), + "1122"); + //create an invalid session + createInvalidSession(contextHandler.getSessionHandler().getSessionCache(), + contextHandler.getSessionHandler().getSessionCache().getSessionDataStore(), + "2233"); + + client = new HttpClient(); + client.start(); + + //make a request with another session cookie in there that is not valid + Request request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=check"); + request.header("Cookie", "JSESSIONID=1122"); //is valid + request.header("Cookie", "JSESSIONID=2233"); //is invalid + ContentResponse response = request.send(); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + assertEquals("1122", response.getContentAsString()); + } + finally + { + server1.stop(); + client.stop(); + } + } + + @Test + public void testMultipleSessionCookiesMultipleExists() throws Exception + { + String contextPath = ""; + String servletMapping = "/server"; + HttpClient client = null; + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + + TestServer server1 = new TestServer(0, -1, -1, cacheFactory, storeFactory); + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + ServletContextHandler contextHandler = server1.addContext(contextPath); + contextHandler.addServlet(holder, servletMapping); + server1.start(); + int port1 = server1.getPort(); + + try (StacklessLogging stackless = new StacklessLogging(DuplicateCookieTest.class.getPackage())) + { + //create some of unexpired sessions + createUnExpiredSession(contextHandler.getSessionHandler().getSessionCache(), + contextHandler.getSessionHandler().getSessionCache().getSessionDataStore(), + "1234"); + createUnExpiredSession(contextHandler.getSessionHandler().getSessionCache(), + contextHandler.getSessionHandler().getSessionCache().getSessionDataStore(), + "5678"); + createUnExpiredSession(contextHandler.getSessionHandler().getSessionCache(), + contextHandler.getSessionHandler().getSessionCache().getSessionDataStore(), + "9111"); + + client = new HttpClient(); + client.start(); + + //make a request with multiple valid session ids + Request request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=check"); + request.header("Cookie", "JSESSIONID=1234"); + request.header("Cookie", "JSESSIONID=5678"); + ContentResponse response = request.send(); + assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + } + finally + { + server1.stop(); + client.stop(); + } + } + + public Session createUnExpiredSession(SessionCache cache, SessionDataStore store, String id) throws Exception + { + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData(id, now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); + Session s = cache.newSession(data); + cache.add(id, s); + return s; + } + + public Session createInvalidSession(SessionCache cache, SessionDataStore store, String id) throws Exception + { + Session session = createUnExpiredSession(cache, store, id); + session._state = Session.State.INVALID; + return session; + } + + public static class TestServlet extends HttpServlet + { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException + { + String action = request.getParameter("action"); + if (StringUtil.isBlank(action)) + return; + + if (action.equalsIgnoreCase("check")) + { + HttpSession session = request.getSession(false); + assertNotNull(session); + httpServletResponse.getWriter().print(session.getId()); + } + else if (action.equalsIgnoreCase("create")) + { + request.getSession(true); + } + } + } +} diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java index 593024d1ed7..a1b91471d98 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java @@ -1,24 +1,25 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; import java.io.IOException; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -29,15 +30,16 @@ import javax.servlet.http.HttpSession; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.util.thread.Locker.Lock; +import org.eclipse.jetty.util.thread.AutoLock; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -75,35 +77,47 @@ public class IdleSessionTest _server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(IdleSessionTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); String url = "http://localhost:" + port1 + contextPath + servletMapping; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url + "?action=init"); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); - assertTrue(sessionCookie != null); + assertNotNull(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); //and wait until the session should be passivated out pause(evictionSec * 2); - + //check that the session has been idled String id = TestServer.extractSessionId(sessionCookie); assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); assertTrue(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); //make another request to reactivate the session + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); Request request = client.newRequest(url + "?action=test"); ContentResponse response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session reactivated assertTrue(contextHandler.getSessionHandler().getSessionCache().contains(id)); @@ -119,17 +133,27 @@ public class IdleSessionTest ((TestSessionDataStore)contextHandler.getSessionHandler().getSessionCache().getSessionDataStore())._map.clear(); //make a request + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); request = client.newRequest(url + "?action=testfail"); response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //Test trying to reactivate an expired session (ie before the scavenger can get to it) //make a request to set up a session on the server + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); response = client.GET(url + "?action=init"); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); sessionCookie = response.getHeaders().get("Set-Cookie"); - assertTrue(sessionCookie != null); + assertNotNull(sessionCookie); id = TestServer.extractSessionId(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); //and wait until the session should be idled out pause(evictionSec * 2); @@ -146,9 +170,14 @@ public class IdleSessionTest pause(inactivePeriod + (3 * scavengePeriod)); //make another request to reactivate the session + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); request = client.newRequest(url + "?action=testfail"); response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); assertFalse(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); @@ -174,21 +203,28 @@ public class IdleSessionTest _server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(IdleSessionTest.class.getPackage())) { HttpClient client = new HttpClient(); client.start(); String url = "http://localhost:" + port1 + contextPath + servletMapping; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url + "?action=init"); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); - assertTrue(sessionCookie != null); + assertNotNull(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); //the session should never be cached String id = TestServer.extractSessionId(sessionCookie); @@ -196,10 +232,15 @@ public class IdleSessionTest assertTrue(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); //make another request to reactivate the session + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); Request request = client.newRequest(url + "?action=test"); ContentResponse response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session still not in the cache assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); assertTrue(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); @@ -209,17 +250,28 @@ public class IdleSessionTest ((TestSessionDataStore)contextHandler.getSessionHandler().getSessionCache().getSessionDataStore())._map.clear(); //make a request + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); request = client.newRequest(url + "?action=testfail"); response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //Test trying to reactivate an expired session (ie before the scavenger can get to it) //make a request to set up a session on the server + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); response = client.GET(url + "?action=init"); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); sessionCookie = response.getHeaders().get("Set-Cookie"); - assertTrue(sessionCookie != null); + assertNotNull(sessionCookie); id = TestServer.extractSessionId(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //stop the scavenger if (_server1.getHouseKeeper() != null) @@ -233,10 +285,15 @@ public class IdleSessionTest pause(inactivePeriod + (3 * scavengePeriod)); //make another request to reactivate the session + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); request = client.newRequest(url + "?action=testfail"); response2 = request.send(); assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id)); assertFalse(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id)); } @@ -261,7 +318,7 @@ public class IdleSessionTest session.setAttribute("value", 1); originalId = session.getId(); Session s = (Session)session; - try (Lock lock = s.lock()) + try (AutoLock lock = s.lock()) { assertTrue(s.isResident()); } @@ -270,21 +327,21 @@ public class IdleSessionTest else if ("test".equals(action)) { HttpSession session = request.getSession(false); - assertTrue(session != null); - assertTrue(originalId.equals(session.getId())); + assertNotNull(session); + assertEquals(originalId, session.getId()); Session s = (Session)session; - try (Lock lock = s.lock();) + try (AutoLock lock = s.lock()) { assertTrue(s.isResident()); } Integer v = (Integer)session.getAttribute("value"); - session.setAttribute("value", v.intValue() + 1); + session.setAttribute("value", v + 1); _session = session; } else if ("testfail".equals(action)) { HttpSession session = request.getSession(false); - assertTrue(session == null); + assertNull(session); _session = session; } } diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java index 9ba0aeaad20..576ea5a30fb 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java index 915f88cf7e7..63a40cb3773 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NonClusteredSessionScavengingTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NonClusteredSessionScavengingTest.java index 07c3b8f284c..21f67420419 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NonClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NonClusteredSessionScavengingTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -75,8 +75,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase context1.addServlet(TestServlet.class, servletMapping); TestHttpSessionListener listener = new TestHttpSessionListener(); context1.getSessionHandler().addEventListener(listener); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - context1.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); try { @@ -144,8 +144,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase TestServer server = new TestServer(0, maxInactivePeriod, scavengePeriod, cacheFactory, storeFactory); ServletContextHandler context = server.addContext("/"); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - context.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); _dataStore = context.getSessionHandler().getSessionCache().getSessionDataStore(); context.addServlet(TestServlet.class, servletMapping); @@ -208,8 +208,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase TestServer server = new TestServer(0, maxInactivePeriod, scavengePeriod, cacheFactory, storeFactory); ServletContextHandler context = server.addContext("/"); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - context.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); _dataStore = context.getSessionHandler().getSessionCache().getSessionDataStore(); context.addServlet(TestServlet.class, servletMapping); String contextPath = "/"; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NullSessionCacheTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NullSessionCacheTest.java index 59b7ee41240..3d344e26243 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NullSessionCacheTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/NullSessionCacheTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -24,17 +24,81 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** * NullSessionCacheTest */ -public class NullSessionCacheTest -{ - @Test - public void testEvictOnExit() throws Exception +public class NullSessionCacheTest extends AbstractSessionCacheTest +{ + @Override + public AbstractSessionCacheFactory newSessionCacheFactory(int evictionPolicy, boolean saveOnCreate, + boolean saveOnInactiveEvict, boolean removeUnloadableSessions, + boolean flushOnResponseCommit) { + NullSessionCacheFactory factory = new NullSessionCacheFactory(); + factory.setSaveOnCreate(saveOnCreate); + factory.setRemoveUnloadableSessions(removeUnloadableSessions); + factory.setFlushOnResponseCommit(flushOnResponseCommit); + return factory; + } + + @Test + public void testShutdownWithSessionStore() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + AbstractSessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(true);//fake passivation + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + + context.start(); + + //put a session in the cache and store + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + Session session = cache.newSession(data); + TestSessionActivationListener listener = new TestSessionActivationListener(); + cache.add("1234", session); + //cache never contains the session + assertFalse(cache.contains("1234")); + session.setAttribute("aaa", listener); + //write session out on release + cache.release("1234", session); + assertEquals(1, store._numSaves.get()); + assertEquals(1, listener.passivateCalls); + assertEquals(0, listener.activateCalls); //NullSessionCache always evicts on release, so never reactivates + + assertTrue(store.exists("1234")); + //cache never contains session + assertFalse(cache.contains("1234")); + + context.stop(); //calls shutdown + + //session should still exist in store + assertTrue(store.exists("1234")); + //cache never contains the session + assertFalse(cache.contains("1234")); + //shutdown does not save session + assertEquals(1, listener.passivateCalls); + assertEquals(0, listener.activateCalls); + } + + @Test + public void testNotCached() throws Exception + { + //Test the NullSessionCache never contains the session Server server = new Server(); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); @@ -55,16 +119,117 @@ public class NullSessionCacheTest SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); data.setExpiry(now + TimeUnit.DAYS.toMillis(1)); Session session = cache.newSession(null, data); //mimic a request making a session - session.complete(); //mimic request leaving session - cache.put("1234", session); //null cache doesn't store the session - assertFalse(cache.contains("1234")); + cache.add("1234", session); + assertFalse(cache.contains("1234"));//null cache doesn't actually retain the session + + //mimic releasing the session after the request is finished + cache.release("1234", session); assertTrue(store.exists("1234")); + assertFalse(cache.contains("1234")); + //simulate a new request using the previously created session session = cache.get("1234"); //get the session again session.access(now); //simulate a request - session.complete(); //simulate a request leaving - cache.put("1234", session); //finish with the session - + cache.release("1234", session); //finish with the session + assertFalse(cache.contains("1234")); assertFalse(session.isResident()); } + + /** + * Test contains method. + */ + @Test + public void testContains() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = (SessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //test one that doesn't exist + assertFalse(cache.contains("1234")); + + //test one that exists + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + Session session = cache.newSession(data); + cache.add("1234", session); + assertFalse(cache.contains("1234")); + } + + /** + * Test the exist method. + */ + @Test + public void testExists() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, false, false, false, false); + SessionCache cache = (SessionCache)cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //test one that doesn't exist anywhere at all + assertFalse(cache.exists("1234")); + + //test one that only exists in the store + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + store.store("1234", data); + assertTrue(cache.exists("1234")); + } + + /** + * Test the delete method. + */ + @Test + public void testDelete() + throws Exception + { + Server server = new Server(); + + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/test"); + context.setServer(server); + + SessionCacheFactory cacheFactory = newSessionCacheFactory(SessionCache.NEVER_EVICT, true, false, false, false); + SessionCache cache = cacheFactory.getSessionCache(context.getSessionHandler()); + + TestSessionDataStore store = new TestSessionDataStore(); + cache.setSessionDataStore(store); + context.getSessionHandler().setSessionCache(cache); + context.start(); + + //test remove non-existent session + Session session = cache.delete("1234"); + assertNull(session); + + //test remove of existing session in store only + long now = System.currentTimeMillis(); + SessionData data = store.newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + store.store("1234", data); + session = cache.delete("1234"); + assertNull(session); //NullSessionCache never returns the session that was removed from the cache because it was never in the cache! + assertFalse(store.exists("1234")); + assertFalse(cache.contains("1234")); + } } diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RedirectSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RedirectSessionTest.java index b13162d6085..9617086b63a 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RedirectSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RedirectSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java index 6d861a23102..046b7341251 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -59,8 +59,8 @@ public class ReentrantRequestSessionTest ServletContextHandler context = server.addContext(contextPath); context.addServlet(TestServlet.class, servletMapping); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - context.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server.getServerConnector().addBean(scopeListener); try { diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java index 083eb451831..c4cc8f31416 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RequestDispatchedSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RequestDispatchedSessionTest.java new file mode 100644 index 00000000000..881380cc529 --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/RequestDispatchedSessionTest.java @@ -0,0 +1,146 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.util.FormContentProvider; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.Fields; +import org.eclipse.jetty.util.component.LifeCycle; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class RequestDispatchedSessionTest +{ + private Server server; + private HttpClient client; + + @BeforeEach + public void startServer() throws Exception + { + server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(0); + server.addConnector(connector); + + // Default session behavior + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + contextHandler.addServlet(LoginServlet.class, "/login"); + contextHandler.addServlet(ShowUserServlet.class, "/user"); + contextHandler.addServlet(DefaultServlet.class, "/"); + + HandlerList handlers = new HandlerList(); + handlers.addHandler(contextHandler); + handlers.addHandler(new DefaultHandler()); + + server.setHandler(handlers); + + server.start(); + } + + @AfterEach + public void stopServerAndClient() + { + LifeCycle.stop(server); + LifeCycle.stop(client); + } + + @BeforeEach + public void startClient() throws Exception + { + client = new HttpClient(); + client.start(); + } + + @Test + public void testRedirect() throws Exception + { + Fields postForm = new Fields(); + postForm.add("username", "whizbat"); + + ContentResponse response = client.newRequest(server.getURI().resolve("/login")) + .method(HttpMethod.POST) + .content(new FormContentProvider(postForm)) + .send(); + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + } + + public static class LoginServlet extends HttpServlet + { + public static final String USERNAME = "loggedInUserName"; + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + if (request.getParameter("username") != null) + { + if (request.getSession() != null) + { + request.getSession().invalidate(); + } + request.getSession(true).setAttribute(USERNAME, request.getParameter("username")); + request.getRequestDispatcher("/user").forward(request, response); + return; + } + } + } + + public static class ShowUserServlet extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + showUser(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + showUser(req, resp); + } + + private void showUser(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setContentType("text/plain"); + resp.setCharacterEncoding("utf-8"); + PrintWriter out = resp.getWriter(); + String userName = (String)req.getSession().getAttribute(LoginServlet.USERNAME); + out.printf("UserName is %s%n", userName); + } + } +} diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameContextForwardedSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameContextForwardedSessionTest.java index 368283c365f..b9fd2934313 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameContextForwardedSessionTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameContextForwardedSessionTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -58,8 +58,8 @@ public class SameContextForwardedSessionTest TestServer testServer = new TestServer(0, -1, -1, cacheFactory, storeFactory); ServletContextHandler testServletContextHandler = testServer.addContext("/context"); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - testServletContextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + testServer.getServerConnector().addBean(scopeListener); ServletHolder holder = new ServletHolder(new Servlet1()); testServletContextHandler.addServlet(holder, "/one"); testServletContextHandler.addServlet(Servlet2.class, "/two"); diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameNodeLoadTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameNodeLoadTest.java index daa6c972428..7221870716d 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameNodeLoadTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SameNodeLoadTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SaveOptimizeTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SaveOptimizeTest.java index 856faed6685..ef210fcc9d3 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SaveOptimizeTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SaveOptimizeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -29,11 +29,10 @@ import javax.servlet.http.HttpSession; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -81,7 +80,7 @@ public class SaveOptimizeTest _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(SaveOptimizeTest.class.getPackage())) { HttpClient client = new HttpClient(); try @@ -124,12 +123,14 @@ public class SaveOptimizeTest _servlet = new TestServlet(); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(SaveOptimizeTest.class.getPackage())) { HttpClient client = new HttpClient(); try @@ -138,11 +139,16 @@ public class SaveOptimizeTest String url = "http://localhost:" + port1 + contextPath + servletMapping + "?action=create&check=true"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertNotNull(sessionCookie); String sessionId = TestServer.extractSessionId(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); SessionData data = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(data); @@ -151,9 +157,14 @@ public class SaveOptimizeTest int initialNumSaves = getNumSaves(); for (int i = 0; i < 5; i++) { - // Perform a request to contextB with the same session cookie + // Perform a request with the same session cookie + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=noop").send(); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session is unchanged SessionData d = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(d); @@ -195,12 +206,14 @@ public class SaveOptimizeTest _servlet = new TestServlet(); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(SaveOptimizeTest.class.getPackage())) { HttpClient client = new HttpClient(); try @@ -209,19 +222,29 @@ public class SaveOptimizeTest String url = "http://localhost:" + port1 + contextPath + servletMapping + "?action=create&check=true"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertNotNull(sessionCookie); String sessionId = TestServer.extractSessionId(sessionCookie); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + SessionData data = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(data); // Perform a request to do nothing with the same session cookie int numSavesBefore = getNumSaves(); + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=noop").send(); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session not saved SessionData d = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(d); @@ -229,8 +252,13 @@ public class SaveOptimizeTest // Perform a request to mutate the session numSavesBefore = getNumSaves(); + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=mutate").send(); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session is saved d = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(d); @@ -268,12 +296,14 @@ public class SaveOptimizeTest _servlet = new TestServlet(); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(SaveOptimizeTest.class.getPackage())) { HttpClient client = new HttpClient(); try @@ -282,12 +312,17 @@ public class SaveOptimizeTest String url = "http://localhost:" + port1 + contextPath + servletMapping + "?action=create&check=true"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertNotNull(sessionCookie); String sessionId = TestServer.extractSessionId(sessionCookie); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + SessionData data = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(data); long lastSaved = data.getLastSaved(); @@ -295,8 +330,13 @@ public class SaveOptimizeTest //make another request, session should not change // Perform a request to do nothing with the same session cookie + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=noop").send(); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session not saved SessionData d = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(d); @@ -306,8 +346,13 @@ public class SaveOptimizeTest Thread.sleep(1000 * savePeriod); // Perform a request to do nothing with the same session cookie + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=noop").send(); - + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session is saved d = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(d); @@ -346,12 +391,14 @@ public class SaveOptimizeTest _servlet = new TestServlet(); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(SaveOptimizeTest.class.getPackage())) { HttpClient client = new HttpClient(); try @@ -360,11 +407,16 @@ public class SaveOptimizeTest String url = "http://localhost:" + port1 + contextPath + servletMapping + "?action=create&check=true"; //make a request to set up a session on the server + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET(url); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); String sessionCookie = response.getHeaders().get("Set-Cookie"); assertNotNull(sessionCookie); String sessionId = TestServer.extractSessionId(sessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); SessionData data = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(data); @@ -372,8 +424,13 @@ public class SaveOptimizeTest assertTrue(lastSaved > 0); //check session created was saved // Perform a request to do nothing with the same session cookie, check the session object is different + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=noop&check=diff").send(); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + //check session not saved SessionData d = contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().load(sessionId); assertNotNull(d); @@ -413,14 +470,14 @@ public class SaveOptimizeTest _servlet = new TestServlet(); ServletHolder holder = new ServletHolder(_servlet); ServletContextHandler contextHandler = _server1.addContext(contextPath); - TestContextScopeListener scopeListener = new TestContextScopeListener(); - contextHandler.addEventListener(scopeListener); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server1.getServerConnector().addBean(scopeListener); contextHandler.addServlet(holder, servletMapping); _servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); _server1.start(); int port1 = _server1.getPort(); - try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + try (StacklessLogging stackless = new StacklessLogging(SaveOptimizeTest.class.getPackage())) { HttpClient client = new HttpClient(); try diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java index d6eac23dc6f..fd55f277dfa 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -30,6 +30,7 @@ import javax.servlet.http.HttpSession; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.junit.jupiter.api.Test; @@ -37,6 +38,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * SessionEvictionFailureTest @@ -109,9 +111,6 @@ public class SessionEvictionFailureTest _nextStoreResults = storeResults; } - /** - * @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler) - */ @Override public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception { @@ -176,7 +175,7 @@ public class SessionEvictionFailureTest int port1 = server.getPort(); HttpClient client = new HttpClient(); client.start(); - try + try (StacklessLogging stackless = new StacklessLogging(SessionEvictionFailureTest.class.getPackage())) { String url = "http://localhost:" + port1 + contextPath + servletMapping; @@ -192,6 +191,7 @@ public class SessionEvictionFailureTest // Make another request to see if the session is still in the cache and can be used, //allow it to be saved this time + assertTrue(context.getSessionHandler().getSessionCache().contains(TestServer.extractSessionId(sessionCookie))); Request request = client.newRequest(url + "?action=test"); response = request.send(); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateCreateScavengeTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateCreateScavengeTest.java index 7b53f854872..6c99c4d2aaf 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateCreateScavengeTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateCreateScavengeTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidationTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidationTest.java new file mode 100644 index 00000000000..2d31055db4e --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionInvalidationTest.java @@ -0,0 +1,137 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.server.session; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * SessionInvalidationTest + * + * Test that various methods on sessions can't be accessed after invalidation + */ +public class SessionInvalidationTest +{ + @Test + public void testInvalidation() throws Exception + { + String contextPath = ""; + String servletMapping = "/server"; + int scavengePeriod = -1; + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + ((AbstractSessionDataStoreFactory)storeFactory).setGracePeriodSec(scavengePeriod); + + TestServer server = new TestServer(0, 0, scavengePeriod, + cacheFactory, storeFactory); + ServletContextHandler context = server.addContext(contextPath); + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + context.addServlet(holder, servletMapping); + + try + { + server.start(); + int port1 = server.getPort(); + + HttpClient client = new HttpClient(); + client.start(); + try + { + String url = "http://localhost:" + port1 + contextPath + servletMapping; + // Create the session + ContentResponse response1 = client.GET(url + "?action=init"); + assertEquals(HttpServletResponse.SC_OK, response1.getStatus()); + String sessionCookie = response1.getHeaders().get("Set-Cookie"); + assertTrue(sessionCookie != null); + + // Make a request which will invalidate the existing session + Request request2 = client.newRequest(url + "?action=test"); + ContentResponse response2 = request2.send(); + assertEquals(HttpServletResponse.SC_OK, response2.getStatus()); + } + finally + { + client.stop(); + } + } + finally + { + server.stop(); + } + } + + public static class TestServlet extends HttpServlet + { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException + { + String action = request.getParameter("action"); + + if ("init".equals(action)) + { + HttpSession session = request.getSession(true); + assertNotNull(session); + } + else if ("test".equals(action)) + { + HttpSession session = request.getSession(false); + assertNotNull(session); + + //invalidate existing session + session.invalidate(); + + assertThrows(IllegalStateException.class, () -> session.invalidate()); + assertThrows(IllegalStateException.class, () -> session.getLastAccessedTime()); + assertThrows(IllegalStateException.class, () -> session.getCreationTime()); + assertThrows(IllegalStateException.class, () -> session.getAttribute("foo")); + assertThrows(IllegalStateException.class, () -> session.getAttributeNames()); + assertThrows(IllegalStateException.class, () -> session.getValue("foo")); + assertThrows(IllegalStateException.class, () -> session.getValueNames()); + assertThrows(IllegalStateException.class, () -> session.putValue("a", "b")); + assertThrows(IllegalStateException.class, () -> session.removeAttribute("foo")); + assertThrows(IllegalStateException.class, () -> session.removeValue("foo")); + assertThrows(IllegalStateException.class, () -> session.setAttribute("a", "b")); + assertDoesNotThrow(() -> session.getId()); + + } + } + } +} diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java index de387916ef0..7fd71f0b0d8 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; @@ -184,7 +184,7 @@ public class SessionListenerTest assertThat(sessionId, is(in(listener.createdSessions))); //and wait until the session should have expired - Thread.currentThread().sleep(TimeUnit.SECONDS.toMillis(inactivePeriod + (2*scavengePeriod))); + Thread.currentThread().sleep(TimeUnit.SECONDS.toMillis(inactivePeriod + (2 * scavengePeriod))); assertThat(sessionId, is(in(listener.destroyedSessions))); diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java index bd28af27aa1..b28e0a0620b 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java @@ -1,24 +1,27 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.server.session; import java.io.IOException; +import java.net.HttpCookie; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -37,7 +40,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -60,7 +62,19 @@ public class SessionRenewTest //make the server with a NullSessionCache _server = new TestServer(0, -1, -1, cacheFactory, storeFactory); - doTest(new RenewalVerifier()); + doTest(new RenewalVerifier() + { + + @Override + public void verify(WebAppContext context, String oldSessionId, String newSessionId) throws Exception + { + //null cache means it should contain neither session + assertFalse(context.getSessionHandler().getSessionCache().contains(newSessionId)); + assertFalse(context.getSessionHandler().getSessionCache().contains(oldSessionId)); + super.verify(context, oldSessionId, newSessionId); + } + + }); } /** @@ -90,6 +104,74 @@ public class SessionRenewTest }); } + @Test + public void testSessionRenewalMultiContext() throws Exception + { + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + + _server = new TestServer(0, -1, -1, cacheFactory, storeFactory); + + String contextPathA = ""; + String servletMapping = "/server"; + WebAppContext contextA = _server.addWebAppContext(".", contextPathA); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server.getServerConnector().addBean(scopeListener); + contextA.setParentLoaderPriority(true); + contextA.addServlet(TestServlet.class, servletMapping); + + WebAppContext contextB = _server.addWebAppContext(".", "/B"); + contextB.setParentLoaderPriority(true); + + HttpClient client = new HttpClient(); + try + { + _server.start(); + int port = _server.getPort(); + + client.start(); + + //pre-create session data for both contextA and contextB + long now = System.currentTimeMillis(); + SessionData dataA = contextA.getSessionHandler().getSessionCache().getSessionDataStore().newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + contextA.getSessionHandler().getSessionCache().getSessionDataStore().store("1234", dataA); + SessionData dataB = contextB.getSessionHandler().getSessionCache().getSessionDataStore().newSessionData("1234", now - 20, now - 10, now - 20, TimeUnit.MINUTES.toMillis(10)); + contextB.getSessionHandler().getSessionCache().getSessionDataStore().store("1234", dataB); + + //make a request to change the sessionid + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); + Request request = client.newRequest("http://localhost:" + port + contextPathA + servletMapping + "?action=renew"); + request.cookie(new HttpCookie(SessionHandler.__DefaultSessionCookie, "1234")); + ContentResponse renewResponse = request.send(); + assertEquals(HttpServletResponse.SC_OK, renewResponse.getStatus()); + String newSessionCookie = renewResponse.getHeaders().get("Set-Cookie"); + assertTrue(newSessionCookie != null); + String updatedId = TestServer.extractSessionId(newSessionCookie); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + + //session ids should be updated on all contexts + contextA.getSessionHandler().getSessionCache().contains(updatedId); + contextB.getSessionHandler().getSessionCache().contains(updatedId); + + Session sessiona = ((AbstractSessionCache)contextA.getSessionHandler().getSessionCache()).getAndEnter(updatedId, false); + Session sessionb = ((AbstractSessionCache)contextB.getSessionHandler().getSessionCache()).getAndEnter(updatedId, false); + + //sessions should nor have any usecounts + assertEquals(0, sessiona.getRequests()); + assertEquals(0, sessionb.getRequests()); + + } + finally + { + client.stop(); + _server.stop(); + } + } + /** * Perform the test by making a request to create a session * then another request that will renew the session id. @@ -101,6 +183,8 @@ public class SessionRenewTest String contextPath = ""; String servletMapping = "/server"; WebAppContext context = _server.addWebAppContext(".", contextPath); + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + _server.getServerConnector().addBean(scopeListener); context.setParentLoaderPriority(true); context.addServlet(TestServlet.class, servletMapping); TestHttpSessionIdListener testListener = new TestHttpSessionIdListener(); @@ -115,18 +199,28 @@ public class SessionRenewTest client.start(); //make a request to create a session + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create"); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + String sessionCookie = response.getHeaders().get("Set-Cookie"); assertTrue(sessionCookie != null); assertFalse(testListener.isCalled()); //make a request to change the sessionid + synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=renew"); ContentResponse renewResponse = request.send(); - assertEquals(HttpServletResponse.SC_OK, renewResponse.getStatus()); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + String renewSessionCookie = renewResponse.getHeaders().get("Set-Cookie"); assertNotNull(renewSessionCookie); assertNotSame(sessionCookie, renewSessionCookie); @@ -175,6 +269,17 @@ public class SessionRenewTest } } + public static class TestServletB extends HttpServlet + { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + //Ensure a session exists + } + + } + public static class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; @@ -194,7 +299,8 @@ public class SessionRenewTest assertTrue(beforeSession != null); String beforeSessionId = beforeSession.getId(); - ((Session)beforeSession).renewId(request); + //((Session)beforeSession).renewId(request); + request.changeSessionId(); HttpSession afterSession = request.getSession(false); @@ -210,10 +316,6 @@ public class SessionRenewTest assertTrue(sessionIdManager.isIdInUse(afterSessionId)); //new session id should be in use assertFalse(sessionIdManager.isIdInUse(beforeSessionId)); - HttpSession session = sessionManager.getSession(afterSessionId); - assertNotNull(session); - session = sessionManager.getSession(beforeSessionId); - assertNull(session); if (((Session)afterSession).isIdChanged()) ((org.eclipse.jetty.server.Response)response).replaceCookie(sessionManager.getSessionCookie(afterSession, request.getContextPath(), request.isSecure())); diff --git a/tests/test-sessions/test-sessions-common/src/test/resources/jetty-logging.properties b/tests/test-sessions/test-sessions-common/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..56cc73e5d68 --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/test/resources/jetty-logging.properties @@ -0,0 +1,2 @@ +# Jetty Logging using jetty-slf4j-impl +#org.eclipse.jetty.LEVEL=DEBUG diff --git a/tests/test-webapps/.gitignore b/tests/test-webapps/.gitignore deleted file mode 100644 index e73b9a8a351..00000000000 --- a/tests/test-webapps/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*/src/main/webapp/META-INF diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index cb9def53bc6..20dc2928376 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -41,6 +41,10 @@ test-http2-webapp test-simple-webapp test-felix-webapp - test-cdi2-webapp + test-cdi-common-webapp + test-weld-cdi-webapp + test-owb-cdi-webapp + test-websocket-webapp + test-bad-websocket-webapp - \ No newline at end of file + diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/pom.xml b/tests/test-webapps/test-bad-websocket-webapp/pom.xml similarity index 50% rename from jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/pom.xml rename to tests/test-webapps/test-bad-websocket-webapp/pom.xml index a241cfa2f58..4ae87c9a887 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-base/pom.xml +++ b/tests/test-webapps/test-bad-websocket-webapp/pom.xml @@ -1,39 +1,33 @@ - 4.0.0 - - org.eclipse.jetty.its.jetty-run-war-mojo-it - jetty-simple-project - 0.0.1-SNAPSHOT + org.eclipse.jetty.tests + test-webapps-parent + 10.0.0-SNAPSHOT - jetty-simple-base - jar + 4.0.0 + test-bad-websocket-webapp + war - Jetty :: Simple :: Base + Test :: Jetty Bad Websocket Simple Webapp + Contains wrong websocket which should fail at deployment + + org.eclipse.jetty.toolchain + jetty-javax-websocket-api + + + org.eclipse.jetty.websocket + websocket-javax-common + ${project.version} + org.eclipse.jetty.toolchain jetty-servlet-api provided - - org.slf4j - slf4j-api - - - commons-io - commons-io - - - org.eclipse.jetty.toolchain - jetty-perf-helper - - - com.fasterxml.jackson.core - jackson-databind - + diff --git a/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/BadOnCloseServerEndpoint.java b/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/BadOnCloseServerEndpoint.java new file mode 100644 index 00000000000..9b8f02aea2d --- /dev/null +++ b/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/BadOnCloseServerEndpoint.java @@ -0,0 +1,53 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.tests.webapp.websocket.bad; + +import java.io.IOException; +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/badonclose/{arg}") +public class BadOnCloseServerEndpoint +{ + private static String close = ""; + + @OnMessage + public String echo(String echo) + { + return close + echo; + } + + @OnClose + public void onClose(Session session, @PathParam("arg") StringSequence sb) + { + close = sb.toString(); + } + + @OnError + public void onError(Session session, Throwable t) + throws IOException + { + String message = "Error happened:" + t.getMessage(); + session.getBasicRemote().sendText(message); + } +} diff --git a/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/BadOnOpenServerEndpoint.java b/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/BadOnOpenServerEndpoint.java new file mode 100644 index 00000000000..c0602e05ce4 --- /dev/null +++ b/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/BadOnOpenServerEndpoint.java @@ -0,0 +1,53 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.tests.webapp.websocket.bad; + +import java.io.IOException; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/badonopen/{arg}") +public class BadOnOpenServerEndpoint +{ + private static String open = ""; + + @OnMessage + public String echo(String echo) + { + return open + echo; + } + + @OnOpen + public void onOpen(Session session, @PathParam("arg") StringSequence sb) + { + open = sb.toString(); + } + + @OnError + public void onError(Session session, Throwable t) + throws IOException + { + String message = "Error happened:" + t.getMessage(); + session.getBasicRemote().sendText(message); + } +} diff --git a/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/StringSequence.java b/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/StringSequence.java new file mode 100644 index 00000000000..daa5fb94867 --- /dev/null +++ b/tests/test-webapps/test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/tests/webapp/websocket/bad/StringSequence.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.tests.webapp.websocket.bad; + +public class StringSequence + implements CharSequence +{ + public String stringBuffer = ""; + + public StringSequence(String hold) + { + stringBuffer = hold; + } + + public StringSequence() + { + } + + @Override + public int length() + { + return stringBuffer.length(); + } + + @Override + public char charAt(int index) + { + return stringBuffer.charAt(index); + } + + @Override + public CharSequence subSequence(int start, int end) + { + return stringBuffer.subSequence(start, end); + } + + @Override + public String toString() + { + return stringBuffer; + } +} diff --git a/tests/test-webapps/test-bad-websocket-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-bad-websocket-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..8127f7c9b58 --- /dev/null +++ b/tests/test-webapps/test-bad-websocket-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,10 @@ + + + + Very Simple Bad Websocket Application + diff --git a/tests/test-webapps/test-bad-websocket-webapp/src/main/webapp/index.jsp b/tests/test-webapps/test-bad-websocket-webapp/src/main/webapp/index.jsp new file mode 100644 index 00000000000..c38169bb958 --- /dev/null +++ b/tests/test-webapps/test-bad-websocket-webapp/src/main/webapp/index.jsp @@ -0,0 +1,5 @@ + + +

        Hello World!

        + + diff --git a/tests/test-webapps/test-cdi-common-webapp/pom.xml b/tests/test-webapps/test-cdi-common-webapp/pom.xml new file mode 100644 index 00000000000..ab8cff68cdc --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/pom.xml @@ -0,0 +1,43 @@ + + + + org.eclipse.jetty.tests + test-webapps-parent + 10.0.0-SNAPSHOT + + + 4.0.0 + test-cdi-common-webapp + Test :: CDI :: Common Demo Webapp + war + + + ${project.groupId}.cdi.common + + + + + + + org.eclipse.jetty.toolchain + jetty-servlet-api + provided + + + + javax.inject + javax.inject + 1 + provided + + + + javax.enterprise + cdi-api + 1.2 + provided + + + + + diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java new file mode 100644 index 00000000000..c5d2beab097 --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.inject.Named; + +public class FriendlyGreetings +{ + @Produces + @Named("friendly") + public Greetings getGreetings(InjectionPoint ip) + { + return () -> "Hello " + ip.getMember().getDeclaringClass().getSimpleName(); + } +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java new file mode 100644 index 00000000000..106012a5889 --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java @@ -0,0 +1,24 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +public interface Greetings +{ + String getGreeting(); +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java new file mode 100644 index 00000000000..27296452d09 --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import java.io.IOException; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/greetings") +public class GreetingsServlet extends HttpServlet +{ + @Inject + @Named("friendly") + public Greetings greetings; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setContentType("text/plain"); + resp.getWriter().print(greetings.getGreeting()); + resp.getWriter().print(" from "); + resp.getWriter().println(getServletContext().getAttribute("ServerID")); + } +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java new file mode 100644 index 00000000000..f3156e7ba3f --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java @@ -0,0 +1,57 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Set; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Inject; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/info") +public class InfoServlet extends HttpServlet +{ + @Inject + BeanManager beanManager; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + resp.setContentType("text/plain"); + resp.setCharacterEncoding("utf-8"); + + PrintWriter out = resp.getWriter(); + out.println("Bean Manager: " + beanManager); + Set> beans = beanManager.getBeans(Object.class, new AnnotationLiteral() {}); + for (Bean bean : beans) + { + out.printf("%16s => %s%n", bean.getName(), bean); + for (InjectionPoint ij : bean.getInjectionPoints()) + out.printf("%16s -> %s%n", "", ij); + } + } +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java new file mode 100644 index 00000000000..80496a512ff --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import javax.enterprise.inject.Produces; + +public class ManifestServerID +{ + @Produces + public ServerID getServerID() + { + return () -> + { + String implVersion = this.getClass().getPackage().getImplementationVersion(); + if (implVersion == null) + implVersion = this.getClass().getPackage().getName(); + if (implVersion == null) + implVersion = "unknown"; + return "CDI-Demo-" + implVersion; + }; + } +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java new file mode 100644 index 00000000000..df4857d181a --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import javax.inject.Inject; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +@WebListener +public class MyContextListener implements ServletContextListener +{ + @Inject + public ServerID serverId; + + @Override + public void contextInitialized(ServletContextEvent sce) + { + if (serverId == null) + throw new IllegalStateException("CDI did not inject!"); + sce.getServletContext().setAttribute("ServerID", serverId.get()); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) + { + } +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java new file mode 100644 index 00000000000..4be30404559 --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +import javax.enterprise.inject.Produces; +import javax.inject.Named; + +public class OldGreetings +{ + @Produces + @Named("old") + public Greetings getGreeting() + { + return () -> "Salutations!"; + } +} diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java new file mode 100644 index 00000000000..de9ecf082b6 --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java @@ -0,0 +1,24 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.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.test; + +public interface ServerID +{ + String get(); +} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java similarity index 57% rename from tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java rename to tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java index beee9d1562c..fa80b7ecbcf 100644 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test; diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/resources/META-INF/beans.xml b/tests/test-webapps/test-cdi-common-webapp/src/main/resources/META-INF/beans.xml similarity index 100% rename from tests/test-webapps/test-cdi2-webapp/src/main/resources/META-INF/beans.xml rename to tests/test-webapps/test-cdi-common-webapp/src/main/resources/META-INF/beans.xml diff --git a/tests/test-webapps/test-cdi-common-webapp/src/main/webapp/index.html b/tests/test-webapps/test-cdi-common-webapp/src/main/webapp/index.html new file mode 100644 index 00000000000..a1765080059 --- /dev/null +++ b/tests/test-webapps/test-cdi-common-webapp/src/main/webapp/index.html @@ -0,0 +1,7 @@ +

        CDI Test Webapp

        + +

        CDI Info

        + + +

        Greetings test

        + \ No newline at end of file diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java deleted file mode 100644 index 3e4dc04fe14..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -import javax.enterprise.inject.Produces; -import javax.enterprise.inject.spi.InjectionPoint; -import javax.inject.Named; - -public class FriendlyGreetings -{ - @Produces - @Named("friendly") - public Greetings getGreetings(InjectionPoint ip) - { - return () -> "Hello " + ip.getMember().getDeclaringClass().getSimpleName(); - } -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java deleted file mode 100644 index 425b65052b2..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -public interface Greetings -{ - String getGreeting(); -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java deleted file mode 100644 index 773ea5092d1..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -import java.io.IOException; -import javax.inject.Inject; -import javax.inject.Named; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@WebServlet("/greetings") -public class GreetingsServlet extends HttpServlet -{ - @Inject - @Named("friendly") - public Greetings greetings; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException - { - resp.setContentType("text/plain"); - resp.getWriter().println("[" + greetings.getGreeting() + "]"); - } -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java deleted file mode 100644 index 7809857744e..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Set; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.inject.Inject; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@WebServlet("/info") -public class InfoServlet extends HttpServlet -{ - @Inject - BeanManager beanManager; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException - { - resp.setContentType("text/plain"); - resp.setCharacterEncoding("utf-8"); - - PrintWriter out = resp.getWriter(); - out.println("Bean Manager: " + beanManager); - Set> beans = beanManager.getBeans(""); - for (Bean bean : beans) - { - out.println(" " + bean); - } - } -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java deleted file mode 100644 index 6bc9c7cc4d7..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -import javax.enterprise.inject.Produces; - -public class ManifestServerID -{ - @Produces - public ServerID getServerID() - { - return () -> - { - String implVersion = this.getClass().getPackage().getImplementationVersion(); - if (implVersion == null) - implVersion = this.getClass().getPackage().getName(); - if (implVersion == null) - implVersion = "unknown"; - return "CDI-Demo-" + implVersion; - }; - } -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java deleted file mode 100644 index ead2931610f..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -import javax.inject.Inject; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; - -@WebListener -public class MyContextListener implements ServletContextListener -{ - @Inject - public ServerID serverId; - - @Override - public void contextInitialized(ServletContextEvent sce) - { - sce.getServletContext().setAttribute("ServerID", serverId.get()); - } - - @Override - public void contextDestroyed(ServletContextEvent sce) - { - } -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java deleted file mode 100644 index b9274880d9c..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java +++ /dev/null @@ -1,32 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -import javax.enterprise.inject.Produces; -import javax.inject.Named; - -public class OldGreetings -{ - @Produces - @Named("old") - public Greetings getGreeting() - { - return () -> "Salutations!"; - } -} diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java b/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java deleted file mode 100644 index 5332a27ac46..00000000000 --- a/tests/test-webapps/test-cdi2-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.test; - -public interface ServerID -{ - String get(); -} diff --git a/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/AppListener.java b/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/AppListener.java index 69b780ae895..315fd677fce 100755 --- a/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/AppListener.java +++ b/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/AppListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.demo; diff --git a/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/InfoServlet.java b/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/InfoServlet.java index ac33b980b81..778407f20d9 100644 --- a/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/InfoServlet.java +++ b/tests/test-webapps/test-felix-webapp/src/main/java/org/eclipse/jetty/demo/InfoServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.demo; diff --git a/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java b/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java index 70e0a00755d..6e19307cbdc 100644 --- a/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java +++ b/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.webapp; diff --git a/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java b/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java index 941b0f0723a..06bda4f0673 100644 --- a/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java +++ b/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.webapp; diff --git a/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java b/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java index 52bd97ee117..ea0703bd17f 100644 --- a/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java +++ b/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty.test.webapp; @@ -48,7 +48,7 @@ public class HTTP2FromWebAppIT Server server = new Server(); SslContextFactory.Server serverTLS = new SslContextFactory.Server(); - serverTLS.setKeyStorePath("src/test/resources/keystore.jks"); + serverTLS.setKeyStorePath("src/test/resources/keystore.p12"); serverTLS.setKeyStorePassword("storepwd"); serverTLS.setCipherComparator(new HTTP2Cipher.CipherComparator()); diff --git a/tests/test-webapps/test-http2-webapp/src/test/resources/jetty-logging.properties b/tests/test-webapps/test-http2-webapp/src/test/resources/jetty-logging.properties index 055e90b60ef..fe35fe0c739 100644 --- a/tests/test-webapps/test-http2-webapp/src/test/resources/jetty-logging.properties +++ b/tests/test-webapps/test-http2-webapp/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl org.eclipse.jetty.LEVEL=INFO #org.eclipse.jetty.alpn.LEVEL=DEBUG diff --git a/tests/test-webapps/test-http2-webapp/src/test/resources/keystore.jks b/tests/test-webapps/test-http2-webapp/src/test/resources/keystore.jks deleted file mode 100644 index 428ba54776e..00000000000 Binary files a/tests/test-webapps/test-http2-webapp/src/test/resources/keystore.jks and /dev/null differ diff --git a/tests/test-webapps/test-http2-webapp/src/test/resources/keystore.p12 b/tests/test-webapps/test-http2-webapp/src/test/resources/keystore.p12 new file mode 100644 index 00000000000..f76563f10ec Binary files /dev/null and b/tests/test-webapps/test-http2-webapp/src/test/resources/keystore.p12 differ diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 9dc62a61226..563dc6b029b 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -27,20 +27,14 @@ jetty-maven-plugin ${project.version} - 10 + 10 - - jetty.base - ${basedir}/src/main/config/demo-base - + ${basedir}/src/main/config/demo-base - - java.security.auth.login.config - ${basedir}/src/main/config/demo-base/etc/login.conf - + ${basedir}/src/main/config/demo-base/etc/login.conf - + /test-jaas @@ -48,7 +42,7 @@ xyz - + diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index 4cb51863891..e2e57d4e0fb 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -107,12 +107,9 @@ 8087 foo - 1 + 1 - - fooprop - 222 - + 222 /test @@ -137,6 +134,15 @@ + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + compile + org.eclipse.jetty jetty-servlets @@ -202,19 +208,19 @@ org.eclipse.jetty.websocket - jetty-websocket-api + websocket-jetty-api ${project.version} provided org.eclipse.jetty.websocket - jetty-websocket-server + websocket-jetty-server ${project.version} provided org.eclipse.jetty.websocket - javax-websocket-server + websocket-javax-server ${project.version} test diff --git a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml index 0f9867548b9..0b4cf7f7c31 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml +++ b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml @@ -1,24 +1,29 @@ - - - - - - - - - - - Test Realm - - false - - - + + + + + + + + + + + Test Realm + + + + false + + + - - demo test-realm is deployed. DO NOT USE IN PRODUCTION! - + + org.eclipse.jetty + + demo test-realm is deployed. DO NOT USE IN PRODUCTION! + + diff --git a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/modules/demo.mod b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/modules/demo.mod index 8bb82d2cfcd..96301d9b07d 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/modules/demo.mod +++ b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/modules/demo.mod @@ -28,3 +28,5 @@ org.eclipse.jetty.websocket.jsr356=false # Create and configure the test realm jetty.demo.realm=etc/realm.properties +# JDBC needed by test-jndi and test-spec +--module=jdbc diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/AddListServletRequestListener.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/AddListServletRequestListener.java index fd20c71bd5f..e3f12305ae3 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/AddListServletRequestListener.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/AddListServletRequestListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java index 0284fba9d79..3ab0374ddcf 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -32,8 +32,8 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; // Simple asynchronous Chat room. // This does not handle duplicate usernames or multiple frames/tabs from the same browser @@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger; @SuppressWarnings("serial") public class ChatServlet extends HttpServlet { - private static final Logger LOG = Log.getLogger(ChatServlet.class); + private static final Logger LOG = LoggerFactory.getLogger(ChatServlet.class); private long asyncTimeout = 10000; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/CookieDump.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/CookieDump.java index 2ed68a5d948..7a5fd8a5af7 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/CookieDump.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/CookieDump.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Counter.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Counter.java index 4ff284e5dbe..624723b8f12 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Counter.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Counter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java index 47d001b0fac..930206c0475 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Date2Tag.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DateTag.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DateTag.java index 0f0555b5aec..6def09667d5 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DateTag.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DateTag.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DispatchServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DispatchServlet.java index 1d8e6371363..b8938aa1bae 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DispatchServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/DispatchServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Dump.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Dump.java index 08939e09e8a..cda240ce815 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Dump.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/Dump.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -56,7 +56,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import javax.servlet.http.Part; -import org.eclipse.jetty.util.log.Log; +import org.slf4j.LoggerFactory; /** * Dump Servlet Request. @@ -346,12 +346,12 @@ public class Dump extends HttpServlet } catch (IOException e2) { - Log.getLogger(Dump.class).ignore(e2); + LoggerFactory.getLogger(Dump.class).trace("IGNORED", e2); } } catch (IOException e) { - Log.getLogger(Dump.class).ignore(e); + LoggerFactory.getLogger(Dump.class).trace("IGNORED", e); } return; } diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java index 5c73dde29b8..a7987d18f9b 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/HelloWorld.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/JavaxWebSocketChat.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/JavaxWebSocketChat.java index 475cecee8c9..6b82bb80e25 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/JavaxWebSocketChat.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/JavaxWebSocketChat.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/LoginServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/LoginServlet.java index 4404a61a2f0..4827dd4a6dc 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/LoginServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/LoginServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RegTest.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RegTest.java index fcf09d4659b..7db6bace9be 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RegTest.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RegTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java index b2c543449c5..b93bc279295 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/RewriteServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SecureModeServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SecureModeServlet.java index 7c69a771e27..326568a7473 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SecureModeServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SecureModeServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -32,8 +32,8 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Dump Servlet Request. @@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger; @SuppressWarnings("serial") public class SecureModeServlet extends HttpServlet { - private static final Logger LOG = Log.getLogger(SecureModeServlet.class); + private static final Logger LOG = LoggerFactory.getLogger(SecureModeServlet.class); @Override public void init(ServletConfig config) throws ServletException diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java index 5f5d9703ba8..86fdcca40df 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -41,7 +41,7 @@ public class SessionDump extends HttpServlet /** * Simple object attribute to test serialization */ - public class ObjectAttributeValue implements java.io.Serializable + public static class ObjectAttributeValue implements java.io.Serializable { long l; @@ -58,8 +58,6 @@ public class SessionDump extends HttpServlet int redirectCount = 0; - String pageType; - @Override public void init(ServletConfig config) throws ServletException @@ -67,8 +65,7 @@ public class SessionDump extends HttpServlet super.init(config); } - protected void handleForm(HttpServletRequest request, - HttpServletResponse response) + protected void handleForm(HttpServletRequest request) { HttpSession session = request.getSession(false); String action = request.getParameter("Action"); @@ -99,9 +96,9 @@ public class SessionDump extends HttpServlet @Override public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException + throws IOException { - handleForm(request, response); + handleForm(request); String nextUrl = getURI(request) + "?R=" + redirectCount++; String encodedUrl = response.encodeRedirectURL(nextUrl); response.sendRedirect(encodedUrl); @@ -110,9 +107,9 @@ public class SessionDump extends HttpServlet @Override public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException + throws IOException { - handleForm(request, response); + handleForm(request); response.setContentType("text/html"); @@ -124,6 +121,7 @@ public class SessionDump extends HttpServlet } catch (IllegalStateException e) { + log("Session already invalidated", e); session = null; } diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TagListener.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TagListener.java index ad0b9e2c037..785e1a37e3f 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TagListener.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TagListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestFilter.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestFilter.java index 2fc4b2e7ca1..4aa03d55235 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestFilter.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestFilter.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -32,8 +32,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * TestFilter. @@ -44,15 +44,12 @@ import org.eclipse.jetty.util.log.Logger; */ public class TestFilter implements Filter { - private static final Logger LOG = Log.getLogger(TestFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(TestFilter.class); private boolean _remote; private ServletContext _context; private final Set _allowed = new HashSet(); - /* - * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) - */ @Override public void init(FilterConfig filterConfig) throws ServletException { @@ -65,9 +62,6 @@ public class TestFilter implements Filter LOG.debug("TestFilter#remote=" + _remote); } - /* - * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) - */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException @@ -113,9 +107,6 @@ public class TestFilter implements Filter } } - /* - * @see javax.servlet.Filter#destroy() - */ @Override public void destroy() { diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestListener.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestListener.java index 8658bf02d52..397e9b68e5e 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestListener.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -129,6 +129,7 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeLi @Override public void contextInitialized(ServletContextEvent sce) { + // System.err.println("contextInitialized "+sce); _called.put("contextInitialized", new Throwable()); diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestServlet.java index 450e1d6efcb..5017289a12a 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/TestServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java index dc32f1a4627..c2374a2e231 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/WebSocketChatServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml index 75523dfb47a..0ca1b452055 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml +++ b/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml @@ -125,6 +125,7 @@ CGI org.eclipse.jetty.servlets.CGI 1 + true @@ -297,7 +298,7 @@ - 5 + 54 diff --git a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/ChatServletTest.java b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/ChatServletTest.java index 717afbfedc8..4d394cb3e7f 100644 --- a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/ChatServletTest.java +++ b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/ChatServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty; diff --git a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/DispatchServletTest.java b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/DispatchServletTest.java index 2e627933b64..b901a8e8d18 100644 --- a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/DispatchServletTest.java +++ b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/DispatchServletTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty; @@ -101,7 +101,7 @@ public class DispatchServletTest tester.addServlet(DefaultServlet.class, "/"); tester.start(); - String selfRefs[] = + String[] selfRefs = {"/dispatch/forward", "/dispatch/includeS", "/dispatch/includeW", "/dispatch/includeN",}; /* diff --git a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java index 2493551f827..31b249b6340 100644 --- a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java +++ b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty; @@ -47,30 +47,27 @@ import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.server.session.DefaultSessionCache; import org.eclipse.jetty.server.session.FileSessionDataStore; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.webapp.Configurations; import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; import org.junit.jupiter.api.Disabled; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Disabled("Not a test case") public class TestServer { - private static final Logger LOG = Log.getLogger(TestServer.class); + private static final Logger LOG = LoggerFactory.getLogger(TestServer.class); public static void main(String[] args) throws Exception { - ((StdErrLog)Log.getLog()).setSource(false); - // TODO don't depend on this file structure - Path jetty_root = FileSystems.getDefault().getPath(".").toAbsolutePath().normalize(); - if (!Files.exists(jetty_root.resolve("VERSION.txt"))) - jetty_root = FileSystems.getDefault().getPath("../../..").toAbsolutePath().normalize(); - if (!Files.exists(jetty_root.resolve("VERSION.txt"))) - throw new IllegalArgumentException(jetty_root.toString()); + Path jettyRoot = FileSystems.getDefault().getPath(".").toAbsolutePath().normalize(); + if (!Files.exists(jettyRoot.resolve("VERSION.txt"))) + jettyRoot = FileSystems.getDefault().getPath("../../..").toAbsolutePath().normalize(); + if (!Files.exists(jettyRoot.resolve("VERSION.txt"))) + throw new IllegalArgumentException(jettyRoot.toString()); // Setup Threadpool QueuedThreadPool threadPool = new QueuedThreadPool(); @@ -84,7 +81,6 @@ public class TestServer // Setup JMX MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); server.addBean(mbContainer); - server.addBean(Log.getLog()); // Common HTTP configuration HttpConfiguration config = new HttpConfiguration(); @@ -115,7 +111,7 @@ public class TestServer // Setup context HashLoginService login = new HashLoginService(); login.setName("Test Realm"); - login.setConfig(jetty_root.resolve("tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/realm.properties").toString()); + login.setConfig(jettyRoot.resolve("tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/realm.properties").toString()); server.addBean(login); File log = File.createTempFile("jetty-yyyy_mm_dd", "log"); @@ -127,7 +123,7 @@ public class TestServer WebAppContext webapp = new WebAppContext(); webapp.setContextPath("/test"); webapp.setParentLoaderPriority(true); - webapp.setResourceBase(jetty_root.resolve("tests/test-webapps/test-jetty-webapp/src/main/webapp").toString()); + webapp.setResourceBase(jettyRoot.resolve("tests/test-webapps/test-jetty-webapp/src/main/webapp").toString()); webapp.setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, ".*/test-jetty-webapp/target/classes.*$|" + ".*/jetty-servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\\.jar$" @@ -148,7 +144,7 @@ public class TestServer contexts.addHandler(webapp); ContextHandler srcroot = new ContextHandler(); - srcroot.setResourceBase(jetty_root.resolve("tests/test-webapps/test-jetty-webapp/src").toString()); + srcroot.setResourceBase(jettyRoot.resolve("tests/test-webapps/test-jetty-webapp/src").toString()); srcroot.setHandler(new ResourceHandler()); srcroot.setContextPath("/src"); contexts.addHandler(srcroot); @@ -162,9 +158,6 @@ public class TestServer private static class RestartHandler extends HandlerWrapper { - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -187,7 +180,7 @@ public class TestServer } catch (Exception e) { - LOG.warn(e); + LOG.warn("Unable to restart server", e); } } }.start(); diff --git a/tests/test-webapps/test-jetty-webapp/src/test/resources/jetty-logging.properties b/tests/test-webapps/test-jetty-webapp/src/test/resources/jetty-logging.properties index 606fca83005..04724735a9d 100644 --- a/tests/test-webapps/test-jetty-webapp/src/test/resources/jetty-logging.properties +++ b/tests/test-webapps/test-jetty-webapp/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +# Jetty Logging using jetty-slf4j-impl com.acme.LEVEL=INFO # org.eclipse.jetty.annotations.LEVEL=DEBUG \ No newline at end of file diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index 8d2afb5be46..08fce22680d 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -83,12 +83,12 @@ jetty-maven-plugin ${project.version} - ${project.build.directory}/plugin-context.xml - + ${project.build.directory}/plugin-context.xml + src/main/webapp src/main/webapp/WEB-INF/web.xml /test-jndi - + diff --git a/tests/test-webapps/test-jndi-webapp/src/main/java/com/acme/JNDITest.java b/tests/test-webapps/test-jndi-webapp/src/main/java/com/acme/JNDITest.java index a2f0774c5af..6162609d5fa 100644 --- a/tests/test-webapps/test-jndi-webapp/src/main/java/com/acme/JNDITest.java +++ b/tests/test-webapps/test-jndi-webapp/src/main/java/com/acme/JNDITest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; diff --git a/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockDataSource.java b/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockDataSource.java index 0775ae1b54a..7d16f9bce5f 100644 --- a/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockDataSource.java +++ b/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockDataSource.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -39,18 +39,12 @@ public class MockDataSource implements DataSource return null; } - /** - * @see javax.sql.DataSource#getConnection() - */ @Override public Connection getConnection() throws SQLException { return null; } - /** - * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String) - */ @Override public Connection getConnection(String username, String password) throws SQLException @@ -58,35 +52,23 @@ public class MockDataSource implements DataSource return null; } - /** - * @see javax.sql.DataSource#getLogWriter() - */ @Override public PrintWriter getLogWriter() throws SQLException { return null; } - /** - * @see javax.sql.DataSource#getLoginTimeout() - */ @Override public int getLoginTimeout() throws SQLException { return 0; } - /** - * @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter) - */ @Override public void setLogWriter(PrintWriter out) throws SQLException { } - /** - * @see javax.sql.DataSource#setLoginTimeout(int) - */ @Override public void setLoginTimeout(int seconds) throws SQLException { diff --git a/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockTransport.java b/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockTransport.java index a8567efd30c..0b9fd2937d1 100644 --- a/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockTransport.java +++ b/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockTransport.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -38,9 +38,6 @@ public class MockTransport extends Transport super(session, urlname); } - /** - * @see javax.mail.Transport#sendMessage(javax.mail.Message, javax.mail.Address[]) - */ @Override public void sendMessage(Message arg0, Address[] arg1) throws MessagingException { diff --git a/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockUserTransaction.java b/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockUserTransaction.java index aabe2f3ae3d..edffcaf2957 100644 --- a/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockUserTransaction.java +++ b/tests/test-webapps/test-mock-resources/src/main/java/com/acme/MockUserTransaction.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme; @@ -31,17 +31,11 @@ import javax.transaction.UserTransaction; public class MockUserTransaction implements UserTransaction { - /** - * @see javax.transaction.UserTransaction#begin() - */ @Override public void begin() throws NotSupportedException, SystemException { } - /** - * @see javax.transaction.UserTransaction#commit() - */ @Override public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, @@ -49,35 +43,23 @@ public class MockUserTransaction implements UserTransaction { } - /** - * @see javax.transaction.UserTransaction#getStatus() - */ @Override public int getStatus() throws SystemException { return 0; } - /** - * @see javax.transaction.UserTransaction#rollback() - */ @Override public void rollback() throws IllegalStateException, SecurityException, SystemException { } - /** - * @see javax.transaction.UserTransaction#setRollbackOnly() - */ @Override public void setRollbackOnly() throws IllegalStateException, SystemException { } - /** - * @see javax.transaction.UserTransaction#setTransactionTimeout(int) - */ @Override public void setTransactionTimeout(int arg0) throws SystemException { diff --git a/tests/test-webapps/test-owb-cdi-webapp/pom.xml b/tests/test-webapps/test-owb-cdi-webapp/pom.xml new file mode 100644 index 00000000000..7540b59c8dd --- /dev/null +++ b/tests/test-webapps/test-owb-cdi-webapp/pom.xml @@ -0,0 +1,70 @@ + + + + org.eclipse.jetty.tests + test-webapps-parent + 10.0.0-SNAPSHOT + + + 4.0.0 + test-owb-cdi-webapp + Test :: CDI On Jetty :: OWB Demo Webapp + war + + + ${project.groupId}.cdi.owb + + + + owb-cdi-demo + + + + + + org.eclipse.jetty.toolchain + jetty-servlet-api + provided + + + + org.eclipse.jetty.tests + test-cdi-common-webapp + ${project.version} + war + runtime + + + + + org.apache.geronimo.specs + geronimo-annotation_1.3_spec + 1.1 + + + org.apache.geronimo.specs + geronimo-jcdi_2.0_spec + 1.1 + + + org.apache.geronimo.specs + geronimo-atinject_1.0_spec + 1.1 + + + org.apache.geronimo.specs + geronimo-interceptor_1.2_spec + 1.1 + + + org.apache.openwebbeans + openwebbeans-web + 2.0.15 + + + org.apache.openwebbeans + openwebbeans-jetty9 + 2.0.11 + + + diff --git a/tests/test-webapps/test-owb-cdi-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/tests/test-webapps/test-owb-cdi-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer new file mode 100644 index 00000000000..f164a18c5a8 --- /dev/null +++ b/tests/test-webapps/test-owb-cdi-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer @@ -0,0 +1 @@ +org.eclipse.jetty.cdi.owb.OwbServletContainerInitializer \ No newline at end of file diff --git a/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml b/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml new file mode 100644 index 00000000000..99f1d2befa7 --- /dev/null +++ b/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml @@ -0,0 +1,17 @@ + + + + + + + + BeanManager + + + javax.enterprise.inject.spi.BeanManager + org.apache.webbeans.container.ManagerObjectFactory + + + + + diff --git a/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml b/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml new file mode 100644 index 00000000000..0291691bbfb --- /dev/null +++ b/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/jetty-web-owb.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/web.xml similarity index 76% rename from tests/test-webapps/test-cdi2-webapp/src/main/webapp/WEB-INF/web.xml rename to tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/web.xml index 1665f2146c7..79a39c5b9d4 100644 --- a/tests/test-webapps/test-cdi2-webapp/src/main/webapp/WEB-INF/web.xml +++ b/tests/test-webapps/test-owb-cdi-webapp/src/main/webapp/WEB-INF/web.xml @@ -3,11 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> - CDI Integration Test WebApp - - - org.jboss.weld.environment.servlet.Listener - + OWB CDI Integration Test WebApp + + Object factory for the CDI Bean Manager diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index 97800f44fa7..5fc4a70de4b 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -7,7 +7,6 @@ ../pom.xml 4.0.0 - org.eclipse.jetty test-proxy-webapp Test :: Jetty Proxy Webapp war @@ -35,6 +34,15 @@ + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + compile + org.eclipse.jetty jetty-proxy @@ -76,7 +84,7 @@ org.eclipse.jetty - jetty-alpn-server + jetty-alpn-java-server ${project.version} test diff --git a/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java b/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java index d5a6fcbf076..1bd261c1111 100644 --- a/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java +++ b/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package org.eclipse.jetty; @@ -35,8 +35,6 @@ import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.webapp.WebAppContext; @@ -47,9 +45,7 @@ public class TestTransparentProxyServer { public static void main(String[] args) throws Exception { - ((StdErrLog)Log.getLog()).setSource(false); - - String jetty_root = "../../.."; + String jettyRoot = "../../.."; // Setup Threadpool QueuedThreadPool threadPool = new QueuedThreadPool(); @@ -62,17 +58,16 @@ public class TestTransparentProxyServer // Setup JMX MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); server.addBean(mbContainer); - server.addBean(Log.getLog()); // Common HTTP configuration - HttpConfiguration config = new HttpConfiguration(); - config.setSecurePort(8443); - config.addCustomizer(new ForwardedRequestCustomizer()); - config.setSendDateHeader(true); - config.setSendServerVersion(true); + HttpConfiguration httpConfig = new HttpConfiguration(); + httpConfig.setSecurePort(8443); + httpConfig.addCustomizer(new ForwardedRequestCustomizer()); + httpConfig.setSendDateHeader(true); + httpConfig.setSendServerVersion(true); // Http Connector - HttpConnectionFactory http = new HttpConnectionFactory(config); + HttpConnectionFactory http = new HttpConnectionFactory(httpConfig); ServerConnector httpConnector = new ServerConnector(server, http); httpConnector.setPort(8080); httpConnector.setIdleTimeout(30000); @@ -80,11 +75,8 @@ public class TestTransparentProxyServer // SSL configurations SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath(jetty_root + "/jetty-server/src/main/config/etc/keystore"); - sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); - sslContextFactory.setTrustStorePath(jetty_root + "/jetty-server/src/main/config/etc/keystore"); - sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyStorePath(jettyRoot + "/jetty-server/src/main/config/modules/test-keystore/test-keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setExcludeCipherSuites( "SSL_RSA_WITH_DES_CBC_SHA", "SSL_DHE_RSA_WITH_DES_CBC_SHA", @@ -96,11 +88,11 @@ public class TestTransparentProxyServer sslContextFactory.setCipherComparator(new HTTP2Cipher.CipherComparator()); // HTTPS Configuration - HttpConfiguration https_config = new HttpConfiguration(config); - https_config.addCustomizer(new SecureRequestCustomizer()); + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); // HTTP2 factory - HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(https_config); + HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig); ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); alpn.setDefaultProtocol(h2.getProtocol()); @@ -109,7 +101,7 @@ public class TestTransparentProxyServer // HTTP2 Connector ServerConnector http2Connector = - new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(https_config)); + new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig)); http2Connector.setPort(8443); http2Connector.setIdleTimeout(15000); server.addConnector(http2Connector); diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/Foo.java b/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/Foo.java index 720ed776fa3..fbec630953c 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/Foo.java +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/Foo.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.initializer; diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/FooInitializer.java b/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/FooInitializer.java index e2e65b80f63..ca1751ad108 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/FooInitializer.java +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/initializer/FooInitializer.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.initializer; @@ -33,18 +33,12 @@ public class FooInitializer implements ServletContainerInitializer public static class BarListener implements ServletContextListener { - /** - * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) - */ @Override public void contextInitialized(ServletContextEvent sce) { throw new IllegalStateException("BAR LISTENER CALLED!"); } - /** - * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) - */ @Override public void contextDestroyed(ServletContextEvent sce) { @@ -55,9 +49,6 @@ public class FooInitializer implements ServletContainerInitializer public static class FooListener implements ServletContextListener { - /** - * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) - */ @Override public void contextInitialized(ServletContextEvent sce) { @@ -83,9 +74,6 @@ public class FooInitializer implements ServletContainerInitializer } } - /** - * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) - */ @Override public void contextDestroyed(ServletContextEvent sce) { @@ -103,5 +91,10 @@ public class FooInitializer implements ServletContainerInitializer ServletRegistration.Dynamic reg = context.addServlet("AnnotationTest", "com.acme.AnnotationTest"); context.setAttribute("com.acme.AnnotationTest.complete", (reg == null)); context.addListener(new FooListener()); + + //test adding jsp file dynamically + ServletRegistration.Dynamic jspFile = context.addJspFile("dynamic.jsp", "/dynamic.jsp"); + context.setAttribute("com.acme.jsp.file", (jspFile != null)); + jspFile.addMapping("/dynamicjsp/*"); } } diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index c2d5ba30928..bada431d66d 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -138,17 +138,17 @@ jetty-maven-plugin ${project.version} - 10 + 10 true - ${project.build.directory}/plugin-context.xml - + ${project.build.directory}/plugin-context.xml + src/main/webapp src/main/webapp/WEB-INF/web.xml /test-spec .*/jetty-servlet-api-[^/]*\.jar$ true ${basedir}/src/main/webapp/WEB-INF/jetty-env.xml - + Test Realm diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotatedListener.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotatedListener.java index fc0ff62c35b..241cdde622c 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotatedListener.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotatedListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; @@ -107,6 +107,29 @@ public class AnnotatedListener implements HttpSessionListener, HttpSessionAttrib throw new IllegalStateException("AnnotatedListener already initialized"); sce.getServletContext().setAttribute("com.acme.AnnotationTest.sclInjectWebListenerTest", Boolean.valueOf(maxAmount != null)); + + boolean setSessionTimeout; + try + { + sce.getServletContext().setSessionTimeout(180); + setSessionTimeout = true; + } + catch (Exception e) + { + setSessionTimeout = false; + } + sce.getServletContext().setAttribute("com.acme.AnnotationTest.sclSetSessionTimeout", Boolean.valueOf(setSessionTimeout)); + + boolean getSessionTimeout; + try + { + getSessionTimeout = (sce.getServletContext().getSessionTimeout() == 180); + } + catch (Exception e) + { + getSessionTimeout = false; + } + sce.getServletContext().setAttribute("com.acme.AnnotationTest.sclGetSessionTimeout", Boolean.valueOf(getSessionTimeout)); } public void requestCompleted(ServletRequestEvent rre) diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java index 0aead59d67c..e9c576edf60 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; @@ -186,6 +186,17 @@ public class AnnotationTest extends HttpServlet out.println(""); out.println("

        Results

        "); + out.println("

        Context Defaults

        "); + out.println("

        default-context-path: " + + (request.getServletContext().getAttribute("default-context-path") != null ? "PASS" : "FAIL") + + "

        "); + out.println("

        request-character-encoding: " + + ("utf-8".equals(request.getServletContext().getAttribute("request-character-encoding")) ? "PASS" : "FAIL") + + "

        "); + out.println("

        response-character-encoding: " + + ("utf-8".equals(request.getServletContext().getAttribute("response-character-encoding")) ? "PASS" : "FAIL") + + "

        "); + out.println("

        Init Params from Annotation

        "); out.println("
        ");
                     out.println("initParams={@WebInitParam(name=\"fromAnnotation\", value=\"xyz\")}");
        @@ -251,7 +262,11 @@ public class AnnotationTest extends HttpServlet
                     out.println("

        ServletContextListener Registration Prevented from ServletContextListener

        "); Boolean webListenerPrevention = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.sclFromSclRegoTest"); out.println("

        Result: " + (webListenerPrevention.booleanValue() ? "PASS" : "FAIL") + "

        "); - + + out.println("

        Add Jsp File Registration

        "); + complete = (Boolean)config.getServletContext().getAttribute("com.acme.jsp.file"); + out.println("

        Result: " + (complete.booleanValue() ? "PASS" : "FAIL") + "

        "); + out.println("

        ServletContextListener In web.xml Injected

        "); Boolean listenerInject = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.sclInjectTest"); out.println("

        Result: " + (listenerInject.booleanValue() ? "PASS" : "FAIL") + "

        "); @@ -260,6 +275,12 @@ public class AnnotationTest extends HttpServlet Boolean annotatedListenerInject = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.sclInjectWebListenerTest"); out.println("

        Result: " + (annotatedListenerInject.booleanValue() ? "PASS" : "FAIL") + "

        "); + out.println("

        ServletContextListener as @WebListener Get/Set Session Timeout

        "); + out.println("

        getSessionTimeout Result: " + + ((Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.sclGetSessionTimeout") ? "PASS" : "FAIL") + "

        "); + out.println("

        setSessionTimeout Result: " + + ((Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.sclSetSessionTimeout") ? "PASS" : "FAIL") + "

        "); + out.println("

        Programmatic Listener Injected

        "); Boolean programListenerInject = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.programListenerInjectTest"); out.println("

        Result: " + (programListenerInject.booleanValue() ? "PASS" : "FAIL") + "

        "); @@ -295,19 +316,19 @@ public class AnnotationTest extends HttpServlet out.println("private Double minAmount;"); out.println("
        "); if (maxAmount == null) - out.println("

        Result: " + envResult + ": FAIL"); + out.println("

        Result: " + envResult + ": FAIL"); else out.println("

        Result: " + envResult + ": " + (maxAmount.compareTo(55D) == 0 ? " PASS" : " FAIL") + ""); out.println("
        JNDI Lookup Result: " + envLookupResult + ""); if (minAmount == null) - out.println("

        Result: " + envResult2 + ": FAIL"); + out.println("

        Result: " + envResult2 + ": FAIL"); else out.println("
        Result: " + envResult2 + ": " + (minAmount.compareTo(0.99D) == 0 ? " PASS" : " FAIL") + ""); out.println("
        JNDI Lookup Result: " + envLookupResult2 + ""); if (avgAmount == null) - out.println("

        Result: " + envResult3 + ": FAIL"); + out.println("

        Result: " + envResult3 + ": FAIL"); else out.println("
        Result: " + envResult3 + ": " + (avgAmount.compareTo(1.25D) == 0 ? " PASS" : " FAIL") + ""); out.println("
        JNDI Lookup Result: " + envLookupResult3 + "

        "); diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AsyncListenerServlet.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AsyncListenerServlet.java index 435ad909490..5cc1daa911d 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AsyncListenerServlet.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AsyncListenerServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/Bar.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/Bar.java index d27191dddd6..1172fe7fded 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/Bar.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/Bar.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/ClassLoaderServlet.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/ClassLoaderServlet.java index c467fac2708..c37262340d6 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/ClassLoaderServlet.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/ClassLoaderServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/MultiPartTest.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/MultiPartTest.java index 95c4dcc5286..387803900cb 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/MultiPartTest.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/MultiPartTest.java @@ -1,26 +1,24 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Collection; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -63,17 +61,13 @@ public class MultiPartTest extends HttpServlet out.println("

        "); Collection parts = request.getParts(); - out.println("Parts: " + parts.size()); + out.println("Parts: " + parts.size() + "
        "); for (Part p : parts) { - out.println("

        " + p.getName() + "

        "); - out.println("Size: " + p.getSize()); - if (p.getContentType() == null || p.getContentType().startsWith("text/plain")) - { - out.println("

        "); - copy(p.getInputStream(), out); - out.println("

        "); - } + out.println("
        PartName: " + sanitizeXmlString(p.getName())); + out.println("
        Size: " + p.getSize()); + String contentType = p.getContentType(); + out.println("
        ContentType: " + contentType); } out.println(""); out.println(""); @@ -109,20 +103,67 @@ public class MultiPartTest extends HttpServlet } } - // TODO remove inline once 9.4.19 is released with a fix for #3726 - public static void copy(InputStream in, - OutputStream out) - throws IOException + public static String sanitizeXmlString(String html) { - int bufferSize = 8192; - byte[] buffer = new byte[bufferSize]; + if (html == null) + return null; - while (true) + int i = 0; + + // Are there any characters that need sanitizing? + loop: + for (; i < html.length(); i++) { - int len = in.read(buffer, 0, bufferSize); - if (len < 0) - break; - out.write(buffer, 0, len); + char c = html.charAt(i); + switch (c) + { + case '&': + case '<': + case '>': + case '\'': + case '"': + break loop; + default: + if (Character.isISOControl(c) && !Character.isWhitespace(c)) + break loop; + } } + // No characters need sanitizing, so return original string + if (i == html.length()) + return html; + + // Create builder with OK content so far + StringBuilder out = new StringBuilder(html.length() * 4 / 3); + out.append(html, 0, i); + + // sanitize remaining content + for (; i < html.length(); i++) + { + char c = html.charAt(i); + switch (c) + { + case '&': + out.append("&"); + break; + case '<': + out.append("<"); + break; + case '>': + out.append(">"); + break; + case '\'': + out.append("'"); + break; + case '"': + out.append("""); + break; + default: + if (Character.isISOControl(c) && !Character.isWhitespace(c)) + out.append('?'); + else + out.append(c); + } + } + return out.toString(); } } diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/RoleAnnotationTest.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/RoleAnnotationTest.java index 29f01241f85..4b612d24680 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/RoleAnnotationTest.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/RoleAnnotationTest.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/SecuredServlet.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/SecuredServlet.java index 70438644ad1..8719d8688fa 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/SecuredServlet.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/SecuredServlet.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/TestListener.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/TestListener.java index 659f9049298..a8f2eecf12b 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/TestListener.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/TestListener.java @@ -1,19 +1,19 @@ // -// ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. // -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 // -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 // -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== // package com.acme.test; diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml index 4a0126dbd58..d75a82a5097 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/jetty-web.xml @@ -3,11 +3,15 @@ - The test-spec webapp is deployed. DO NOT USE IN PRODUCTION! + + The test-spec webapp is deployed. DO NOT USE IN PRODUCTION! + + - + + org.eclipse.jetty + + WEB-INF/lib/jetty-util.jar logging used! + + diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/web.xml index 92b9efbd773..f5e0e3fa8a4 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/web.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/webapp/WEB-INF/web.xml @@ -9,6 +9,8 @@ Test Annotations WebApp /test-spec + utf-8 + utf-8 com.acme.test.TestListener @@ -80,7 +82,6 @@ server-administrator - + - javax.servlet - javax.servlet-api - 3.1.0 - provided + org.eclipse.jetty.tests + test-cdi-common-webapp + ${project.version} + war + runtime + org.jboss.weld.servlet - weld-servlet + weld-servlet-core ${weld.version}
        diff --git a/tests/test-webapps/test-cdi2-webapp/src/main/webapp/WEB-INF/jetty-env.xml b/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml similarity index 97% rename from tests/test-webapps/test-cdi2-webapp/src/main/webapp/WEB-INF/jetty-env.xml rename to tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml index 57bd8efa30d..a079f8241a6 100644 --- a/tests/test-webapps/test-cdi2-webapp/src/main/webapp/WEB-INF/jetty-env.xml +++ b/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/jetty-env.xml @@ -15,4 +15,4 @@
        - \ No newline at end of file + diff --git a/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..f622db81989 --- /dev/null +++ b/tests/test-webapps/test-weld-cdi-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + Weld CDI Integration Test WebApp + + + org.jboss.weld.environment.servlet.Listener + + + + Object factory for the CDI Bean Manager + BeanManager + javax.enterprise.inject.spi.BeanManager + +